-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
ci: only require packages from internal pypi if there are no 3.13 wheels upstream #115455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,43 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import argparse | ||
| import json | ||
| import tomllib | ||
| import urllib.request | ||
| from collections.abc import Sequence | ||
|
|
||
| _INTERNAL_PYPI = "https://pypi.devinfra.sentry.io/simple" | ||
|
|
||
|
|
||
| def _has_upstream_cp313_wheels(name: str, version: str) -> bool | None: | ||
| """ | ||
| Returns True if upstream PyPI has satisfactory cp313 wheels for macOS arm64 | ||
| or Linux x86_64 (or a pure-Python wheel that covers all platforms). | ||
| Returns None if the upstream check could not be performed (e.g. no network). | ||
| """ | ||
| url = f"https://pypi.org/pypi/{name}/{version}/json" | ||
| try: | ||
| with urllib.request.urlopen(url, timeout=5) as resp: | ||
| data = json.load(resp) | ||
| except Exception: | ||
| return None | ||
|
|
||
| has_mac = False | ||
| has_linux = False | ||
|
|
||
| for dist in data.get("urls", []): | ||
| if dist.get("packagetype") != "bdist_wheel": | ||
| continue | ||
| fn = dist["filename"] | ||
| if fn.endswith("-none-any.whl"): | ||
| return True | ||
| if "cp313" in fn and "macosx" in fn and "arm64" in fn: | ||
| has_mac = True | ||
| if "cp313" in fn and ("manylinux" in fn or "musllinux" in fn) and "x86_64" in fn: | ||
| has_linux = True | ||
|
|
||
| return has_mac and has_linux | ||
|
|
||
|
|
||
| def main(argv: Sequence[str] | None = None) -> int: | ||
| """ | ||
|
|
@@ -23,20 +57,34 @@ def main(argv: Sequence[str] | None = None) -> int: | |
| continue | ||
|
|
||
| # non-specifier requirements won't have registry as a source | ||
| if ( | ||
| package["source"].get("registry", "") | ||
| != "https://pypi.devinfra.sentry.io/simple" | ||
| package_registry = package["source"].get("registry", "") | ||
|
|
||
| if package_registry not in ( | ||
| "https://pypi.org/simple", | ||
| _INTERNAL_PYPI, | ||
|
joshuarli marked this conversation as resolved.
joshuarli marked this conversation as resolved.
|
||
| ): | ||
| raise SystemExit( | ||
| f""" | ||
| The specifier for package {package["name"]} in {filename} isn't allowed: | ||
|
|
||
| You cannot use dependencies that are not on internal pypi. | ||
|
|
||
| You also cannot use non-specifier requirements. | ||
| Packages must come from pypi.org or the internal Sentry PyPI | ||
| (https://pypi.devinfra.sentry.io/simple) for packages that lack | ||
| suitable upstream wheels. URL/VCS/local dependencies are not allowed. | ||
| See PEP440: https://www.python.org/dev/peps/pep-0440/#direct-references""" | ||
| ) | ||
|
|
||
| if package_registry == _INTERNAL_PYPI: | ||
| version = package.get("version", "") | ||
| has_wheels = _has_upstream_cp313_wheels(package["name"], version) | ||
| if has_wheels: | ||
| raise SystemExit( | ||
| f""" | ||
| Package {package["name"]}=={version} in {filename} is sourced from internal | ||
| PyPI but upstream PyPI already has cp313 wheels for macOS arm64 and/or Linux | ||
|
Comment on lines
+82
to
+83
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: The error message uses "and/or" when describing platform requirements, but the code logic requires "and", potentially misleading developers. Suggested FixUpdate the error message string at lines 82-84 to use "and" instead of "and/or". Similarly, correct the docstring for the Prompt for AI AgentAlso affects:
|
||
| x86_64. Remove it from [tool.uv.sources] and no-build-package in pyproject.toml | ||
| so it is fetched from pypi.org directly.""" | ||
| ) | ||
|
|
||
| return 0 | ||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The PyPI API call in
_has_upstream_cp313_wheelsdoes not canonicalize package names, causing it to fail silently for packages with underscores.Severity: MEDIUM
Suggested Fix
Before constructing the URL, normalize the package
nameaccording to PEP 503 rules. This can be done by replacing underscores, periods, and hyphens with a single hyphen and lowercasing the name. For example:canonical_name = re.sub(r"[-_.]+", "-", name).lower().Prompt for AI Agent