Skip to content

Commit c00f588

Browse files
committed
Merge branch 'main' of https://github.com/pypa/setuptools into ANN204-wo-ignore-fully-untyped
2 parents c28822d + 12ca018 commit c00f588

30 files changed

+511
-296
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 80.3.0
2+
current_version = 80.7.1
33
commit = True
44
tag = True
55

NEWS.rst

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,76 @@
1+
v80.7.1
2+
=======
3+
4+
Bugfixes
5+
--------
6+
7+
- Only attempt to fetch eggs for unsatisfied requirements. (#4998)
8+
- In installer, when discovering egg dists, let metadata discovery search each egg. (#4998)
9+
10+
11+
v80.7.0
12+
=======
13+
14+
Features
15+
--------
16+
17+
- Removed usage of pkg_resources from installer. Set an official deadline on the installer deprecation to 2025-10-31. (#4997)
18+
19+
20+
Misc
21+
----
22+
23+
- #4996
24+
25+
26+
v80.6.0
27+
=======
28+
29+
Features
30+
--------
31+
32+
- Added a build dependency on coherent.licensed to inject the declared license text at build time. (#4981)
33+
34+
35+
Misc
36+
----
37+
38+
- #4995
39+
40+
41+
v80.5.0
42+
=======
43+
44+
Features
45+
--------
46+
47+
- Replaced more references to pkg_resources with importlib equivalents. (#3085)
48+
49+
50+
Misc
51+
----
52+
53+
- #4982
54+
55+
56+
v80.4.0
57+
=======
58+
59+
Features
60+
--------
61+
62+
- Simplified the error reporting in editable installs. (#4984)
63+
64+
65+
v80.3.1
66+
=======
67+
68+
Bugfixes
69+
--------
70+
71+
- Restored select attributes in easy_install for temporary pbr compatibility. (#4976)
72+
73+
174
v80.3.0
275
=======
376

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
'pip': ('https://pip.pypa.io/en/latest', None),
242242
'build': ('https://build.pypa.io/en/latest', None),
243243
'PyPUG': ('https://packaging.python.org/en/latest', None),
244+
'pytest': ('https://docs.pytest.org/en/stable', None),
244245
'packaging': ('https://packaging.pypa.io/en/latest', None),
245246
'twine': ('https://twine.readthedocs.io/en/stable', None),
246247
'importlib-resources': (

docs/userguide/development_mode.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,25 @@ More information is available on the text of :pep:`PEP 660 <660#what-to-put-in-t
229229
used.
230230

231231

232+
Debugging Tips
233+
--------------
234+
235+
If encountering problems installing a project in editable mode,
236+
follow these recommended steps to help debug:
237+
238+
- Try to install the project normally, without using the editable mode.
239+
Does the error still persist?
240+
(If it does, try fixing the problem before attempting the editable mode).
241+
- When using binary extensions, make sure all OS-level
242+
dependencies are installed (e.g. compilers, toolchains, binary libraries, ...).
243+
- Try the latest version of setuptools (maybe the error was already fixed).
244+
- When the project or its dependencies are using any setuptools extension
245+
or customization, make sure they support the editable mode.
246+
247+
After following the steps above, if the problem still persists and
248+
you think this is related to how setuptools handles editable installations,
249+
please submit a `reproducible example <https://stackoverflow.com/help/minimal-reproducible-example>`_ at `the bug tracker <https://github.com/pypa/setuptools/issues>`_.
250+
232251
----
233252

234253
.. rubric:: Notes

docs/userguide/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Contents
2525
:maxdepth: 1
2626

2727
quickstart
28+
interfaces
2829
package_discovery
2930
dependency_management
3031
development_mode

docs/userguide/interfaces.rst

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
Supported Interfaces
2+
====================
3+
4+
Setuptools is a complicated library with many interface surfaces and challenges. In addition to its primary purpose as a packaging build backend, Setuptools also has historically served as a standalone builder, installer, uploader, metadata provider, and more. Additionally, because it's implemented as a Python library, its entire functionality is incidentally exposed as a library.
5+
6+
In addition to operating as a library, because newer versions of Setuptools are often used to build older (sometimes decades-old) packages, it has a high burden of stability.
7+
8+
In order to have the ability to make sensible changes to the project, downstream developers and consumers should avoid depending on internal implementation details of the library and should rely only on the supported interfaces:
9+
10+
- *Tier 1*: APIs required by modern PyPA packaging standards (:pep:`517`, :pep:`660`) and Documented APIs for customising build behavior or creating plugins (:doc:`/userguide/extension`, :doc:`/references/keywords`):
11+
12+
These APIs are expected to be extremely stable and have deprecation notices and periods prior to backward incompatible changes or removals.
13+
14+
Please note that *functional and integration tests* capture specific behaviors and expectations about how the library and system is intended to work for outside users;
15+
and *code comments and docstrings* (including in tests) may provide specific protections to limit the changes to behaviors on which a downstream consumer can rely.
16+
17+
- *Tier 2*: Documented ``distutils`` APIs:
18+
19+
``setuptools`` strives to honor the interfaces provided by ``distutils`` and
20+
will coordinate with the ``pypa/distutils`` repository so that the
21+
appropriate deprecation notices are issued.
22+
23+
In principle, these are documented in :doc:`/deprecated/distutils/apiref`.
24+
Please note however that when a suitable replacement is available or advised,
25+
the existing ``distutils`` API is considered deprecated and should not be used
26+
(see :pep:`632#migration-advice` and :doc:`/deprecated/distutils-legacy`).
27+
28+
Depending on other behaviors is risky and subject to future breakage. If a project wishes to consider using interfaces that aren't covered above, consider requesting those interfaces to be added prior to depending on them (perhaps through a pull request implementing the change and relevant regression tests).
29+
30+
Please check further information about deprecated and unsupported behaviors in :doc:`/deprecated/index`.
31+
32+
33+
Support Policy Exceptions
34+
-------------------------
35+
36+
Behaviors and interfaces explicitly documented/advertised as deprecated,
37+
or that :obj:`issue deprecation warnings <warnings.warn>`
38+
will be supported up to the end of the announced deprecation period.
39+
40+
However there are a few circumstances in which the Setuptools' maintainers
41+
reserve the right of speeding up the deprecation cycle and shortening deprecation periods:
42+
43+
1. When security vulnerabilities are identified in specific code paths and the
44+
reworking existing APIs is not viable.
45+
2. When standards in the Python packaging ecosystem externally drive non-backward
46+
compatible changes in the code base.
47+
3. When changes in behavior are externally driven by 3rd-party dependencies
48+
and code maintained outside of the ``pypa/setuptools`` repository.
49+
50+
Note that these are exceptional circumstances and that the project will
51+
carefully attempt to find alternatives before resorting to unscheduled removals.
52+
53+
54+
What to do when deprecation periods are undefined?
55+
--------------------------------------------------
56+
57+
In some cases it is difficult to define how long Setuptools will take
58+
to remove certain features, behaviors or APIs.
59+
For example, it may be complicated to assess how wide-spread the usage
60+
of a certain feature is in the ecosystem.
61+
62+
Therefore, Setuptools may start to issue deprecation warnings without a clear due date.
63+
This occurs because we want to notify consumers about upcoming breaking
64+
changes as soon as possible so that they can start working in migration plans.
65+
66+
This does not mean that users should treat this deprecation as low priority or
67+
interpret the lack of due date as a signal that a breaking change will never happen.
68+
69+
The advised course of action is for users to create a migration plan
70+
as soon as they have identified to be subject to a Setuptools deprecation.
71+
72+
Setuptools may introduce relatively short deprecation periods (e.g. 6 months)
73+
when a deprecation warning has already been issued for a long period without a
74+
explicit due date.
75+
76+
77+
How to stay on top of upcoming deprecations?
78+
--------------------------------------------
79+
80+
It is a good idea to employ an automated test suite with relatively good
81+
coverage in your project and keep an eye on the logs.
82+
You can also automate this process by forwarding the standard output/error
83+
streams to a log file and using heuristics to identify deprecations
84+
(e.g. by searching for the word ``deprecation`` or ``deprecated``).
85+
You may need to increase the level of verbosity of your output as
86+
some tools may hide log messages by default (e.g. via ``pip -vv install ...``).
87+
88+
Additionally, if you are supporting a project that depends on Setuptools,
89+
you can implement a CI workflow that leverages
90+
:external+python:ref:`Python warning filters <warning-filter>`
91+
to improve the visibility of warnings.
92+
93+
This workflow can be comprised, for example, of 3 iterative steps that require
94+
developers to acknowledge the deprecation warnings:
95+
96+
1. Leverage Python Warning's Filter to transform warnings into exceptions during automated tests.
97+
2. Devise a migration plan:
98+
99+
- It is a good idea to track deprecations as if they were issues,
100+
and apply project management techniques to monitor the progress in handling them.
101+
- Determine which parts of your code are affected and understand
102+
the changes required to eliminate the warnings.
103+
104+
3. Modify the warning's filter you are using in the CI to not fail
105+
with the newly identified exceptions (e.g. by using the ``default`` action
106+
with a specific category or regular expression for the warning message).
107+
This can be done globally for the whole test suite or locally in a
108+
test-by-test basis.
109+
110+
Test tools like :pypi:`pytest` offer CLI and configuration options
111+
to facilitate controlling the warning's filter (see :external+pytest:doc:`how-to/capture-warnings`).
112+
113+
Note that there are many ways to incorporate such workflow in your CI.
114+
For example, if you have enough deployment resources and consider
115+
deprecation warning management to be a day-to-day development test
116+
you can set the warning's filter directly on your main CI loop.
117+
On the other hand if you have critical timelines and cannot afford CI jobs
118+
occasionally failing to flag maintenance, you can consider scheduling a
119+
periodic CI run separated from your main/mission-critical workflow.
120+
121+
122+
What does "support" mean?
123+
-------------------------
124+
125+
Setuptools is a non-profit community-driven open source project and as such
126+
the word "support" is used in a best-effort manner and with limited scope.
127+
For example, it is not always possible to quickly provide fixes for bugs.
128+
129+
We appreciate the patience of the community and incentivise users
130+
impacted by bugs to contribute to fixes in the form of
131+
:doc:`PR submissions </development/developer-guide>`, to speed-up the process.
132+
133+
When we say "a certain feature is supported" we mean that we will do our best
134+
to ensure this feature keeps working as documented.
135+
Note however that, as in any system, unintended breakages may happen.
136+
We appreciate the community understand and `considerate feedback`_.
137+
138+
.. _considerate feedback: https://opensource.how/etiquette/
139+
140+
141+
What to do after the deprecation period ends?
142+
---------------------------------------------
143+
144+
If you have limited development resources and is not able to
145+
devise a migration plan before Setuptools removes a deprecated feature,
146+
you can still resort to restricting the version of Setuptools to be installed.
147+
This usually includes modifying ``[build-system] requires`` in ``pyproject.toml``
148+
and/or specifying ``pip`` :external+pip:ref:`Constraints Files` via
149+
the ``PIP_CONSTRAINT`` environment variable (or passing |build-constraint-uv|_).
150+
Please avoid however to pre-emptively add version constraints if not necessary,
151+
(you can read more about this in https://iscinumpy.dev/post/bound-version-constraints/).
152+
153+
.. |build-constraint-uv| replace:: ``--build-constraint`` to ``uv``
154+
.. _build-constraint-uv: https://docs.astral.sh/uv/concepts/projects/build/#build-constraints
155+
156+
157+
A note on "Public Names"
158+
------------------------
159+
160+
Python devs may be used to the convention that private members are prefixed
161+
with an ``_`` (underscore) character and that any member not marked by this
162+
public. Due to the history and legacy of Setuptools this is not necessarily
163+
the case [#private]_.
164+
165+
In this project, "public interfaces" are defined as interfaces explicitly
166+
documented for 3rd party consumption.
167+
168+
When accessing a member in the ``setuptools`` package, please make sure it is
169+
documented for external usage. Also note that names imported from different
170+
modules/submodules are considered internal implementation details unless
171+
explicitly listed in ``__all__``. The fact that they are accessible in the
172+
namespace of the ``import``-er module is a mere side effect of the way Python works.
173+
174+
.. [#private]
175+
While names prefixed by ``_`` are always considered private,
176+
not necessary the absence of the prefix signals public members.

pkg_resources/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,7 @@ def _macos_arch(machine):
440440

441441

442442
def get_build_platform():
443-
"""Return this platform's string for platform-specific distributions
444-
445-
XXX Currently this is the same as ``distutils.util.get_platform()``, but it
446-
needs some hacks for Linux and macOS.
447-
"""
443+
"""Return this platform's string for platform-specific distributions"""
448444
from sysconfig import get_platform
449445

450446
plat = get_platform()

pyproject.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
[build-system]
2-
requires = []
2+
requires = [
3+
# "setuptools>=77",
4+
# "setuptools_scm[toml]>=3.4.1",
5+
# jaraco/skeleton#174
6+
"coherent.licensed",
7+
]
38
build-backend = "setuptools.build_meta"
49
backend-path = ["."]
510

611
[project]
712
name = "setuptools"
8-
version = "80.3.0"
13+
version = "80.7.1"
914
authors = [
1015
{ name = "Python Packaging Authority", email = "[email protected]" },
1116
]

setuptools/__init__.py

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import functools
1111
import os
12-
import re
1312
import sys
1413
from abc import abstractmethod
1514
from collections.abc import Mapping
@@ -30,7 +29,6 @@
3029
from .warnings import SetuptoolsDeprecationWarning
3130

3231
import distutils.core
33-
from distutils.errors import DistutilsOptionError
3432

3533
__all__ = [
3634
'setup',
@@ -175,42 +173,6 @@ def __init__(self, dist: Distribution, **kw) -> None:
175173
super().__init__(dist)
176174
vars(self).update(kw)
177175

178-
def _ensure_stringlike(self, option, what, default=None):
179-
val = getattr(self, option)
180-
if val is None:
181-
setattr(self, option, default)
182-
return default
183-
elif not isinstance(val, str):
184-
raise DistutilsOptionError(f"'{option}' must be a {what} (got `{val}`)")
185-
return val
186-
187-
def ensure_string_list(self, option: str) -> None:
188-
r"""Ensure that 'option' is a list of strings. If 'option' is
189-
currently a string, we split it either on /,\s*/ or /\s+/, so
190-
"foo bar baz", "foo,bar,baz", and "foo, bar baz" all become
191-
["foo", "bar", "baz"].
192-
193-
..
194-
TODO: This method seems to be similar to the one in ``distutils.cmd``
195-
Probably it is just here for backward compatibility with old Python versions?
196-
197-
:meta private:
198-
"""
199-
val = getattr(self, option)
200-
if val is None:
201-
return
202-
elif isinstance(val, str):
203-
setattr(self, option, re.split(r',\s*|\s+', val))
204-
else:
205-
if isinstance(val, list):
206-
ok = all(isinstance(v, str) for v in val)
207-
else:
208-
ok = False
209-
if not ok:
210-
raise DistutilsOptionError(
211-
f"'{option}' must be a list of strings (got {val!r})"
212-
)
213-
214176
@overload
215177
def reinitialize_command(
216178
self, command: str, reinit_subcommands: bool = False, **kw

0 commit comments

Comments
 (0)