Add support for managed installs of free-threaded Python (#8100)

Closes https://github.com/astral-sh/uv/issues/7193

```

❯ cargo run -q -- python uninstall 3.13t
Searching for Python versions matching: Python 3.13t
Uninstalled Python 3.13.0 in 231ms
 - cpython-3.13.0+freethreaded-macos-aarch64-none
❯ cargo run -q -- python install 3.13t
Searching for Python versions matching: Python 3.13t
Installed Python 3.13.0 in 3.54s
 + cpython-3.13.0+freethreaded-macos-aarch64-none
❯ cargo run -q -- python install 3.12t
Searching for Python versions matching: Python 3.12t
error: No download found for request: cpython-3.12t-macos-aarch64-none
❯ cargo run -q -- python install 3.13rc3t
Searching for Python versions matching: Python 3.13rc3t
Found existing installation for Python 3.13rc3t: cpython-3.13.0+freethreaded-macos-aarch64-none
❯ cargo run -q -- run -p 3.13t python -c "import sys; print(sys.base_prefix)"
/Users/zb/.local/share/uv/python/cpython-3.13.0+freethreaded-macos-aarch64-none
```
This commit is contained in:
Zanie Blue 2024-10-14 15:18:52 -05:00 committed by GitHub
parent db0f0aec09
commit 5f33915e03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 6319 additions and 4211 deletions

View file

@ -50,6 +50,18 @@ def prepare_libc(libc: str) -> str | None:
return libc.title()
def prepare_variant(variant: str | None) -> str | None:
match variant:
case None:
return "PythonVariant::Default"
case "freethreaded":
return "PythonVariant::Freethreaded"
case "debug":
return "PythonVariant::Debug"
case _:
raise ValueError(f"Unknown variant: {variant}")
def prepare_arch(arch: str) -> str:
match arch:
# Special constructors
@ -78,6 +90,7 @@ def prepare_value(value: dict) -> dict:
value["name"] = prepare_name(value["name"])
value["libc"] = prepare_libc(value["libc"])
value["prerelease"] = prepare_prerelease(value["prerelease"])
value["variant"] = prepare_variant(value["variant"])
return value
@ -90,6 +103,8 @@ def main() -> None:
data["versions"] = [
{"key": key, "value": prepare_value(value)}
for key, value in json.loads(VERSION_METADATA.read_text()).items()
# Exclude debug variants for now, we don't support them in the Rust side
if value["variant"] != "debug"
]
# Render the template
@ -100,7 +115,7 @@ def main() -> None:
# Update the file
logging.info(f"Updating `{TARGET}`...")
TARGET.write_text(output)
TARGET.write_text("// DO NOT EDIT\n//\n" + output)
subprocess.check_call(
["rustfmt", str(TARGET)],
stderr=subprocess.STDOUT,