Skip to content

Commit

Permalink
Merge branch 'main' into fix/3777
Browse files Browse the repository at this point in the history
  • Loading branch information
di authored Jan 9, 2025
2 parents c1bf7c7 + fb7f3d3 commit cb18737
Show file tree
Hide file tree
Showing 99 changed files with 1,074 additions and 619 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 = 75.6.0
current_version = 75.8.0
commit = True
tag = True

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
working-directory: setuptools/tests/config
run: python -m downloads.preload setupcfg_examples.txt
- name: Adjust env vars
shell: bash
run: |
echo 'PIPX_DEFAULT_PYTHON=${{ steps.python-install.outputs.python-path }}' >> $GITHUB_ENV
- name: Pre-build distributions for test
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.1
rev: v0.8.0
hooks:
- id: ruff
args: [--fix, --unsafe-fixes]
Expand Down
21 changes: 21 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
v75.8.0
=======

Features
--------

- Implemented ``Dynamic`` field for core metadata (as introduced in PEP 643).
The existing implementation is currently experimental and the exact approach
may change in future releases. (#4698)


v75.7.0
=======

Features
--------

- Synced with pypa/distutils@c97a3db2f including better support for free threaded Python on Windows (pypa/distutils#310), improved typing support, and linter accommodations. (#4478)
- Synced with pypa/distutils@ff11eed0c including bugfix for duplicate CFLAGS and adaption to support Python 3.13 is_abs in the C compiler (#4669). (#4790)


v75.6.0
=======

Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/extension.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ a non-``None`` value. Here's an example validation function::
"""Verify that value is True, False, 0, or 1"""
if bool(value) != value:
raise SetupError(
"%r must be a boolean value (got %r)" % (attr,value)
f"{attr!r} must be a boolean value (got {value!r}"
)

Your function should accept three arguments: the ``Distribution`` object,
Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Package discovery
-----------------
For projects that follow a simple directory structure, ``setuptools`` should be
able to automatically detect all :term:`packages <package>` and
:term:`namespaces <namespace-package>`. However, complex projects might include
:term:`namespaces <namespace package>`. However, complex projects might include
additional folders and supporting files that not necessarily should be
distributed (or that can confuse ``setuptools`` auto discovery algorithm).

Expand Down
6 changes: 3 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ ignore_missing_imports = True

# - wheel: does not intend on exposing a programmatic API https://github.com/pypa/wheel/pull/610#issuecomment-2081687671
[mypy-wheel.*]
ignore_missing_imports = True
follow_untyped_imports = True
# - The following are not marked as py.typed:
# - jaraco: Since mypy 1.12, the root name of the untyped namespace package gets called-out too
# - jaraco.develop: https://github.com/jaraco/jaraco.develop/issues/22
# - jaraco.envs: https://github.com/jaraco/jaraco.envs/issues/7
# - jaraco.packaging: https://github.com/jaraco/jaraco.packaging/issues/20
# - jaraco.path: https://github.com/jaraco/jaraco.path/issues/2
# - jaraco.text: https://github.com/jaraco/jaraco.text/issues/17
[mypy-jaraco,jaraco.develop,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.text]
ignore_missing_imports = True
[mypy-jaraco,jaraco.develop.*,jaraco.envs,jaraco.packaging.*,jaraco.path,jaraco.text]
follow_untyped_imports = True

# Even when excluding a module, import issues can show up due to following import
# https://github.com/python/mypy/issues/11936#issuecomment-1466764006
Expand Down
63 changes: 26 additions & 37 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ def get_supported_platform():
m = macosVersionString.match(plat)
if m is not None and sys.platform == "darwin":
try:
plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3))
major_minor = '.'.join(_macos_vers()[:2])
build = m.group(3)
plat = f'macosx-{major_minor}-{build}'
except ValueError:
# not macOS
pass
Expand Down Expand Up @@ -449,12 +451,8 @@ def get_build_platform():
if sys.platform == "darwin" and not plat.startswith('macosx-'):
try:
version = _macos_vers()
machine = os.uname()[4].replace(" ", "_")
return "macosx-%d.%d-%s" % (
int(version[0]),
int(version[1]),
_macos_arch(machine),
)
machine = _macos_arch(os.uname()[4].replace(" ", "_"))
return f"macosx-{version[0]}.{version[1]}-{machine}"
except ValueError:
# if someone is running a non-Mac darwin system, this will fall
# through to the default implementation
Expand Down Expand Up @@ -492,7 +490,7 @@ def compatible_platforms(provided: str | None, required: str | None) -> bool:
provDarwin = darwinVersionString.match(provided)
if provDarwin:
dversion = int(provDarwin.group(1))
macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2))
macosversion = f"{reqMac.group(1)}.{reqMac.group(2)}"
if (
dversion == 7
and macosversion >= "10.3"
Expand Down Expand Up @@ -875,9 +873,7 @@ def resolve(

# Mapping of requirement to set of distributions that required it;
# useful for reporting info about conflicts.
required_by: collections.defaultdict[Requirement, set[str]] = (
collections.defaultdict(set)
)
required_by = collections.defaultdict[Requirement, set[str]](set)

while requirements:
# process dependencies breadth-first
Expand Down Expand Up @@ -1316,7 +1312,7 @@ def __iadd__(self, other: Distribution | Environment) -> Self:
for dist in other[project]:
self.add(dist)
else:
raise TypeError("Can't add %r to environment" % (other,))
raise TypeError(f"Can't add {other!r} to environment")
return self

def __add__(self, other: Distribution | Environment) -> Self:
Expand Down Expand Up @@ -1699,7 +1695,7 @@ def get_metadata(self, name: str) -> str:
except UnicodeDecodeError as exc:
# Include the path in the error message to simplify
# troubleshooting, and without changing the exception type.
exc.reason += ' in {} file at path: {}'.format(name, path)
exc.reason += f' in {name} file at path: {path}'
raise

def get_metadata_lines(self, name: str) -> Iterator[str]:
Expand Down Expand Up @@ -2018,15 +2014,15 @@ def _zipinfo_name(self, fspath):
return ''
if fspath.startswith(self.zip_pre):
return fspath[len(self.zip_pre) :]
raise AssertionError("%s is not a subpath of %s" % (fspath, self.zip_pre))
raise AssertionError(f"{fspath} is not a subpath of {self.zip_pre}")

def _parts(self, zip_path):
# Convert a zipfile subpath into an egg-relative path part list.
# pseudo-fs path
fspath = self.zip_pre + zip_path
if fspath.startswith(self.egg_root + os.sep):
return fspath[len(self.egg_root) + 1 :].split(os.sep)
raise AssertionError("%s is not a subpath of %s" % (fspath, self.egg_root))
raise AssertionError(f"{fspath} is not a subpath of {self.egg_root}")

@property
def zipinfo(self):
Expand Down Expand Up @@ -2729,15 +2725,16 @@ def __init__(
self.dist = dist

def __str__(self) -> str:
s = "%s = %s" % (self.name, self.module_name)
s = f"{self.name} = {self.module_name}"
if self.attrs:
s += ':' + '.'.join(self.attrs)
if self.extras:
s += ' [%s]' % ','.join(self.extras)
extras = ','.join(self.extras)
s += f' [{extras}]'
return s

def __repr__(self) -> str:
return "EntryPoint.parse(%r)" % str(self)
return f"EntryPoint.parse({str(self)!r})"

@overload
def load(
Expand Down Expand Up @@ -3049,9 +3046,7 @@ def version(self):
version = self._get_version()
if version is None:
path = self._get_metadata_path_for_display(self.PKG_INFO)
msg = ("Missing 'Version:' header and/or {} file at path: {}").format(
self.PKG_INFO, path
)
msg = f"Missing 'Version:' header and/or {self.PKG_INFO} file at path: {path}"
raise ValueError(msg, self) from e

return version
Expand Down Expand Up @@ -3107,9 +3102,7 @@ def requires(self, extras: Iterable[str] = ()) -> list[Requirement]:
try:
deps.extend(dm[safe_extra(ext)])
except KeyError as e:
raise UnknownExtra(
"%s has no such extra feature %r" % (self, ext)
) from e
raise UnknownExtra(f"{self} has no such extra feature {ext!r}") from e
return deps

def _get_metadata_path_for_display(self, name):
Expand Down Expand Up @@ -3150,19 +3143,15 @@ def activate(self, path: list[str] | None = None, replace: bool = False) -> None

def egg_name(self):
"""Return what this distribution's standard .egg filename should be"""
filename = "%s-%s-py%s" % (
to_filename(self.project_name),
to_filename(self.version),
self.py_version or PY_MAJOR,
)
filename = f"{to_filename(self.project_name)}-{to_filename(self.version)}-py{self.py_version or PY_MAJOR}"

if self.platform:
filename += '-' + self.platform
return filename

def __repr__(self) -> str:
if self.location:
return "%s (%s)" % (self, self.location)
return f"{self} ({self.location})"
else:
return str(self)

Expand All @@ -3172,7 +3161,7 @@ def __str__(self) -> str:
except ValueError:
version = None
version = version or "[unknown version]"
return "%s %s" % (self.project_name, version)
return f"{self.project_name} {version}"

def __getattr__(self, attr: str):
"""Delegate all unrecognized public attributes to .metadata provider"""
Expand Down Expand Up @@ -3200,17 +3189,17 @@ def from_filename(
def as_requirement(self):
"""Return a ``Requirement`` that matches this distribution exactly"""
if isinstance(self.parsed_version, packaging.version.Version):
spec = "%s==%s" % (self.project_name, self.parsed_version)
spec = f"{self.project_name}=={self.parsed_version}"
else:
spec = "%s===%s" % (self.project_name, self.parsed_version)
spec = f"{self.project_name}==={self.parsed_version}"

return Requirement.parse(spec)

def load_entry_point(self, group: str, name: str) -> _ResolvedEntryPoint:
"""Return the `name` entry point of `group` or raise ImportError"""
ep = self.get_entry_info(group, name)
if ep is None:
raise ImportError("Entry point %r not found" % ((group, name),))
raise ImportError(f"Entry point {(group, name)!r} not found")
return ep.load()

@overload
Expand Down Expand Up @@ -3327,8 +3316,8 @@ def check_version_conflict(self):
):
continue
issue_warning(
"Module %s was already imported from %s, but %s is being added"
" to sys.path" % (modname, fn, self.location),
f"Module {modname} was already imported from {fn}, "
f"but {self.location} is being added to sys.path",
)

def has_version(self) -> bool:
Expand Down Expand Up @@ -3512,7 +3501,7 @@ def __hash__(self) -> int:
return self.__hash

def __repr__(self) -> str:
return "Requirement.parse(%r)" % str(self)
return f"Requirement.parse({str(self)!r})"

@staticmethod
def parse(s: str | Iterable[str]) -> Requirement:
Expand Down
10 changes: 5 additions & 5 deletions pkg_resources/tests/test_pkg_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ def test_get_metadata__bad_utf8(tmpdir):
"codec can't decode byte 0xe9 in position 1: "
'invalid continuation byte in METADATA file at path: '
)
assert expected in actual, 'actual: {}'.format(actual)
assert actual.endswith(metadata_path), 'actual: {}'.format(actual)
assert expected in actual, f'actual: {actual}'
assert actual.endswith(metadata_path), f'actual: {actual}'


def make_distribution_no_version(tmpdir, basename):
Expand Down Expand Up @@ -252,11 +252,11 @@ def test_distribution_version_missing(
"""
Test Distribution.version when the "Version" header is missing.
"""
basename = 'foo.{}'.format(suffix)
basename = f'foo.{suffix}'
dist, dist_dir = make_distribution_no_version(tmpdir, basename)

expected_text = ("Missing 'Version:' header and/or {} file at path: ").format(
expected_filename
expected_text = (
f"Missing 'Version:' header and/or {expected_filename} file at path: "
)
metadata_path = os.path.join(dist_dir, expected_filename)

Expand Down
10 changes: 7 additions & 3 deletions pkg_resources/tests/test_working_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,13 @@ def parametrize_test_working_set_resolve(*test_list):
)
)
return pytest.mark.parametrize(
'installed_dists,installable_dists,'
'requirements,replace_conflicting,'
'resolved_dists_or_exception',
(
"installed_dists",
"installable_dists",
"requirements",
"replace_conflicting",
"resolved_dists_or_exception",
),
argvalues,
ids=idlist,
)
Expand Down
12 changes: 6 additions & 6 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 = "75.6.0"
version = "75.8.0"
authors = [
{ name = "Python Packaging Authority", email = "[email protected]" },
]
Expand Down Expand Up @@ -44,7 +44,7 @@ test = [
"packaging>=24.2",
"jaraco.envs>=2.2",
"pytest-xdist>=3", # Dropped dependency on pytest-fork and py
"jaraco.path>=3.2.0",
"jaraco.path>=3.7.2", # Typing fixes
"build[virtualenv]>=1.0.3",
"filelock>=3.4.0",
"ini2toml[lite]>=0.14",
Expand Down Expand Up @@ -102,7 +102,7 @@ core = [

# for distutils
"jaraco.collections",
"jaraco.functools>=4",
"jaraco.functools >= 4",
"packaging",
"more_itertools",
]
Expand All @@ -114,8 +114,8 @@ check = [

# local

# changed defaults for PT001 and PT023 astral-sh/ruff#13292
"ruff >= 0.7.0; sys_platform != 'cygwin'",
# Removal of deprecated UP027, PT004 & PT005 astral-sh/ruff#14383
"ruff >= 0.8.0; sys_platform != 'cygwin'",
]

cover = [
Expand All @@ -135,7 +135,7 @@ type = [
# pin mypy version so a new version doesn't suddenly cause the CI to fail,
# until types-setuptools is removed from typeshed.
# For help with static-typing issues, or mypy update, ping @Avasam
"mypy>=1.12,<1.14",
"mypy==1.14.*",
# Typing fixes in version newer than we require at runtime
"importlib_metadata>=7.0.2; python_version < '3.10'",
# Imported unconditionally in tools/finalize.py
Expand Down
6 changes: 0 additions & 6 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,12 @@ extend-select = [
]
ignore = [
"PERF203", # try-except-in-loop, micro-optimisation with many false-positive. Worth checking but don't block CI
"PT004", # deprecated https://github.com/astral-sh/ruff/issues/8796#issuecomment-2057143531
"PT005", # deprecated https://github.com/astral-sh/ruff/issues/8796#issuecomment-2057143531
"PT007", # temporarily disabled, TODO: configure and standardize to preference
"PT011", # temporarily disabled, TODO: tighten expected error
"PT012", # pytest-raises-with-multiple-statements, avoid extra dummy methods for a few lines, sometimes we explicitly assert in case of no error
"TRY003", # raise-vanilla-args, avoid multitude of exception classes
"TRY301", # raise-within-try, it's handy
"UP015", # redundant-open-modes, explicit is preferred
"UP027", # unpacked-list-comprehension, is actually slower for cases relevant to unpacking, set for deprecation: https://github.com/astral-sh/ruff/issues/12754
"UP030", # temporarily disabled
"UP031", # temporarily disabled
"UP032", # temporarily disabled
"UP038", # Using `X | Y` in `isinstance` call is slower and more verbose https://github.com/astral-sh/ruff/issues/7871
# Only enforcing return type annotations for public functions
"ANN202", # missing-return-type-private-function
Expand Down
Loading

0 comments on commit cb18737

Please sign in to comment.