Skip to content

Commit

Permalink
Merge branch 'main' into pkg_resources-explicit-public-return-annotat…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
Avasam authored Jun 24, 2024
2 parents 47cdab6 + 48ce5ed commit 31468cd
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 70.0.0
current_version = 70.1.0
commit = True
tag = True

Expand Down
44 changes: 43 additions & 1 deletion NEWS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
v70.1.0
=======

Features
--------

- Adopted the ``bdist_wheel`` command from the ``wheel`` project -- by :user:`agronholm` (#1386)
- Improve error message when ``pkg_resources.ZipProvider`` tries to extract resources with a missing Egg -- by :user:`Avasam`

Added variables and parameter type annotations to ``pkg_resources`` to be nearly on par with typeshed.\* -- by :user:`Avasam`
\* Excluding ``TypeVar`` and ``overload``. Return types are currently inferred. (#4246)
- Migrated Setuptools' own config to pyproject.toml (#4310)


Bugfixes
--------

- Prevent a ``TypeError: 'NoneType' object is not callable`` when ``shutil_rmtree`` is called without an ``onexc`` parameter on Python<=3.11 -- by :user:`Avasam` (#4382)
- Replace use of mktemp with can_symlink from the stdlib test suite. (#4403)
- Improvement for ``attr:`` directives in configuration to handle
more edge cases related to complex ``package_dir``. (#4405)
- Fix accidental implicit string concatenation. (#4411)


Misc
----

- #4365, #4422


v70.0.0
=======

Expand Down Expand Up @@ -109,7 +139,19 @@ v69.3.0
Features
--------

- Support PEP 625 by canonicalizing package name and version in filenames. (#3593)
- Support PEP 625 by canonicalizing package name and version in filenames
per
`the spec <https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name>`_.
Projects whose names contain uppercase characters, dashes, or periods will
now see their sdist names normalized to match the standard and the format
previously seen in wheels. For example:

- ``zope.interface`` -> ``zope_interface``
- ``CherryPy`` -> ``cherrypy``
- ``foo-bar_baz`` -> ``foo_bar_baz``

Projects are encouraged to adopt this change to align with standards and
other backend build systems. (#3593)


v69.2.0
Expand Down
1 change: 0 additions & 1 deletion newsfragments/1386.feature.rst

This file was deleted.

4 changes: 0 additions & 4 deletions newsfragments/4246.feature.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/4310.feature.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/4365.misc.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/4382.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/4403.bugfix.rst

This file was deleted.

2 changes: 0 additions & 2 deletions newsfragments/4405.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion newsfragments/4411.bugfix.rst

This file was deleted.

51 changes: 43 additions & 8 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,15 +756,15 @@ def __iter__(self) -> Iterator[Distribution]:
The yield order is the order in which the items' path entries were
added to the working set.
"""
seen = {}
seen = set()
for item in self.entries:
if item not in self.entry_keys:
# workaround a cache issue
continue

for key in self.entry_keys[item]:
if key not in seen:
seen[key] = True
seen.add(key)
yield self.by_key[key]

def add(
Expand Down Expand Up @@ -868,7 +868,7 @@ def resolve(
# set up the stack
requirements = list(requirements)[::-1]
# set of processed requirements
processed = {}
processed = set()
# key -> dist
best = {}
to_activate = []
Expand Down Expand Up @@ -902,7 +902,7 @@ def resolve(
required_by[new_requirement].add(req.project_name)
req_extras[new_requirement] = req.extras

processed[req] = True
processed.add(req)

# return list of distros to activate
return to_activate
Expand Down Expand Up @@ -1446,7 +1446,7 @@ def get_cache_path(self, archive_name: str, names: Iterable[StrPath] = ()) -> st

self._warn_unsafe_extraction_path(extract_path)

self.cached_files[target_path] = 1
self.cached_files[target_path] = True
return target_path

@staticmethod
Expand Down Expand Up @@ -1719,8 +1719,7 @@ def run_script(self, script_name: str, namespace: dict[str, Any]) -> None:
**locals()
),
)
if not self.egg_info:
raise TypeError("Provider is missing egg_info", self.egg_info)

script_text = self.get_metadata(script).replace('\r\n', '\n')
script_text = script_text.replace('\r', '\n')
script_filename = self._fn(self.egg_info, script)
Expand Down Expand Up @@ -1756,7 +1755,11 @@ def _listdir(self, path) -> list[str]:
"Can't perform this operation for unregistered loader type"
)

def _fn(self, base: str, resource_name: str):
def _fn(self, base: str | None, resource_name: str):
if base is None:
raise TypeError(
"`base` parameter in `_fn` is `None`. Either override this method or check the parameter first."
)
self._validate_resource_path(resource_name)
if resource_name:
return os.path.join(base, *resource_name.split('/'))
Expand Down Expand Up @@ -3591,6 +3594,38 @@ class PkgResourcesDeprecationWarning(Warning):
"""


# Ported from ``setuptools`` to avoid introducing an import inter-dependency:
_LOCALE_ENCODING = "locale" if sys.version_info >= (3, 10) else None


def _read_utf8_with_fallback(file: str, fallback_encoding=_LOCALE_ENCODING) -> str:
"""See setuptools.unicode_utils._read_utf8_with_fallback"""
try:
with open(file, "r", encoding="utf-8") as f:
return f.read()
except UnicodeDecodeError: # pragma: no cover
msg = f"""\
********************************************************************************
`encoding="utf-8"` fails with {file!r}, trying `encoding={fallback_encoding!r}`.
This fallback behaviour is considered **deprecated** and future versions of
`setuptools/pkg_resources` may not implement it.
Please encode {file!r} with "utf-8" to ensure future builds will succeed.
If this file was produced by `setuptools` itself, cleaning up the cached files
and re-building/re-installing the package with a newer version of `setuptools`
(e.g. by updating `build-system.requires` in its `pyproject.toml`)
might solve the problem.
********************************************************************************
"""
# TODO: Add a deadline?
# See comment in setuptools.unicode_utils._Utf8EncodingNeeded
warnings.warn(msg, PkgResourcesDeprecationWarning, stacklevel=2)
with open(file, "r", encoding=fallback_encoding) as f:
return f.read()


# from jaraco.functools 1.3
def _call_aside(f, *args, **kwargs):
f(*args, **kwargs)
Expand Down
54 changes: 54 additions & 0 deletions pkg_resources/tests/test_integration_zope_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import platform
from inspect import cleandoc

import jaraco.path
import pytest

pytestmark = pytest.mark.integration


# For the sake of simplicity this test uses fixtures defined in
# `setuptools.test.fixtures`,
# and it also exercise conditions considered deprecated...
# So if needed this test can be deleted.
@pytest.mark.skipif(
platform.system() != "Linux",
reason="only demonstrated to fail on Linux in #4399",
)
def test_interop_pkg_resources_iter_entry_points(tmp_path, venv):
"""
Importing pkg_resources.iter_entry_points on console_scripts
seems to cause trouble with zope-interface, when deprecates installation method
is used. See #4399.
"""
project = {
"pkg": {
"foo.py": cleandoc(
"""
from pkg_resources import iter_entry_points
def bar():
print("Print me if you can")
"""
),
"setup.py": cleandoc(
"""
from setuptools import setup, find_packages
setup(
install_requires=["zope-interface==6.4.post2"],
entry_points={
"console_scripts": [
"foo=foo:bar",
],
},
)
"""
),
}
}
jaraco.path.build(project, prefix=tmp_path)
cmd = ["pip", "install", "-e", ".", "--no-use-pep517"]
venv.run(cmd, cwd=tmp_path / "pkg") # Needs this version of pkg_resources installed
out = venv.run(["foo"])
assert "Print me if you can" in out
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ backend-path = ["."]

[project]
name = "setuptools"
version = "70.0.0"
version = "70.1.0"
authors = [
{ name = "Python Packaging Authority", email = "distutils-sig@python.org" },
]
Expand Down Expand Up @@ -160,15 +160,14 @@ PKG-INFO = "setuptools.command.egg_info:write_pkg_info"
include-package-data = false

[tool.setuptools.packages.find]
include = [
"setuptools*",
"pkg_resources*",
"_distutils_hack*",
]
exclude = [
"*.tests",
"*.tests.*",
"tools*",
"debian*",
"launcher*",
"newsfragments*",
"docs",
"docs.*",
]
namespaces = true

Expand Down
4 changes: 1 addition & 3 deletions setuptools/command/bdist_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,7 @@ def finalize_options(self):
wheel = self.distribution.get_option_dict("wheel")
if "universal" in wheel:
# please don't define this in your global configs
log.warning(
"The [wheel] section is deprecated. Use [bdist_wheel] instead.",
)
log.warn("The [wheel] section is deprecated. Use [bdist_wheel] instead.")
val = wheel["universal"][1].strip()
if val.lower() in ("1", "true", "yes"):
self.universal = True
Expand Down
16 changes: 8 additions & 8 deletions setuptools/command/easy_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ def exe_to_egg(self, dist_filename, egg_tmp): # noqa: C901
prefixes = get_exe_prefixes(dist_filename)
to_compile = []
native_libs = []
top_level = {}
top_level = set()

def process(src, dst):
s = src.lower()
Expand All @@ -1059,10 +1059,10 @@ def process(src, dst):
dl = dst.lower()
if dl.endswith('.pyd') or dl.endswith('.dll'):
parts[-1] = bdist_egg.strip_module(parts[-1])
top_level[os.path.splitext(parts[0])[0]] = True
top_level.add([os.path.splitext(parts[0])[0]])
native_libs.append(src)
elif dl.endswith('.py') and old != 'SCRIPTS/':
top_level[os.path.splitext(parts[0])[0]] = True
top_level.add([os.path.splitext(parts[0])[0]])
to_compile.append(dst)
return dst
if not src.endswith('.pth'):
Expand Down Expand Up @@ -1484,14 +1484,14 @@ def get_site_dirs():
def expand_paths(inputs): # noqa: C901 # is too complex (11) # FIXME
"""Yield sys.path directories that might contain "old-style" packages"""

seen = {}
seen = set()

for dirname in inputs:
dirname = normalize_path(dirname)
if dirname in seen:
continue

seen[dirname] = True
seen.add(dirname)
if not os.path.isdir(dirname):
continue

Expand Down Expand Up @@ -1520,7 +1520,7 @@ def expand_paths(inputs): # noqa: C901 # is too complex (11) # FIXME
if line in seen:
continue

seen[line] = True
seen.add(line)
if not os.path.isdir(line):
continue

Expand Down Expand Up @@ -1622,7 +1622,7 @@ def __init__(self, filename, sitedirs=()):
def _load_raw(self):
paths = []
dirty = saw_import = False
seen = dict.fromkeys(self.sitedirs)
seen = set(self.sitedirs)
f = open(self.filename, 'rt', encoding=py39.LOCALE_ENCODING)
# ^-- Requires encoding="locale" instead of "utf-8" (python/cpython#77102).
for line in f:
Expand All @@ -1643,7 +1643,7 @@ def _load_raw(self):
dirty = True
paths.pop()
continue
seen[normalized_path] = True
seen.add(normalized_path)
f.close()
# remove any trailing empty/blank line
while paths and not paths[-1].strip():
Expand Down
4 changes: 2 additions & 2 deletions setuptools/package_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ def fetch_distribution( # noqa: C901 # is too complex (14) # FIXME
"""
# process a Requirement
self.info("Searching for %s", requirement)
skipped = {}
skipped = set()
dist = None

def find(req, env=None):
Expand All @@ -642,7 +642,7 @@ def find(req, env=None):
"Skipping development or system egg: %s",
dist,
)
skipped[dist] = True
skipped.add(dist)
continue

test = dist in req and (dist.precedence <= SOURCE_DIST or not source)
Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/test_dist_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def test_output_dir(self, tmp_path, keep_egg_info):
run_command("dist_info", "--output-dir", out, *opts, cwd=tmp_path)
assert len(list(out.glob("*.dist-info"))) == 1
assert len(list(tmp_path.glob("*.dist-info"))) == 0
expected_egg_info = 1 if keep_egg_info else 0
expected_egg_info = int(keep_egg_info)
assert len(list(out.glob("*.egg-info"))) == expected_egg_info
assert len(list(tmp_path.glob("*.egg-info"))) == 0
assert len(list(out.glob("*.__bkp__"))) == 0
Expand Down

0 comments on commit 31468cd

Please sign in to comment.