Add mypy type check for uv-python scripts (#5332)

## Summary

Per https://github.com/astral-sh/uv/pull/4853#issuecomment-2212505407

> If we're going to aim for full type coverage, we should probably
follow this by adding type checking in CI too otherwise it seems too
easy for it to become out of date.
This commit is contained in:
Jo 2024-07-23 22:14:05 +08:00 committed by GitHub
parent 025f2f3162
commit 43084249ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 17 deletions

View file

@ -59,14 +59,27 @@ jobs:
- name: "Prettier" - name: "Prettier"
run: npx prettier --check "**/*.{json5,yaml,yml}" run: npx prettier --check "**/*.{json5,yaml,yml}"
- name: "README check"
run: python scripts/transform_readme.py --target pypi
python-lint:
name: "Python lint"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.12
- name: "Ruff format" - name: "Ruff format"
run: pipx run ruff format --diff . run: pipx run ruff format --diff .
- name: "Ruff check" - name: "Ruff check"
run: pipx run ruff check . run: pipx run ruff check .
- name: "README check" - name: "Mypy check"
run: python scripts/transform_readme.py --target pypi run: pipx run --python 3.12 mypy
cargo-clippy: cargo-clippy:
needs: determine_changes needs: determine_changes

View file

@ -78,7 +78,7 @@ class ImplementationName(StrEnum):
class PythonDownload: class PythonDownload:
version: Version version: Version
triple: PlatformTriple triple: PlatformTriple
flavor: str | None flavor: str
implementation: ImplementationName implementation: ImplementationName
filename: str filename: str
url: str url: str
@ -185,7 +185,7 @@ class CPythonFinder(Finder):
# Collapse CPython variants to a single URL flavor per triple # Collapse CPython variants to a single URL flavor per triple
downloads = [] downloads = []
for choices in results.values(): for choices in results.values():
flavors = {} flavors: dict[PlatformTriple, tuple[PythonDownload, int]] = {}
for choice in choices: for choice in choices:
priority = self._get_flavor_priority(choice.flavor) priority = self._get_flavor_priority(choice.flavor)
existing = flavors.get(choice.triple) existing = flavors.get(choice.triple)
@ -250,12 +250,12 @@ class CPythonFinder(Finder):
# Ex) # Ex)
# https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1%2B20240107-aarch64-unknown-linux-gnu-lto-full.tar.zst # https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1%2B20240107-aarch64-unknown-linux-gnu-lto-full.tar.zst
if url.endswith(".sha256"): if url.endswith(".sha256"):
return return None
filename = unquote(url.rsplit("/", maxsplit=1)[-1]) filename = unquote(url.rsplit("/", maxsplit=1)[-1])
match = self._filename_re.match(filename) match = self._filename_re.match(filename)
if match is None: if match is None:
return return None
version, triple = match.groups() version, triple = match.groups()
if triple.endswith("-full"): if triple.endswith("-full"):
@ -265,14 +265,14 @@ class CPythonFinder(Finder):
if match is not None: if match is not None:
triple, flavor = match.groups() triple, flavor = match.groups()
else: else:
flavor = None flavor = ""
if flavor in self.HIDDEN_FLAVORS: if flavor in self.HIDDEN_FLAVORS:
return return None
version = Version.from_str(version) version = Version.from_str(version)
triple = self._normalize_triple(triple) triple = self._normalize_triple(triple)
if triple is None: if triple is None:
return return None
return PythonDownload( return PythonDownload(
version=version, version=version,
@ -286,7 +286,7 @@ class CPythonFinder(Finder):
def _normalize_triple(self, triple: str) -> PlatformTriple | None: def _normalize_triple(self, triple: str) -> PlatformTriple | None:
if "-static" in triple: if "-static" in triple:
logging.debug("Skipping %r: static unsupported", triple) logging.debug("Skipping %r: static unsupported", triple)
return return None
triple = self.SPECIAL_TRIPLES.get(triple, triple) triple = self.SPECIAL_TRIPLES.get(triple, triple)
pieces = triple.split("-") pieces = triple.split("-")
@ -300,7 +300,7 @@ class CPythonFinder(Finder):
libc = "none" libc = "none"
except IndexError: except IndexError:
logging.debug("Skipping %r: unknown triple", triple) logging.debug("Skipping %r: unknown triple", triple)
return return None
return PlatformTriple(arch, operating_system, libc) return PlatformTriple(arch, operating_system, libc)
@ -313,7 +313,7 @@ class CPythonFinder(Finder):
def _normalize_os(self, os: str) -> str: def _normalize_os(self, os: str) -> str:
return os return os
def _get_flavor_priority(self, flavor: str | None) -> int: def _get_flavor_priority(self, flavor: str) -> int:
"""Returns the priority of a flavor. Lower is better.""" """Returns the priority of a flavor. Lower is better."""
try: try:
pref = self.FLAVOR_PREFERENCES.index(flavor) pref = self.FLAVOR_PREFERENCES.index(flavor)
@ -385,7 +385,7 @@ async def find() -> None:
render(downloads) render(downloads)
def main(): def main() -> None:
parser = argparse.ArgumentParser(description="Fetch Python version metadata.") parser = argparse.ArgumentParser(description="Fetch Python version metadata.")
parser.add_argument( parser.add_argument(
"-v", "-v",

View file

@ -14,12 +14,13 @@ Usage:
uv run --isolated -- crates/uv-python/template-download-metadata.py uv run --isolated -- crates/uv-python/template-download-metadata.py
""" """
import sys
import logging
import argparse import argparse
import json import json
import logging
import subprocess import subprocess
import sys
from pathlib import Path from pathlib import Path
from typing import Any
import chevron_blue import chevron_blue
@ -66,10 +67,10 @@ def prepare_value(value: dict) -> dict:
return value return value
def main(): def main() -> None:
debug = logging.getLogger().getEffectiveLevel() <= logging.DEBUG debug = logging.getLogger().getEffectiveLevel() <= logging.DEBUG
data = {} data: dict[str, Any] = {}
data["generated_with"] = Path(__file__).relative_to(WORKSPACE_ROOT).as_posix() data["generated_with"] = Path(__file__).relative_to(WORKSPACE_ROOT).as_posix()
data["generated_from"] = TEMPLATE.relative_to(WORKSPACE_ROOT).as_posix() data["generated_from"] = TEMPLATE.relative_to(WORKSPACE_ROOT).as_posix()
data["versions"] = [ data["versions"] = [

View file

@ -72,3 +72,7 @@ version_files = [
[tool.uv] [tool.uv]
managed = false managed = false
[tool.mypy]
ignore_missing_imports = true
files = "crates/uv-python/*.py"