Skip to content

Commit

Permalink
fix: support free-threaded python and latest pbs-installer (#3201)
Browse files Browse the repository at this point in the history
* fix: support free-threaded python and latest pbs-installer

Signed-off-by: Frost Ming <[email protected]>

* add news and docs

Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming authored Oct 10, 2024
1 parent 99ecaa2 commit c8782c8
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
6 changes: 6 additions & 0 deletions docs/usage/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ Remove an installed Python interpreter:
pdm python remove 3.9.8
```

Install a free-threaded Python interpreter:

```bash
pdm python install 3.13t
```

!!! TIP "Share installations with Rye"

PDM installs Python interpreters using the same source as [Rye](https://rye-up.com). If you are using Rye at the same time, you can point the `python.install_root` to the same directory as Rye to share the Python interpreters:
Expand Down
1 change: 1 addition & 0 deletions news/3201.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support installing free-threaded Python interpreters with the `t` suffix.
18 changes: 12 additions & 6 deletions src/pdm/cli/commands/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,20 +135,26 @@ def install_python(project: Project, request: str) -> PythonInfo:
arch = "x86" if arch == "32" else (arch or THIS_ARCH)

ver, python_file = get_download_link(version, implementation=implementation, arch=arch, build_dir=False)
with ui.open_spinner(f"Downloading [success]{ver}[/]") as spinner:
destination = root / str(ver)
interpreter = destination / "bin" / "python3" if sys.platform != "win32" else destination / "python.exe"
logger.debug("Installing %s to %s", ver, destination)
ver_str = f'{ver}{"t" if request.endswith("t") else ""}'
with ui.open_spinner(f"Downloading [success]{ver_str}[/]") as spinner:
destination = root / ver_str
logger.debug("Installing %s to %s", ver_str, destination)
env = BareEnvironment(project)
install_root = destination
if install_root.joinpath("install").exists():
install_root = install_root.joinpath("install")
interpreter = install_root / "bin" / "python3" if sys.platform != "win32" else destination / "python.exe"
if not destination.exists() or not interpreter.exists():
shutil.rmtree(destination, ignore_errors=True)
destination.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile() as tf:
tf.close()
original_filename = download(python_file, tf.name, env.session)
spinner.update(f"Installing [success]{ver}[/]")
spinner.update(f"Installing [success]{ver_str}[/]")
install_file(tf.name, destination, original_filename)

if destination.joinpath("install").exists():
install_root = destination.joinpath("install")
interpreter = install_root / "bin" / "python3" if sys.platform != "win32" else install_root / "python.exe"
if not interpreter.exists():
raise InstallationError("Installation failed, please try again.")

Expand Down
2 changes: 1 addition & 1 deletion src/pdm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ def get_all_installable_python_versions(build_dir: bool = False) -> list[PythonV
from pbs_installer._versions import PYTHON_VERSIONS

arch = "x86" if THIS_ARCH == "32" else THIS_ARCH
matches = [v for v, u in PYTHON_VERSIONS.items() if u.get((THIS_PLATFORM, arch, not build_dir))]
matches = [v for v, u in PYTHON_VERSIONS.items() if any(k[:2] == (THIS_PLATFORM, arch) for k in u)]
return matches


Expand Down

0 comments on commit c8782c8

Please sign in to comment.