Allow creating venv with free-threaded python builds (#7431)

<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

closes #4828

First iteration for an implementation. I need to add more tests but
wanted your opinion on the implementation first.

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
Currently tested using the following command but will add tests shortly:

```console
D:\repo\uv> cargo run venv -p 3.13t && .venv\Scripts\python.exe
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.52s
     Running `target\debug\uv.exe venv -p 3.13t`
Using Python 3.13.0rc1 interpreter at: C:\Users\bschoen\AppData\Local\Programs\Python\Python313\python3.13t.exe
Creating virtualenv at: .venv
Activate with: .venv\Scripts\activate
Python 3.13.0rc1 experimental free-threading build (tags/v3.13.0rc1:e4a3e78, Jul 31 2024, 21:06:58) [MSC v.1940 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
Bas Schoenmaeckers 2024-09-24 00:36:16 +02:00 committed by GitHub
parent 0dea932d83
commit 77c2496f47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 423 additions and 152 deletions

View file

@ -481,19 +481,20 @@ impl WindowsExecutable {
}
/// The name of the launcher shim.
fn launcher(self) -> &'static str {
fn launcher(self, interpreter: &Interpreter) -> &'static str {
match self {
WindowsExecutable::Python => "venvlauncher.exe",
WindowsExecutable::PythonMajor => "venvlauncher.exe",
WindowsExecutable::PythonMajorMinor => "venvlauncher.exe",
WindowsExecutable::Pythonw => "venvwlauncher.exe",
Self::Python | Self::PythonMajor | Self::PythonMajorMinor
if interpreter.gil_disabled() =>
{
"venvlaunchert.exe"
}
Self::Python | Self::PythonMajor | Self::PythonMajorMinor => "venvlauncher.exe",
Self::Pythonw if interpreter.gil_disabled() => "venvwlaunchert.exe",
Self::Pythonw => "venvwlauncher.exe",
// From 3.13 on these should replace the `python.exe` and `pythonw.exe` shims.
// These are not relevant as of now for PyPy as it doesn't yet support Python 3.13.
WindowsExecutable::PyPy => "venvlauncher.exe",
WindowsExecutable::PyPyMajor => "venvlauncher.exe",
WindowsExecutable::PyPyMajorMinor => "venvlauncher.exe",
WindowsExecutable::PyPyw => "venvwlauncher.exe",
WindowsExecutable::PyPyMajorMinorw => "venvwlauncher.exe",
Self::PyPy | Self::PyPyMajor | Self::PyPyMajorMinor => "venvlauncher.exe",
Self::PyPyw | Self::PyPyMajorMinorw => "venvwlauncher.exe",
WindowsExecutable::GraalPy => "venvlauncher.exe",
}
}
@ -534,7 +535,7 @@ fn copy_launcher_windows(
.join("venv")
.join("scripts")
.join("nt")
.join(executable.launcher());
.join(executable.launcher(interpreter));
match fs_err::copy(shim, scripts.join(executable.exe(interpreter))) {
Ok(_) => return Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound => {}
@ -545,7 +546,7 @@ fn copy_launcher_windows(
// Third priority: on Conda at least, we can look for the launcher shim next to
// the Python executable itself.
let shim = base_python.with_file_name(executable.launcher());
let shim = base_python.with_file_name(executable.launcher(interpreter));
match fs_err::copy(shim, scripts.join(executable.exe(interpreter))) {
Ok(_) => return Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound => {}