From 4be275dcb5399983d4cc7766893728104941cc3e Mon Sep 17 00:00:00 2001 From: konstin Date: Wed, 29 Oct 2025 11:15:16 +0100 Subject: [PATCH] Ban macOS 11+ minor tags not supported by pip, packaging nor uv See https://github.com/pypa/packaging.python.org/issues/1933 When macOS switched to a versioning scheme incrementing the major version with macOS 11, packaging and subsequently pip and uv decided to only emit tags with the minor version 0 for macOS 11+ (since we don't know how many minors each version has). PyPI doesn't currently enforce this requirement, to the confusion of users who upload wheels that are ultimately not usuable (https://github.com/astral-sh/uv/issues/16337). This PR bans uploads of those wheels, enforcing a minor version of 0 for macOS 11+. Matching implementations in pip and uv: https://github.com/pypa/packaging/blob/a85e63daecba56bbb829492624a844d306053504/src/packaging/tags.py#L452-L460 https://github.com/astral-sh/uv/blob/64bcd4e8a6ad629fa9ffc2922b4cc0cd57cb8dbe/crates/uv-platform-tags/src/tags.rs#L528-L538 (Pending DPO thread) --- tests/unit/forklift/test_legacy.py | 3 ++- warehouse/forklift/legacy.py | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/unit/forklift/test_legacy.py b/tests/unit/forklift/test_legacy.py index 08f56f94c4d4..9eb90bdab965 100644 --- a/tests/unit/forklift/test_legacy.py +++ b/tests/unit/forklift/test_legacy.py @@ -2843,7 +2843,7 @@ def test_upload_attestation_fails_without_oidc_publisher( "macosx_10_13_x86_64", "macosx_11_0_x86_64", "macosx_10_15_arm64", - "macosx_11_10_universal2", + "macosx_15_0_universal2", "ios_13_0_arm64_iphoneos", "ios_13_0_arm64_iphonesimulator", "ios_13_0_x86_64_iphonesimulator", @@ -3408,6 +3408,7 @@ def test_upload_fails_with_invalid_filename( "linux_x86_64", "linux_x86_64.win32", "macosx_9_2_x86_64", + "macosx_11_2_arm64", "macosx_16_2_arm64", "macosx_10_15_amd64", ], diff --git a/warehouse/forklift/legacy.py b/warehouse/forklift/legacy.py index a21ccab42195..9f33e6226a6b 100644 --- a/warehouse/forklift/legacy.py +++ b/warehouse/forklift/legacy.py @@ -119,7 +119,7 @@ "linux_armv7l", } # macosx is a little more complicated: -_macosx_platform_re = re.compile(r"macosx_(?P\d+)_(\d+)_(?P.*)") +_macosx_platform_re = re.compile(r"macosx_(?P\d+)_(?P\d+)_(?P.*)") _macosx_arches = { "ppc", "ppc64", @@ -133,8 +133,8 @@ "universal", "universal2", } +# macosx 10 is also supported, but with different rules _macosx_major_versions = { - "10", "11", "12", "13", @@ -178,9 +178,17 @@ def _valid_platform_tag(platform_tag): if platform_tag in _allowed_platforms: return True m = _macosx_platform_re.match(platform_tag) + # https://github.com/pypa/packaging.python.org/issues/1933 + # There's two macosx formats: `macosx_10_{minor}` for the 10.x series where + # only the minor version ever increased, and `macosx_{major}_0` for the + # new release scheme where we don't know how many minor versions each + # release has. + if m and m.group("major") == "10" and m.group("arch") in _macosx_arches: + return True if ( m and m.group("major") in _macosx_major_versions + and m.group("minor") == "0" and m.group("arch") in _macosx_arches ): return True