Refactor Toolchain API to always take ToolchainRequest instead of str (#4341)

This API was taking an `Option<&str>` for caller convenience in some
places but we ought to just take a `ToolchainRequest` consistently.
This commit is contained in:
Zanie Blue 2024-06-17 12:16:15 -04:00 committed by GitHub
parent 67f1285ce3
commit b5d280dc40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 78 additions and 56 deletions

View file

@ -1205,7 +1205,7 @@ mod tests {
let toolchain =
context.run_with_vars(&[("VIRTUAL_ENV", Some(venv.as_os_str()))], || {
Toolchain::find(
Some("3.12"),
Some(ToolchainRequest::parse("3.12")),
SystemPython::Required,
PreviewMode::Disabled,
&context.cache,
@ -1220,7 +1220,7 @@ mod tests {
// With a patch version that cannot be toolchain
let result = context.run_with_vars(&[("VIRTUAL_ENV", Some(venv.as_os_str()))], || {
Toolchain::find(
Some("3.12.3"),
Some(ToolchainRequest::parse("3.12.3")),
SystemPython::Required,
PreviewMode::Disabled,
&context.cache,
@ -1263,7 +1263,7 @@ mod tests {
&[("VIRTUAL_ENV", Some(context.tempdir.as_os_str()))],
|| {
Toolchain::find(
Some("3.12.3"),
Some(ToolchainRequest::parse("3.12.3")),
SystemPython::Required,
PreviewMode::Disabled,
&context.cache,
@ -1290,7 +1290,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("foobar"),
Some(ToolchainRequest::parse("foobar")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1317,7 +1317,7 @@ mod tests {
let result = context.run(|| {
Toolchain::find(
Some("3.10.0"),
Some(ToolchainRequest::parse("3.10.0")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1344,7 +1344,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("./foo/bar"),
Some(ToolchainRequest::parse("./foo/bar")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1359,7 +1359,7 @@ mod tests {
context.add_python_versions(&["3.11.1"])?;
let toolchain = context.run(|| {
Toolchain::find(
Some("./foo/bar"),
Some(ToolchainRequest::parse("./foo/bar")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1387,7 +1387,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some(python.to_str().unwrap()),
Some(ToolchainRequest::parse(python.to_str().unwrap())),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1402,7 +1402,7 @@ mod tests {
// With `SystemPython::Explicit
let toolchain = context.run(|| {
Toolchain::find(
Some(python.to_str().unwrap()),
Some(ToolchainRequest::parse(python.to_str().unwrap())),
SystemPython::Explicit,
PreviewMode::Disabled,
&context.cache,
@ -1416,7 +1416,7 @@ mod tests {
let result = context.run(|| {
Toolchain::find(
Some(python.to_str().unwrap()),
Some(ToolchainRequest::parse(python.to_str().unwrap())),
SystemPython::Disallowed,
PreviewMode::Disabled,
&context.cache,
@ -1436,7 +1436,7 @@ mod tests {
context.add_python_versions(&["3.11.1"])?;
let toolchain = context.run(|| {
Toolchain::find(
Some(python.to_str().unwrap()),
Some(ToolchainRequest::parse(python.to_str().unwrap())),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1459,7 +1459,7 @@ mod tests {
TestContext::mock_venv(&venv, "3.10.0")?;
let toolchain = context.run(|| {
Toolchain::find(
Some("../foo/.venv"),
Some(ToolchainRequest::parse("../foo/.venv")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1473,7 +1473,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some(venv.to_str().unwrap()),
Some(ToolchainRequest::parse(venv.to_str().unwrap())),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1495,7 +1495,9 @@ mod tests {
)?;
let toolchain = context.run(|| {
Toolchain::find(
Some(context.tempdir.child("bar").to_str().unwrap()),
Some(ToolchainRequest::parse(
context.tempdir.child("bar").to_str().unwrap(),
)),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1513,7 +1515,7 @@ mod tests {
let toolchain =
context.run_with_vars(&[("VIRTUAL_ENV", Some(other_venv.as_os_str()))], || {
Toolchain::find(
Some(venv.to_str().unwrap()),
Some(ToolchainRequest::parse(venv.to_str().unwrap())),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1535,7 +1537,7 @@ mod tests {
let result = context.run(|| {
Toolchain::find(
Some("./foo/bar"),
Some(ToolchainRequest::parse("./foo/bar")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1567,7 +1569,7 @@ mod tests {
let toolchain = context
.run(|| {
Toolchain::find(
Some("bar"),
Some(ToolchainRequest::parse("bar")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1623,7 +1625,7 @@ mod tests {
let toolchain = context
.run(|| {
Toolchain::find(
Some("pypy"),
Some(ToolchainRequest::parse("pypy")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1650,7 +1652,7 @@ mod tests {
let toolchain = context
.run(|| {
Toolchain::find(
Some("pypy"),
Some(ToolchainRequest::parse("pypy")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1692,7 +1694,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy3.10"),
Some(ToolchainRequest::parse("pypy3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1718,7 +1720,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy@3.10"),
Some(ToolchainRequest::parse("pypy@3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1755,7 +1757,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy@3.10"),
Some(ToolchainRequest::parse("pypy@3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1774,7 +1776,7 @@ mod tests {
])?;
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy@3.10"),
Some(ToolchainRequest::parse("pypy@3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1807,7 +1809,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy@3.10"),
Some(ToolchainRequest::parse("pypy@3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,
@ -1836,7 +1838,7 @@ mod tests {
let toolchain = context.run(|| {
Toolchain::find(
Some("pypy@3.10"),
Some(ToolchainRequest::parse("pypy@3.10")),
SystemPython::Allowed,
PreviewMode::Disabled,
&context.cache,

View file

@ -39,13 +39,12 @@ impl Toolchain {
///
/// See [`uv-toolchain::discovery`] for implementation details.
pub fn find(
python: Option<&str>,
python: Option<ToolchainRequest>,
system: SystemPython,
preview: PreviewMode,
cache: &Cache,
) -> Result<Self, Error> {
if let Some(python) = python {
let request = ToolchainRequest::parse(python);
if let Some(request) = python {
Self::find_requested(&request, system, preview, cache)
} else if system.is_preferred() {
Self::find_default(preview, cache)
@ -134,19 +133,19 @@ impl Toolchain {
///
/// Unlike [`Toolchain::find`], if the toolchain is not installed it will be installed automatically.
pub async fn find_or_fetch<'a>(
python: Option<&str>,
python: Option<ToolchainRequest>,
system: SystemPython,
preview: PreviewMode,
client_builder: BaseClientBuilder<'a>,
cache: &Cache,
) -> Result<Self, Error> {
// Perform a find first
match Self::find(python, system, preview, cache) {
match Self::find(python.clone(), system, preview, cache) {
Ok(venv) => Ok(venv),
Err(Error::NotFound(_)) if system.is_allowed() && preview.is_enabled() => {
debug!("Requested Python not found, checking for available download...");
let request = if let Some(request) = python {
ToolchainRequest::parse(request)
request
} else {
ToolchainRequest::default()
};

View file

@ -10,7 +10,7 @@ use uv_cache::Cache;
use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_installer::{SitePackages, SitePackagesDiagnostic};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain, ToolchainRequest};
use crate::commands::{elapsed, ExitStatus};
use crate::printer::Printer;
@ -31,8 +31,12 @@ pub(crate) fn pip_check(
} else {
SystemPython::Allowed
};
let environment =
PythonEnvironment::from_toolchain(Toolchain::find(python, system, preview, cache)?);
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.map(ToolchainRequest::parse),
system,
preview,
cache,
)?);
debug!(
"Using Python {} environment at {}",

View file

@ -10,7 +10,7 @@ use uv_cache::Cache;
use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_installer::SitePackages;
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain, ToolchainRequest};
use crate::commands::ExitStatus;
use crate::printer::Printer;
@ -31,8 +31,12 @@ pub(crate) fn pip_freeze(
} else {
SystemPython::Allowed
};
let environment =
PythonEnvironment::from_toolchain(Toolchain::find(python, system, preview, cache)?);
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.map(ToolchainRequest::parse),
system,
preview,
cache,
)?);
debug!(
"Using Python {} environment at {}",

View file

@ -25,7 +25,9 @@ use uv_resolver::{
DependencyMode, ExcludeNewer, FlatIndex, InMemoryIndex, OptionsBuilder, PreReleaseMode,
ResolutionMode,
};
use uv_toolchain::{Prefix, PythonEnvironment, PythonVersion, SystemPython, Target, Toolchain};
use uv_toolchain::{
Prefix, PythonEnvironment, PythonVersion, SystemPython, Target, Toolchain, ToolchainRequest,
};
use uv_types::{BuildIsolation, HashStrategy, InFlight};
use crate::commands::pip::operations::Modifications;
@ -120,7 +122,7 @@ pub(crate) async fn pip_install(
SystemPython::Explicit
};
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.as_deref(),
python.as_deref().map(ToolchainRequest::parse),
system,
preview,
&cache,

View file

@ -14,8 +14,8 @@ use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_installer::SitePackages;
use uv_normalize::PackageName;
use uv_toolchain::Toolchain;
use uv_toolchain::{PythonEnvironment, SystemPython};
use uv_toolchain::{Toolchain, ToolchainRequest};
use crate::commands::ExitStatus;
use crate::commands::ListFormat;
@ -41,8 +41,12 @@ pub(crate) fn pip_list(
} else {
SystemPython::Allowed
};
let environment =
PythonEnvironment::from_toolchain(Toolchain::find(python, system, preview, cache)?);
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.map(ToolchainRequest::parse),
system,
preview,
cache,
)?);
debug!(
"Using Python {} environment at {}",

View file

@ -12,7 +12,7 @@ use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_installer::SitePackages;
use uv_normalize::PackageName;
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain, ToolchainRequest};
use crate::commands::ExitStatus;
use crate::printer::Printer;
@ -46,8 +46,12 @@ pub(crate) fn pip_show(
} else {
SystemPython::Allowed
};
let environment =
PythonEnvironment::from_toolchain(Toolchain::find(python, system, preview, cache)?);
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.map(ToolchainRequest::parse),
system,
preview,
cache,
)?);
debug!(
"Using Python {} environment at {}",

View file

@ -24,7 +24,9 @@ use uv_resolver::{
DependencyMode, ExcludeNewer, FlatIndex, InMemoryIndex, OptionsBuilder, PreReleaseMode,
ResolutionMode,
};
use uv_toolchain::{Prefix, PythonEnvironment, PythonVersion, SystemPython, Target, Toolchain};
use uv_toolchain::{
Prefix, PythonEnvironment, PythonVersion, SystemPython, Target, Toolchain, ToolchainRequest,
};
use uv_types::{BuildIsolation, HashStrategy, InFlight};
use crate::commands::pip::operations::Modifications;
@ -115,7 +117,7 @@ pub(crate) async fn pip_sync(
SystemPython::Explicit
};
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.as_deref(),
python.as_deref().map(ToolchainRequest::parse),
system,
preview,
&cache,

View file

@ -15,6 +15,7 @@ use uv_configuration::{KeyringProviderType, PreviewMode};
use uv_fs::Simplified;
use uv_requirements::{RequirementsSource, RequirementsSpecification};
use uv_toolchain::Toolchain;
use uv_toolchain::ToolchainRequest;
use uv_toolchain::{Prefix, PythonEnvironment, SystemPython, Target};
use crate::commands::{elapsed, ExitStatus};
@ -52,7 +53,7 @@ pub(crate) async fn pip_uninstall(
SystemPython::Explicit
};
let environment = PythonEnvironment::from_toolchain(Toolchain::find(
python.as_deref(),
python.as_deref().map(ToolchainRequest::parse),
system,
preview,
&cache,

View file

@ -12,7 +12,7 @@ use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode};
use uv_distribution::{ProjectWorkspace, Workspace};
use uv_normalize::PackageName;
use uv_requirements::RequirementsSource;
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain, ToolchainRequest};
use uv_warnings::warn_user;
use crate::commands::{project, ExitStatus};
@ -128,7 +128,7 @@ pub(crate) async fn run(
} else {
// Note we force preview on during `uv run` for now since the entire interface is in preview
Toolchain::find_or_fetch(
python.as_deref(),
python.as_deref().map(ToolchainRequest::parse),
SystemPython::Allowed,
PreviewMode::Enabled,
client_builder,

View file

@ -10,7 +10,7 @@ use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::{Concurrency, PreviewMode};
use uv_requirements::RequirementsSource;
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain};
use uv_toolchain::{PythonEnvironment, SystemPython, Toolchain, ToolchainRequest};
use uv_warnings::warn_user;
use crate::commands::project::update_environment;
@ -55,7 +55,7 @@ pub(crate) async fn run(
// Discover an interpreter.
// Note we force preview on during `uv tool run` for now since the entire interface is in preview
let interpreter = Toolchain::find(
python.as_deref(),
python.as_deref().map(ToolchainRequest::parse),
SystemPython::Allowed,
PreviewMode::Enabled,
cache,

View file

@ -23,7 +23,7 @@ use uv_dispatch::BuildDispatch;
use uv_fs::Simplified;
use uv_git::GitResolver;
use uv_resolver::{ExcludeNewer, FlatIndex, InMemoryIndex, OptionsBuilder};
use uv_toolchain::{SystemPython, Toolchain};
use uv_toolchain::{SystemPython, Toolchain, ToolchainRequest};
use uv_types::{BuildContext, BuildIsolation, HashStrategy, InFlight};
use crate::commands::{pip, ExitStatus};
@ -127,7 +127,7 @@ async fn venv_impl(
// Locate the Python interpreter to use in the environment
let interpreter = Toolchain::find_or_fetch(
python_request,
python_request.map(ToolchainRequest::parse),
SystemPython::Required,
preview,
client_builder,

View file

@ -18,7 +18,7 @@ use uv_configuration::PreviewMode;
use uv_cache::Cache;
use uv_fs::Simplified;
use uv_toolchain::managed::InstalledToolchains;
use uv_toolchain::{PythonVersion, Toolchain};
use uv_toolchain::{PythonVersion, Toolchain, ToolchainRequest};
// Exclude any packages uploaded after this date.
pub static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z";
@ -596,7 +596,7 @@ pub fn python_path_with_versions(
if inner.is_empty() {
// Fallback to a system lookup if we failed to find one in the toolchain directory
if let Ok(toolchain) = Toolchain::find(
Some(python_version),
Some(ToolchainRequest::parse(python_version)),
// Without required, we could pick the current venv here and the test fails
// because the venv subcommand requires a system interpreter.
uv_toolchain::SystemPython::Required,