mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 12:09:12 +00:00
Rewrite Python interpreter discovery (#3266)
Updates our Python interpreter discovery to conform to the rules described in #2386, please see that issue for a full description of the behavior. Briefly, we now will search for interpreters that satisfy a requested version without stopping at the first Python executable. Additionally, if retrieving information about an interpreter fails we will continue to search for a working interpreter. We also add the plumbing necessary to request Python implementations other than CPython, though we do not add support for other implementations at this time. A major internal goal of this work is to prepare for user-facing managed toolchains i.e. fetching a requested version during `uv run`. These APIs are not introduced, but there is some managed toolchain handling as required for our test suite. Some noteworthy implementation changes: - The `uv_interpreter::find_python` module has been removed in favor of a `uv_interpreter::discovery` module. - There are new types to help structure interpreter requests and track sources - Executable discovery is implemented as a big lazy iterator and is a central authority for source precedence - `uv_interpreter::Error` variants were split into scoped types in each module - There's much more unit test coverage, but not for Windows yet Remaining work: - [x] Write new test cases - [x] Determine correct behavior around executables in the current directory - _Future_: Combine `PythonVersion` and `VersionRequest` - _Future_: Consider splitting `ManagedToolchain` into local and remote variants - _Future_: Add Windows unit test coverage - _Future_: Explore behavior around implementation precedence (i.e. CPython over PyPy) Refactors split into: - #3329 - #3330 - #3331 - #3332 Closes #2386
This commit is contained in:
parent
c14a7dbef3
commit
d540d0f28b
32 changed files with 3100 additions and 1165 deletions
|
@ -25,11 +25,13 @@ pub(crate) struct FetchPythonArgs {
|
|||
pub(crate) async fn fetch_python(args: FetchPythonArgs) -> Result<()> {
|
||||
let start = Instant::now();
|
||||
|
||||
let bootstrap_dir = TOOLCHAIN_DIRECTORY
|
||||
.as_ref()
|
||||
.expect("The toolchain directory must exist for bootstrapping");
|
||||
let bootstrap_dir = TOOLCHAIN_DIRECTORY.clone().unwrap_or_else(|| {
|
||||
std::env::current_dir()
|
||||
.expect("Use `UV_BOOTSTRAP_DIR` if the current directory is not usable.")
|
||||
.join("bin")
|
||||
});
|
||||
|
||||
fs_err::create_dir_all(bootstrap_dir)?;
|
||||
fs_err::create_dir_all(&bootstrap_dir)?;
|
||||
|
||||
let versions = if args.versions.is_empty() {
|
||||
info!("Reading versions from file...");
|
||||
|
@ -59,7 +61,7 @@ pub(crate) async fn fetch_python(args: FetchPythonArgs) -> Result<()> {
|
|||
let mut tasks = futures::stream::iter(downloads.iter())
|
||||
.map(|download| {
|
||||
async {
|
||||
let result = download.fetch(&client, bootstrap_dir).await;
|
||||
let result = download.fetch(&client, &bootstrap_dir).await;
|
||||
(download.python_version(), result)
|
||||
}
|
||||
.instrument(info_span!("download", key = %download))
|
||||
|
@ -130,6 +132,10 @@ pub(crate) async fn fetch_python(args: FetchPythonArgs) -> Result<()> {
|
|||
};
|
||||
|
||||
info!("Installed {} versions", requests.len());
|
||||
info!(
|
||||
r#"To enable discovery: export UV_BOOTSTRAP_DIR="{}""#,
|
||||
bootstrap_dir.display()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue