mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Use cached environments in PEP 723 execution (#4789)
## Summary This seems like another good candidate for environment caching. If you run a script repeatedly, we can just use the existing cached environment.
This commit is contained in:
parent
892106fef0
commit
6a27135a65
3 changed files with 25 additions and 22 deletions
|
@ -126,4 +126,9 @@ impl CachedEnvironment {
|
|||
|
||||
Ok(Self(venv))
|
||||
}
|
||||
|
||||
/// Convert the [`EphemeralEnvironment`] into an [`Interpreter`].
|
||||
pub(crate) fn into_interpreter(self) -> Interpreter {
|
||||
self.0.into_interpreter()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ use uv_requirements::{RequirementsSource, RequirementsSpecification};
|
|||
use uv_warnings::warn_user_once;
|
||||
|
||||
use crate::commands::pip::operations::Modifications;
|
||||
use crate::commands::project::environment::CachedEnvironment;
|
||||
use crate::commands::{project, ExitStatus, SharedState};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::ResolverInstallerSettings;
|
||||
|
@ -55,19 +56,10 @@ pub(crate) async fn run(
|
|||
let state = SharedState::default();
|
||||
|
||||
// Determine whether the command to execute is a PEP 723 script.
|
||||
let temp_dir;
|
||||
let script_interpreter = if let RunCommand::Python(target, _) = &command {
|
||||
if let Some(metadata) = uv_scripts::read_pep723_metadata(&target).await? {
|
||||
debug!("Found PEP 723 script at: {}", target.display());
|
||||
|
||||
let spec = RequirementsSpecification::from_requirements(
|
||||
metadata
|
||||
.dependencies
|
||||
.into_iter()
|
||||
.map(Requirement::from)
|
||||
.collect(),
|
||||
);
|
||||
|
||||
// (1) Explicit request from user
|
||||
let python_request = if let Some(request) = python.as_deref() {
|
||||
Some(PythonRequest::parse(request))
|
||||
|
@ -96,20 +88,15 @@ pub(crate) async fn run(
|
|||
.await?
|
||||
.into_interpreter();
|
||||
|
||||
// Create a virtual environment
|
||||
temp_dir = cache.environment()?;
|
||||
let venv = uv_virtualenv::create_venv(
|
||||
temp_dir.path(),
|
||||
interpreter,
|
||||
uv_virtualenv::Prompt::None,
|
||||
false,
|
||||
false,
|
||||
)?;
|
||||
|
||||
// Install the script requirements.
|
||||
let environment = project::update_environment(
|
||||
venv,
|
||||
spec,
|
||||
let requirements = metadata
|
||||
.dependencies
|
||||
.into_iter()
|
||||
.map(Requirement::from)
|
||||
.collect();
|
||||
let environment = CachedEnvironment::get_or_create(
|
||||
requirements,
|
||||
interpreter,
|
||||
&settings,
|
||||
&state,
|
||||
preview,
|
||||
|
|
|
@ -223,6 +223,7 @@ fn run_script() -> Result<()> {
|
|||
"#
|
||||
})?;
|
||||
|
||||
// Running the script should install the requirements.
|
||||
uv_snapshot!(context.filters(), context.run().arg("--preview").arg("main.py"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
|
@ -235,6 +236,16 @@ fn run_script() -> Result<()> {
|
|||
+ iniconfig==2.0.0
|
||||
"###);
|
||||
|
||||
// Running again should use the existing environment.
|
||||
uv_snapshot!(context.filters(), context.run().arg("--preview").arg("main.py"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"###);
|
||||
|
||||
// Otherwise, the script requirements should _not_ be available, but the project requirements
|
||||
// should.
|
||||
let test_non_script = context.temp_dir.child("main.py");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue