From 1675b390e49ffff5acab16ee0351e7bc1e113fb0 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Fri, 8 Nov 2024 15:17:12 +0530 Subject: [PATCH 01/11] Bump for development --- CHANGELOG.rst | 5 +++++ src/packaging/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 45285b389..a5948af76 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ Changelog --------- +*unreleased* +~~~~~~~~~~~~ + +No unreleased changes. + 24.2 - 2024-11-08 ~~~~~~~~~~~~~~~~~ diff --git a/src/packaging/__init__.py b/src/packaging/__init__.py index d79f73c57..6d3981569 100644 --- a/src/packaging/__init__.py +++ b/src/packaging/__init__.py @@ -6,7 +6,7 @@ __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "24.2" +__version__ = "24.3.dev0" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io" From 2256ed4ac261309a09daa04cc801abd7cff2e6f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 09:23:21 -0800 Subject: [PATCH 02/11] Bump the github-actions group across 1 directory with 2 updates (#864) Bumps the github-actions group with 2 updates in the / directory: [github/codeql-action](https://github.com/github/codeql-action) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `github/codeql-action` from 3.27.0 to 3.28.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/662472033e021d55d94146f66f6058822b0b39fd...48ab28a6f5dbc2a99bf1e0131198dd8f1df78169) Updates `actions/upload-artifact` from 4.4.3 to 4.5.0 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882...6f51ac03b9356f520e9adb1b1b7802705f340c2b) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/lint.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 98bcad28e..f2bad0f72 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -47,9 +47,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - name: Autobuild - uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b35ec45cf..be4f73836 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -52,7 +52,7 @@ jobs: run: pipx run build - name: Archive files - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: dist path: dist From 9375ec2eff48257967c97d331b9a76019e95bdb0 Mon Sep 17 00:00:00 2001 From: Siddhesh Agarwal Date: Thu, 9 Jan 2025 01:09:40 +0530 Subject: [PATCH 03/11] Re-add tests for Unicode file name parsing (#863) This reverts d3388aa83109515de5c17e9fc26e2d09b9648ed3 . --- tests/test_utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_utils.py b/tests/test_utils.py index 87c86eefd..a8cc8d71e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -123,6 +123,20 @@ def test_canonicalize_version_no_strip_trailing_zero(version): (1000, "abc"), {Tag("py3", "none", "any")}, ), + ( + "foo_bár-1.0-py3-none-any.whl", + "foo-bár", + Version("1.0"), + (), + {Tag("py3", "none", "any")}, + ), + ( + "foo_bár-1.0-1000-py3-none-any.whl", + "foo-bár", + Version("1.0"), + (1000, ""), + {Tag("py3", "none", "any")}, + ), ], ) def test_parse_wheel_filename(filename, name, version, build, tags): From 8510bd9d3bab5571974202ec85f6ef7b0359bfaf Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:51:40 +0100 Subject: [PATCH 04/11] Upgrade to ruff 0.9.1 (#865) --- .pre-commit-config.yaml | 2 +- pyproject.toml | 3 +-- src/packaging/_elffile.py | 3 +-- src/packaging/_manylinux.py | 3 +-- src/packaging/_parser.py | 3 +-- src/packaging/_tokenizer.py | 6 +++--- src/packaging/licenses/__init__.py | 2 +- src/packaging/metadata.py | 3 +-- src/packaging/specifiers.py | 3 +-- tests/test_markers.py | 12 ++++-------- 10 files changed, 15 insertions(+), 25 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5e4db59a8..068b2e699 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: additional_dependencies: [pyparsing, nox] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.11 + rev: v0.9.1 hooks: - id: ruff args: [ --fix ] diff --git a/pyproject.toml b/pyproject.toml index 985fd1809..12db2105c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,7 @@ extend-select = [ ] ignore = [ "B027", + "F821", "N818", "RUF003", "RUF012", @@ -95,6 +96,4 @@ ignore = [ "Q003", "COM812", "COM819", - "ISC001", - "ISC002", ] diff --git a/src/packaging/_elffile.py b/src/packaging/_elffile.py index 25f4282cc..7a5afc33b 100644 --- a/src/packaging/_elffile.py +++ b/src/packaging/_elffile.py @@ -69,8 +69,7 @@ def __init__(self, f: IO[bytes]) -> None: }[(self.capacity, self.encoding)] except KeyError as e: raise ELFInvalid( - f"unrecognized capacity ({self.capacity}) or " - f"encoding ({self.encoding})" + f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})" ) from e try: diff --git a/src/packaging/_manylinux.py b/src/packaging/_manylinux.py index 61339a6fc..95f55762e 100644 --- a/src/packaging/_manylinux.py +++ b/src/packaging/_manylinux.py @@ -161,8 +161,7 @@ def _parse_glibc_version(version_str: str) -> tuple[int, int]: m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) if not m: warnings.warn( - f"Expected glibc version with 2 components major.minor," - f" got: {version_str}", + f"Expected glibc version with 2 components major.minor, got: {version_str}", RuntimeWarning, stacklevel=2, ) diff --git a/src/packaging/_parser.py b/src/packaging/_parser.py index c1238c06e..0007c0aa6 100644 --- a/src/packaging/_parser.py +++ b/src/packaging/_parser.py @@ -349,6 +349,5 @@ def _parse_marker_op(tokenizer: Tokenizer) -> Op: return Op(tokenizer.read().text) else: return tokenizer.raise_syntax_error( - "Expected marker operator, one of " - "<=, <, !=, ==, >=, >, ~=, ===, in, not in" + "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in" ) diff --git a/src/packaging/_tokenizer.py b/src/packaging/_tokenizer.py index 89d041605..4cef3a2c6 100644 --- a/src/packaging/_tokenizer.py +++ b/src/packaging/_tokenizer.py @@ -119,9 +119,9 @@ def check(self, name: str, *, peek: bool = False) -> bool: another check. If `peek` is set to `True`, the token is not loaded and would need to be checked again. """ - assert ( - self.next_token is None - ), f"Cannot check for {name!r}, already have {self.next_token!r}" + assert self.next_token is None, ( + f"Cannot check for {name!r}, already have {self.next_token!r}" + ) assert name in self.rules, f"Unknown token name: {name!r}" expression = self.rules[name] diff --git a/src/packaging/licenses/__init__.py b/src/packaging/licenses/__init__.py index 569156d6c..6f7f9e628 100644 --- a/src/packaging/licenses/__init__.py +++ b/src/packaging/licenses/__init__.py @@ -37,8 +37,8 @@ from packaging.licenses._spdx import EXCEPTIONS, LICENSES __all__ = [ - "NormalizedLicenseExpression", "InvalidLicenseExpression", + "NormalizedLicenseExpression", "canonicalize_license_expression", ] diff --git a/src/packaging/metadata.py b/src/packaging/metadata.py index 721f411cf..3bd8602d3 100644 --- a/src/packaging/metadata.py +++ b/src/packaging/metadata.py @@ -678,8 +678,7 @@ def _process_license_files(self, value: list[str]) -> list[str]: ) if pathlib.PureWindowsPath(path).as_posix() != path: raise self._invalid_metadata( - f"{path!r} is invalid for {{field}}, " - "paths must use '/' delimiter" + f"{path!r} is invalid for {{field}}, paths must use '/' delimiter" ) paths.append(path) return paths diff --git a/src/packaging/specifiers.py b/src/packaging/specifiers.py index b30926af8..c84480430 100644 --- a/src/packaging/specifiers.py +++ b/src/packaging/specifiers.py @@ -816,8 +816,7 @@ def __and__(self, other: SpecifierSet | str) -> SpecifierSet: specifier._prereleases = self._prereleases else: raise ValueError( - "Cannot combine SpecifierSets with True and False prerelease " - "overrides." + "Cannot combine SpecifierSets with True and False prerelease overrides." ) return specifier diff --git a/tests/test_markers.py b/tests/test_markers.py index cf08b99ea..faf0d13b9 100644 --- a/tests/test_markers.py +++ b/tests/test_markers.py @@ -290,20 +290,17 @@ def test_environment_with_extra_none(self): True, ), ( - "python_version ~= '2.7.0' and (os_name == 'foo' or " - "os_name == 'bar')", + "python_version ~= '2.7.0' and (os_name == 'foo' or os_name == 'bar')", {"os_name": "foo", "python_version": "2.7.4"}, True, ), ( - "python_version ~= '2.7.0' and (os_name == 'foo' or " - "os_name == 'bar')", + "python_version ~= '2.7.0' and (os_name == 'foo' or os_name == 'bar')", {"os_name": "bar", "python_version": "2.7.4"}, True, ), ( - "python_version ~= '2.7.0' and (os_name == 'foo' or " - "os_name == 'bar')", + "python_version ~= '2.7.0' and (os_name == 'foo' or os_name == 'bar')", {"os_name": "other", "python_version": "2.7.4"}, False, ), @@ -350,8 +347,7 @@ def test_parses_pep345_valid(self, marker_string): False, ), ( - "python_version == '2.5' and platform.python_implementation" - "!= 'Jython'", + "python_version == '2.5' and platform.python_implementation!= 'Jython'", {"python_version": "2.7"}, False, ), From 9b4922dd3c26c8522d716bec79d7e0ed408631c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:50:05 -0800 Subject: [PATCH 05/11] Bump the github-actions group with 3 updates (#870) Bumps the github-actions group with 3 updates: [github/codeql-action](https://github.com/github/codeql-action), [actions/setup-python](https://github.com/actions/setup-python) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `github/codeql-action` from 3.28.0 to 3.28.8 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/48ab28a6f5dbc2a99bf1e0131198dd8f1df78169...dd746615b3b9d728a6a37ca2045b68ca76d4841a) Updates `actions/setup-python` from 5.3.0 to 5.4.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/0b93645e9fea7318ecaed2b359559ac225c90a2b...42375524e23c412d93fb67b49958b491fce71c38) Updates `actions/upload-artifact` from 4.5.0 to 4.6.0 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/6f51ac03b9356f520e9adb1b1b7802705f340c2b...65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/docs.yml | 2 +- .github/workflows/lint.yml | 4 ++-- .github/workflows/test.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f2bad0f72..acbf76f71 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -47,9 +47,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - name: Autobuild - uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/autobuild@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 36e012846..a2b9aeeac 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 name: Install Python with: python-version: "3.9" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index be4f73836..8241667f8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 name: Install Python with: python-version: "3.9" @@ -52,7 +52,7 @@ jobs: run: pipx run build - name: Archive files - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: name: dist path: dist diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8648dbc87..674e97c4f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 name: Install Python ${{ matrix.python_version }} with: python-version: ${{ matrix.python_version }} From 71f38d872a6e88b28da9d1b270f8512475bc90d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:25:30 -0800 Subject: [PATCH 06/11] Bump the github-actions group with 2 updates (#878) Bumps the github-actions group with 2 updates: [github/codeql-action](https://github.com/github/codeql-action) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `github/codeql-action` from 3.28.8 to 3.28.10 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/dd746615b3b9d728a6a37ca2045b68ca76d4841a...b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d) Updates `actions/upload-artifact` from 4.6.0 to 4.6.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08...4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/lint.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index acbf76f71..74e1fa7d0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -47,9 +47,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - name: Autobuild - uses: github/codeql-action/autobuild@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8241667f8..f54bd273a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -52,7 +52,7 @@ jobs: run: pipx run build - name: Archive files - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: dist path: dist From e624d8edfaa28865de7b5a7da8bd59fd410e5331 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 11:12:15 -0700 Subject: [PATCH 07/11] Bump the github-actions group with 3 updates (#886) Bumps the github-actions group with 3 updates: [github/codeql-action](https://github.com/github/codeql-action), [actions/setup-python](https://github.com/actions/setup-python) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `github/codeql-action` from 3.28.10 to 3.28.13 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d...1b549b9259bda1cb5ddde3b41741a82a2d15a841) Updates `actions/setup-python` from 5.4.0 to 5.5.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/42375524e23c412d93fb67b49958b491fce71c38...8d9ed9ac5c53483de85588cdf95a591a75ab9f55) Updates `actions/upload-artifact` from 4.6.1 to 4.6.2 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1...ea165f8d65b6e75b540449e92b4886f43607fa02) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/docs.yml | 2 +- .github/workflows/lint.yml | 4 ++-- .github/workflows/test.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 74e1fa7d0..8a1b1ae13 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -47,9 +47,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - name: Autobuild - uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/autobuild@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/analyze@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a2b9aeeac..dd830f39f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.9" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f54bd273a..11a6750fe 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python with: python-version: "3.9" @@ -52,7 +52,7 @@ jobs: run: pipx run build - name: Archive files - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: dist path: dist diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 674e97c4f..f837fcb36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 name: Install Python ${{ matrix.python_version }} with: python-version: ${{ matrix.python_version }} From 8e49b4373731bffb110c9583e64ad802cb67c7ea Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Wed, 16 Apr 2025 00:35:00 +0100 Subject: [PATCH 08/11] Add support for PEP 738 Android tags (#880) Co-authored-by: Brett Cannon --- docs/tags.rst | 15 ++++++++ src/packaging/tags.py | 39 +++++++++++++++++++++ tests/test_tags.py | 81 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) diff --git a/docs/tags.rst b/docs/tags.rst index 26afe92fa..8ec8c559b 100644 --- a/docs/tags.rst +++ b/docs/tags.rst @@ -168,6 +168,21 @@ to the implementation to provide. Behavior of this method is undefined if invoked on non-iOS platforms without providing explicit version and multiarch arguments. + +.. function:: android_platforms(api_level=None, abi=None) + + Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on + non-Android platforms, the ``api_level`` and ``abi`` arguments are required. + + :param int api_level: The maximum `API level + `__ to return. Defaults + to the current system's version, as returned by ``platform.android_ver``. + :param str abi: The `Android ABI `__, + e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by + ``sysconfig.get_platform``. Hyphens and periods will be replaced with + underscores. + + .. function:: platform_tags(version=None, arch=None) Yields the :attr:`~Tag.platform` tags for the running interpreter. diff --git a/src/packaging/tags.py b/src/packaging/tags.py index f5903402a..8522f59c4 100644 --- a/src/packaging/tags.py +++ b/src/packaging/tags.py @@ -530,6 +530,43 @@ def ios_platforms( ) +def android_platforms( + api_level: int | None = None, abi: str | None = None +) -> Iterator[str]: + """ + Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on + non-Android platforms, the ``api_level`` and ``abi`` arguments are required. + + :param int api_level: The maximum `API level + `__ to return. Defaults + to the current system's version, as returned by ``platform.android_ver``. + :param str abi: The `Android ABI `__, + e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by + ``sysconfig.get_platform``. Hyphens and periods will be replaced with + underscores. + """ + if platform.system() != "Android" and (api_level is None or abi is None): + raise TypeError( + "on non-Android platforms, the api_level and abi arguments are required" + ) + + if api_level is None: + # Python 3.13 was the first version to return platform.system() == "Android", + # and also the first version to define platform.android_ver(). + api_level = platform.android_ver().api_level # type: ignore[attr-defined] + + if abi is None: + abi = sysconfig.get_platform().split("-")[-1] + abi = _normalize_string(abi) + + # 16 is the minimum API level known to have enough features to support CPython + # without major patching. Yield every API level from the maximum down to the + # minimum, inclusive. + min_api_level = 16 + for ver in range(api_level, min_api_level - 1, -1): + yield f"android_{ver}_{abi}" + + def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]: linux = _normalize_string(sysconfig.get_platform()) if not linux.startswith("linux_"): @@ -561,6 +598,8 @@ def platform_tags() -> Iterator[str]: return mac_platforms() elif platform.system() == "iOS": return ios_platforms() + elif platform.system() == "Android": + return android_platforms() elif platform.system() == "Linux": return _linux_platforms() else: diff --git a/tests/test_tags.py b/tests/test_tags.py index 5ec89b244..012acb130 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -77,6 +77,23 @@ def mock_ios_ver(*args): monkeypatch.setattr(platform, "ios_ver", mock_ios_ver) +@pytest.fixture +def mock_android(monkeypatch): + monkeypatch.setattr(sys, "platform", "android") + monkeypatch.setattr(platform, "system", lambda: "Android") + monkeypatch.setattr(sysconfig, "get_platform", lambda: "android-21-arm64_v8a") + + AndroidVer = collections.namedtuple( + "AndroidVer", "release api_level manufacturer model device is_emulator" + ) + monkeypatch.setattr( + platform, + "android_ver", + lambda: AndroidVer("5.0", 21, "Google", "sdk_gphone64_arm64", "emu64a", True), + raising=False, # This function was added in Python 3.13. + ) + + class TestTag: def test_lowercasing(self): tag = tags.Tag("PY3", "None", "ANY") @@ -437,6 +454,69 @@ def test_ios_platforms(self, mock_ios): ] +class TestAndroidPlatforms: + def test_non_android(self): + non_android_error = pytest.raises(TypeError) + with non_android_error: + list(tags.android_platforms()) + with non_android_error: + list(tags.android_platforms(api_level=18)) + with non_android_error: + list(tags.android_platforms(abi="x86_64")) + + # The function can only be called on non-Android platforms if both arguments are + # provided. + assert list(tags.android_platforms(api_level=18, abi="x86_64")) == [ + "android_18_x86_64", + "android_17_x86_64", + "android_16_x86_64", + ] + + def test_detection(self, mock_android): + assert list(tags.android_platforms()) == [ + "android_21_arm64_v8a", + "android_20_arm64_v8a", + "android_19_arm64_v8a", + "android_18_arm64_v8a", + "android_17_arm64_v8a", + "android_16_arm64_v8a", + ] + + def test_api_level(self): + # API levels below the minimum should return nothing. + assert list(tags.android_platforms(api_level=14, abi="x86")) == [] + assert list(tags.android_platforms(api_level=15, abi="x86")) == [] + + assert list(tags.android_platforms(api_level=16, abi="x86")) == [ + "android_16_x86", + ] + assert list(tags.android_platforms(api_level=17, abi="x86")) == [ + "android_17_x86", + "android_16_x86", + ] + assert list(tags.android_platforms(api_level=18, abi="x86")) == [ + "android_18_x86", + "android_17_x86", + "android_16_x86", + ] + + def test_abi(self): + # Real ABI, normalized. + assert list(tags.android_platforms(api_level=16, abi="armeabi_v7a")) == [ + "android_16_armeabi_v7a", + ] + + # Real ABI, not normalized. + assert list(tags.android_platforms(api_level=16, abi="armeabi-v7a")) == [ + "android_16_armeabi_v7a", + ] + + # Nonexistent ABIs should still be accepted and normalized. + assert list(tags.android_platforms(api_level=16, abi="myarch-4.2")) == [ + "android_16_myarch_4_2", + ] + + class TestManylinuxPlatform: def teardown_method(self): # Clear the version cache @@ -722,6 +802,7 @@ def test_linux_not_linux(self, monkeypatch): [ ("Darwin", "mac_platforms"), ("iOS", "ios_platforms"), + ("Android", "android_platforms"), ("Linux", "_linux_platforms"), ("Generic", "_generic_platforms"), ], From 3910129009b25dd1aa1fe32e644bc891188c56fe Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 18 Apr 2025 06:36:58 +0800 Subject: [PATCH 09/11] support 'extras' and 'dependency_groups' markers (#888) Signed-off-by: Frost Ming Co-authored-by: Brett Cannon --- CHANGELOG.rst | 2 +- docs/markers.rst | 3 ++ src/packaging/_tokenizer.py | 3 +- src/packaging/markers.py | 75 ++++++++++++++++++++++++++----------- tests/test_markers.py | 32 ++++++++++++++++ 5 files changed, 91 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a5948af76..8c4a55794 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ Changelog *unreleased* ~~~~~~~~~~~~ -No unreleased changes. +* PEP 751: Add support for ``extras`` and ``dependency_groups`` markers. (:issue:`885`) 24.2 - 2024-11-08 ~~~~~~~~~~~~~~~~~ diff --git a/docs/markers.rst b/docs/markers.rst index e802dac03..def807327 100644 --- a/docs/markers.rst +++ b/docs/markers.rst @@ -64,6 +64,9 @@ Reference :param dict environment: A dictionary containing keys and values to override the detected environment. + :param str context: A string representing the context in which the marker is evaluated. + Acceptable values are "metadata" (for core metadata; default), + "lock_file", and "requirement" (i.e. all other situations). :raises: UndefinedComparison: If the marker uses a comparison on strings which are not valid versions per the :ref:`specification of version specifiers diff --git a/src/packaging/_tokenizer.py b/src/packaging/_tokenizer.py index 4cef3a2c6..d28a9b6cf 100644 --- a/src/packaging/_tokenizer.py +++ b/src/packaging/_tokenizer.py @@ -68,7 +68,8 @@ def __str__(self) -> str: |platform[._](version|machine|python_implementation) |python_implementation |implementation_(name|version) - |extra + |extras? + |dependency_groups )\b """, re.VERBOSE, diff --git a/src/packaging/markers.py b/src/packaging/markers.py index fb7f49cf8..e7cea5729 100644 --- a/src/packaging/markers.py +++ b/src/packaging/markers.py @@ -8,7 +8,7 @@ import os import platform import sys -from typing import Any, Callable, TypedDict, cast +from typing import AbstractSet, Any, Callable, Literal, TypedDict, Union, cast from ._parser import MarkerAtom, MarkerList, Op, Value, Variable from ._parser import parse_marker as _parse_marker @@ -17,6 +17,7 @@ from .utils import canonicalize_name __all__ = [ + "EvaluateContext", "InvalidMarker", "Marker", "UndefinedComparison", @@ -24,7 +25,9 @@ "default_environment", ] -Operator = Callable[[str, str], bool] +Operator = Callable[[str, Union[str, AbstractSet[str]]], bool] +EvaluateContext = Literal["metadata", "lock_file", "requirement"] +MARKERS_ALLOWING_SET = {"extras", "dependency_groups"} class InvalidMarker(ValueError): @@ -174,13 +177,14 @@ def _format_marker( } -def _eval_op(lhs: str, op: Op, rhs: str) -> bool: - try: - spec = Specifier("".join([op.serialize(), rhs])) - except InvalidSpecifier: - pass - else: - return spec.contains(lhs, prereleases=True) +def _eval_op(lhs: str, op: Op, rhs: str | AbstractSet[str]) -> bool: + if isinstance(rhs, str): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs, prereleases=True) oper: Operator | None = _operators.get(op.serialize()) if oper is None: @@ -189,19 +193,29 @@ def _eval_op(lhs: str, op: Op, rhs: str) -> bool: return oper(lhs, rhs) -def _normalize(*values: str, key: str) -> tuple[str, ...]: +def _normalize( + lhs: str, rhs: str | AbstractSet[str], key: str +) -> tuple[str, str | AbstractSet[str]]: # PEP 685 – Comparison of extra names for optional distribution dependencies # https://peps.python.org/pep-0685/ # > When comparing extra names, tools MUST normalize the names being # > compared using the semantics outlined in PEP 503 for names if key == "extra": - return tuple(canonicalize_name(v) for v in values) + assert isinstance(rhs, str), "extra value must be a string" + return (canonicalize_name(lhs), canonicalize_name(rhs)) + if key in MARKERS_ALLOWING_SET: + if isinstance(rhs, str): # pragma: no cover + return (canonicalize_name(lhs), canonicalize_name(rhs)) + else: + return (canonicalize_name(lhs), {canonicalize_name(v) for v in rhs}) # other environment markers don't have such standards - return values + return lhs, rhs -def _evaluate_markers(markers: MarkerList, environment: dict[str, str]) -> bool: +def _evaluate_markers( + markers: MarkerList, environment: dict[str, str | AbstractSet[str]] +) -> bool: groups: list[list[bool]] = [[]] for marker in markers: @@ -220,7 +234,7 @@ def _evaluate_markers(markers: MarkerList, environment: dict[str, str]) -> bool: lhs_value = lhs.value environment_key = rhs.value rhs_value = environment[environment_key] - + assert isinstance(lhs_value, str), "lhs must be a string" lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) groups[-1].append(_eval_op(lhs_value, op, rhs_value)) else: @@ -298,22 +312,36 @@ def __eq__(self, other: Any) -> bool: return str(self) == str(other) - def evaluate(self, environment: dict[str, str] | None = None) -> bool: + def evaluate( + self, + environment: dict[str, str] | None = None, + context: EvaluateContext = "metadata", + ) -> bool: """Evaluate a marker. Return the boolean from evaluating the given marker against the environment. environment is an optional argument to override all or - part of the determined environment. + part of the determined environment. The *context* parameter specifies what + context the markers are being evaluated for, which influences what markers + are considered valid. Acceptable values are "metadata" (for core metadata; + default), "lock_file", and "requirement" (i.e. all other situations). The environment is determined from the current Python process. """ - current_environment = cast("dict[str, str]", default_environment()) - current_environment["extra"] = "" + current_environment = cast( + "dict[str, str | AbstractSet[str]]", default_environment() + ) + if context == "lock_file": + current_environment.update( + extras=frozenset(), dependency_groups=frozenset() + ) + elif context == "metadata": + current_environment["extra"] = "" if environment is not None: current_environment.update(environment) # The API used to allow setting extra to None. We need to handle this # case for backwards compatibility. - if current_environment["extra"] is None: + if "extra" in current_environment and current_environment["extra"] is None: current_environment["extra"] = "" return _evaluate_markers( @@ -321,11 +349,14 @@ def evaluate(self, environment: dict[str, str] | None = None) -> bool: ) -def _repair_python_full_version(env: dict[str, str]) -> dict[str, str]: +def _repair_python_full_version( + env: dict[str, str | AbstractSet[str]], +) -> dict[str, str | AbstractSet[str]]: """ Work around platform.python_version() returning something that is not PEP 440 compliant for non-tagged Python builds. """ - if env["python_full_version"].endswith("+"): - env["python_full_version"] += "local" + python_full_version = cast(str, env["python_full_version"]) + if python_full_version.endswith("+"): + env["python_full_version"] = f"{python_full_version}local" return env diff --git a/tests/test_markers.py b/tests/test_markers.py index faf0d13b9..5106427db 100644 --- a/tests/test_markers.py +++ b/tests/test_markers.py @@ -394,3 +394,35 @@ def test_python_full_version_untagged_user_provided(self): def test_python_full_version_untagged(self): with mock.patch("platform.python_version", return_value="3.11.1+"): assert Marker("python_full_version < '3.12'").evaluate() + + @pytest.mark.parametrize("variable", ["extras", "dependency_groups"]) + @pytest.mark.parametrize( + "expression,result", + [ + pytest.param('"foo" in {0}', True, id="value-in-foo"), + pytest.param('"bar" in {0}', True, id="value-in-bar"), + pytest.param('"baz" in {0}', False, id="value-not-in"), + pytest.param('"baz" not in {0}', True, id="value-not-in-negated"), + pytest.param('"foo" in {0} and "bar" in {0}', True, id="and-in"), + pytest.param('"foo" in {0} or "bar" in {0}', True, id="or-in"), + pytest.param( + '"baz" in {0} and "foo" in {0}', False, id="short-circuit-and" + ), + pytest.param('"foo" in {0} or "baz" in {0}', True, id="short-circuit-or"), + pytest.param('"Foo" in {0}', True, id="case-sensitive"), + ], + ) + def test_extras_and_dependency_groups(self, variable, expression, result): + environment = {variable: {"foo", "bar"}} + assert Marker(expression.format(variable)).evaluate(environment) == result + + @pytest.mark.parametrize("variable", ["extras", "dependency_groups"]) + def test_extras_and_dependency_groups_disallowed(self, variable): + marker = Marker(f'"foo" in {variable}') + assert not marker.evaluate(context="lock_file") + + with pytest.raises(KeyError): + marker.evaluate() + + with pytest.raises(KeyError): + marker.evaluate(context="requirement") From 600ecea15b2388037b8dc94883504ca612947576 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sat, 19 Apr 2025 12:48:08 +0100 Subject: [PATCH 10/11] Add changelog entries --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8c4a55794..10e2ad4d3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ Changelog ~~~~~~~~~~~~ * PEP 751: Add support for ``extras`` and ``dependency_groups`` markers. (:issue:`885`) +* PEP 738: Add support for Android platform tags. (:issue:`880`) 24.2 - 2024-11-08 ~~~~~~~~~~~~~~~~~ From f58537628042c7f29780b9d33f31597e7fc9d664 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Sat, 19 Apr 2025 12:48:36 +0100 Subject: [PATCH 11/11] Bump for release --- CHANGELOG.rst | 4 ++-- src/packaging/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 10e2ad4d3..ed3cbe208 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog --------- -*unreleased* -~~~~~~~~~~~~ +25.0 - 2025-04-19 +~~~~~~~~~~~~~~~~~ * PEP 751: Add support for ``extras`` and ``dependency_groups`` markers. (:issue:`885`) * PEP 738: Add support for Android platform tags. (:issue:`880`) diff --git a/src/packaging/__init__.py b/src/packaging/__init__.py index 6d3981569..d45c22cfd 100644 --- a/src/packaging/__init__.py +++ b/src/packaging/__init__.py @@ -6,7 +6,7 @@ __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "24.3.dev0" +__version__ = "25.0" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io"