mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-01 14:31:12 +00:00
Remove unnecessary optional from uv run
(#5976)
## Summary This is always `Some` now.
This commit is contained in:
parent
921050d747
commit
dd32087842
1 changed files with 73 additions and 100 deletions
|
@ -187,7 +187,7 @@ pub(crate) async fn run(
|
||||||
// Discover and sync the base environment.
|
// Discover and sync the base environment.
|
||||||
let temp_dir;
|
let temp_dir;
|
||||||
let base_interpreter = if let Some(script_interpreter) = script_interpreter {
|
let base_interpreter = if let Some(script_interpreter) = script_interpreter {
|
||||||
Some(script_interpreter)
|
script_interpreter
|
||||||
} else {
|
} else {
|
||||||
let project = if no_project {
|
let project = if no_project {
|
||||||
None
|
None
|
||||||
|
@ -376,16 +376,14 @@ pub(crate) async fn run(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(interpreter)
|
interpreter
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(base_interpreter) = &base_interpreter {
|
|
||||||
debug!(
|
debug!(
|
||||||
"Using Python {} interpreter at: {}",
|
"Using Python {} interpreter at: {}",
|
||||||
base_interpreter.python_version(),
|
base_interpreter.python_version(),
|
||||||
base_interpreter.sys_executable().display()
|
base_interpreter.sys_executable().display()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Read the requirements.
|
// Read the requirements.
|
||||||
let spec = if requirements.is_empty() {
|
let spec = if requirements.is_empty() {
|
||||||
|
@ -401,85 +399,20 @@ pub(crate) async fn run(
|
||||||
Some(spec)
|
Some(spec)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine whether the base environment satisfies the ephemeral requirements. If we don't have
|
|
||||||
// any `--with` requirements, and we already have a base environment, then there's no need to
|
|
||||||
// create an additional environment.
|
|
||||||
let skip_ephemeral = base_interpreter.as_ref().is_some_and(|base_interpreter| {
|
|
||||||
// No additional requirements.
|
|
||||||
let Some(spec) = spec.as_ref() else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(site_packages) = SitePackages::from_interpreter(base_interpreter) else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if !(settings.reinstall.is_none() && settings.reinstall.is_none()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
match site_packages.satisfies(&spec.requirements, &spec.constraints) {
|
|
||||||
// If the requirements are already satisfied, we're done.
|
|
||||||
Ok(SatisfiesResult::Fresh {
|
|
||||||
recursive_requirements,
|
|
||||||
}) => {
|
|
||||||
debug!(
|
|
||||||
"Base environment satisfies requirements: {}",
|
|
||||||
recursive_requirements
|
|
||||||
.iter()
|
|
||||||
.map(|entry| entry.requirement.to_string())
|
|
||||||
.sorted()
|
|
||||||
.join(" | ")
|
|
||||||
);
|
|
||||||
true
|
|
||||||
}
|
|
||||||
Ok(SatisfiesResult::Unsatisfied(requirement)) => {
|
|
||||||
debug!("At least one requirement is not satisfied in the base environment: {requirement}");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
debug!("Failed to check requirements against base environment: {err}");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If necessary, create an environment for the ephemeral requirements or command.
|
// If necessary, create an environment for the ephemeral requirements or command.
|
||||||
let temp_dir;
|
let temp_dir;
|
||||||
let ephemeral_env = if skip_ephemeral {
|
let ephemeral_env = if can_skip_ephemeral(spec.as_ref(), &base_interpreter, &settings) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
debug!("Creating ephemeral environment");
|
debug!("Creating ephemeral environment");
|
||||||
|
|
||||||
// Discover an interpreter.
|
|
||||||
let interpreter = if let Some(base_interpreter) = &base_interpreter {
|
|
||||||
base_interpreter.clone()
|
|
||||||
} else {
|
|
||||||
let client_builder = BaseClientBuilder::new()
|
|
||||||
.connectivity(connectivity)
|
|
||||||
.native_tls(native_tls);
|
|
||||||
|
|
||||||
// Note we force preview on during `uv run` for now since the entire interface is in preview
|
|
||||||
PythonInstallation::find_or_download(
|
|
||||||
python.as_deref().map(PythonRequest::parse),
|
|
||||||
EnvironmentPreference::Any,
|
|
||||||
python_preference,
|
|
||||||
python_downloads,
|
|
||||||
&client_builder,
|
|
||||||
cache,
|
|
||||||
Some(&download_reporter),
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.into_interpreter()
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(match spec.filter(|spec| !spec.is_empty()) {
|
Some(match spec.filter(|spec| !spec.is_empty()) {
|
||||||
None => {
|
None => {
|
||||||
// Create a virtual environment
|
// Create a virtual environment
|
||||||
temp_dir = cache.environment()?;
|
temp_dir = cache.environment()?;
|
||||||
uv_virtualenv::create_venv(
|
uv_virtualenv::create_venv(
|
||||||
temp_dir.path(),
|
temp_dir.path(),
|
||||||
interpreter,
|
base_interpreter.clone(),
|
||||||
uv_virtualenv::Prompt::None,
|
uv_virtualenv::Prompt::None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -491,7 +424,7 @@ pub(crate) async fn run(
|
||||||
|
|
||||||
CachedEnvironment::get_or_create(
|
CachedEnvironment::get_or_create(
|
||||||
spec,
|
spec,
|
||||||
interpreter,
|
base_interpreter.clone(),
|
||||||
&settings,
|
&settings,
|
||||||
&state,
|
&state,
|
||||||
if show_resolution {
|
if show_resolution {
|
||||||
|
@ -521,7 +454,6 @@ pub(crate) async fn run(
|
||||||
// the base environment's site packages. Setting `PYTHONPATH` is insufficient, as it doesn't
|
// the base environment's site packages. Setting `PYTHONPATH` is insufficient, as it doesn't
|
||||||
// resolve `.pth` files in the base environment.
|
// resolve `.pth` files in the base environment.
|
||||||
if let Some(ephemeral_env) = ephemeral_env.as_ref() {
|
if let Some(ephemeral_env) = ephemeral_env.as_ref() {
|
||||||
if let Some(base_interpreter) = base_interpreter.as_ref() {
|
|
||||||
let ephemeral_site_packages = ephemeral_env
|
let ephemeral_site_packages = ephemeral_env
|
||||||
.site_packages()
|
.site_packages()
|
||||||
.next()
|
.next()
|
||||||
|
@ -539,7 +471,6 @@ pub(crate) async fn run(
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug!("Running `{command}`");
|
debug!("Running `{command}`");
|
||||||
let mut process = Command::from(&command);
|
let mut process = Command::from(&command);
|
||||||
|
@ -550,12 +481,7 @@ pub(crate) async fn run(
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(PythonEnvironment::scripts)
|
.map(PythonEnvironment::scripts)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(
|
.chain(std::iter::once(base_interpreter.scripts()))
|
||||||
base_interpreter
|
|
||||||
.as_ref()
|
|
||||||
.map(Interpreter::scripts)
|
|
||||||
.into_iter(),
|
|
||||||
)
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.chain(
|
.chain(
|
||||||
std::env::var_os("PATH")
|
std::env::var_os("PATH")
|
||||||
|
@ -592,6 +518,53 @@ pub(crate) async fn run(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if we can skip creating an additional ephemeral environment in `uv run`.
|
||||||
|
fn can_skip_ephemeral(
|
||||||
|
spec: Option<&RequirementsSpecification>,
|
||||||
|
base_interpreter: &Interpreter,
|
||||||
|
settings: &ResolverInstallerSettings,
|
||||||
|
) -> bool {
|
||||||
|
// No additional requirements.
|
||||||
|
let Some(spec) = spec.as_ref() else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(site_packages) = SitePackages::from_interpreter(base_interpreter) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !(settings.reinstall.is_none() && settings.reinstall.is_none()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match site_packages.satisfies(&spec.requirements, &spec.constraints) {
|
||||||
|
// If the requirements are already satisfied, we're done.
|
||||||
|
Ok(SatisfiesResult::Fresh {
|
||||||
|
recursive_requirements,
|
||||||
|
}) => {
|
||||||
|
debug!(
|
||||||
|
"Base environment satisfies requirements: {}",
|
||||||
|
recursive_requirements
|
||||||
|
.iter()
|
||||||
|
.map(|entry| entry.requirement.to_string())
|
||||||
|
.sorted()
|
||||||
|
.join(" | ")
|
||||||
|
);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Ok(SatisfiesResult::Unsatisfied(requirement)) => {
|
||||||
|
debug!(
|
||||||
|
"At least one requirement is not satisfied in the base environment: {requirement}"
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
debug!("Failed to check requirements against base environment: {err}");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum RunCommand {
|
enum RunCommand {
|
||||||
/// Execute a `python` script.
|
/// Execute a `python` script.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue