mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Revert "Includes sys.prefix
in cached environment keys to avoid --with
collisions across projects (#14403)"
This reverts commit ec54dce919
.
This commit is contained in:
parent
537082c19e
commit
0fd8580e20
3 changed files with 15 additions and 33 deletions
|
@ -174,7 +174,7 @@ impl PythonEnvironment {
|
||||||
/// N.B. This function also works for system Python environments and users depend on this.
|
/// N.B. This function also works for system Python environments and users depend on this.
|
||||||
pub fn from_root(root: impl AsRef<Path>, cache: &Cache) -> Result<Self, Error> {
|
pub fn from_root(root: impl AsRef<Path>, cache: &Cache) -> Result<Self, Error> {
|
||||||
debug!(
|
debug!(
|
||||||
"Checking for Python environment at: {}",
|
"Checking for Python environment at: `{}`",
|
||||||
root.as_ref().user_display()
|
root.as_ref().user_display()
|
||||||
);
|
);
|
||||||
match root.as_ref().try_exists() {
|
match root.as_ref().try_exists() {
|
||||||
|
|
|
@ -107,15 +107,13 @@ impl CachedEnvironment {
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
preview: PreviewMode,
|
preview: PreviewMode,
|
||||||
) -> Result<Self, ProjectError> {
|
) -> Result<Self, ProjectError> {
|
||||||
// Resolve the "base" interpreter, which resolves to an underlying parent interpreter if the
|
let interpreter = Self::base_interpreter(interpreter, cache)?;
|
||||||
// given interpreter is a virtual environment.
|
|
||||||
let base_interpreter = Self::base_interpreter(interpreter, cache)?;
|
|
||||||
|
|
||||||
// Resolve the requirements with the interpreter.
|
// Resolve the requirements with the interpreter.
|
||||||
let resolution = Resolution::from(
|
let resolution = Resolution::from(
|
||||||
resolve_environment(
|
resolve_environment(
|
||||||
spec,
|
spec,
|
||||||
&base_interpreter,
|
&interpreter,
|
||||||
build_constraints.clone(),
|
build_constraints.clone(),
|
||||||
&settings.resolver,
|
&settings.resolver,
|
||||||
network_settings,
|
network_settings,
|
||||||
|
@ -143,29 +141,20 @@ impl CachedEnvironment {
|
||||||
// Use the canonicalized base interpreter path since that's the interpreter we performed the
|
// Use the canonicalized base interpreter path since that's the interpreter we performed the
|
||||||
// resolution with and the interpreter the environment will be created with.
|
// resolution with and the interpreter the environment will be created with.
|
||||||
//
|
//
|
||||||
// We also include the canonicalized `sys.prefix` of the non-base interpreter, that is, the
|
// We cache environments independent of the environment they'd be layered on top of. The
|
||||||
// virtual environment's path. Originally, we shared cached environments independent of the
|
// assumption is such that the environment will _not_ be modified by the user or uv;
|
||||||
// environment they'd be layered on top of. However, this causes collisions as the overlay
|
// otherwise, we risk cache poisoning. For example, if we were to write a `.pth` file to
|
||||||
// `.pth` file can be overridden by another instance of uv. Including this element in the key
|
// the cached environment, it would be shared across all projects that use the same
|
||||||
// avoids this problem at the cost of creating separate cached environments for identical
|
// interpreter and the same cached dependencies.
|
||||||
// `--with` invocations across projects. We use `sys.prefix` rather than `sys.executable` so
|
|
||||||
// we can canonicalize it without invalidating the purpose of the element — it'd probably be
|
|
||||||
// safe to just use the absolute `sys.executable` as well.
|
|
||||||
//
|
|
||||||
// TODO(zanieb): Since we're not sharing these environmments across projects, we should move
|
|
||||||
// [`CachedEvnvironment::set_overlay`] etc. here since the values there should be constant
|
|
||||||
// now.
|
|
||||||
//
|
//
|
||||||
// TODO(zanieb): We should include the version of the base interpreter in the hash, so if
|
// TODO(zanieb): We should include the version of the base interpreter in the hash, so if
|
||||||
// the interpreter at the canonicalized path changes versions we construct a new
|
// the interpreter at the canonicalized path changes versions we construct a new
|
||||||
// environment.
|
// environment.
|
||||||
let environment_hash = cache_digest(&(
|
let interpreter_hash =
|
||||||
&canonicalize_executable(base_interpreter.sys_executable())?,
|
cache_digest(&canonicalize_executable(interpreter.sys_executable())?);
|
||||||
&interpreter.sys_prefix().canonicalize()?,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Search in the content-addressed cache.
|
// Search in the content-addressed cache.
|
||||||
let cache_entry = cache.entry(CacheBucket::Environments, environment_hash, resolution_hash);
|
let cache_entry = cache.entry(CacheBucket::Environments, interpreter_hash, resolution_hash);
|
||||||
|
|
||||||
if cache.refresh().is_none() {
|
if cache.refresh().is_none() {
|
||||||
if let Ok(root) = cache.resolve_link(cache_entry.path()) {
|
if let Ok(root) = cache.resolve_link(cache_entry.path()) {
|
||||||
|
@ -179,7 +168,7 @@ impl CachedEnvironment {
|
||||||
let temp_dir = cache.venv_dir()?;
|
let temp_dir = cache.venv_dir()?;
|
||||||
let venv = uv_virtualenv::create_venv(
|
let venv = uv_virtualenv::create_venv(
|
||||||
temp_dir.path(),
|
temp_dir.path(),
|
||||||
base_interpreter,
|
interpreter,
|
||||||
uv_virtualenv::Prompt::None,
|
uv_virtualenv::Prompt::None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -1302,7 +1302,6 @@ fn run_with_pyvenv_cfg_file() -> Result<()> {
|
||||||
uv = [UV_VERSION]
|
uv = [UV_VERSION]
|
||||||
version_info = 3.12.[X]
|
version_info = 3.12.[X]
|
||||||
include-system-site-packages = false
|
include-system-site-packages = false
|
||||||
relocatable = true
|
|
||||||
extends-environment = [PARENT_VENV]
|
extends-environment = [PARENT_VENV]
|
||||||
|
|
||||||
|
|
||||||
|
@ -4778,7 +4777,6 @@ fn run_groups_include_requires_python() -> Result<()> {
|
||||||
baz = ["iniconfig"]
|
baz = ["iniconfig"]
|
||||||
dev = ["sniffio", {include-group = "foo"}, {include-group = "baz"}]
|
dev = ["sniffio", {include-group = "foo"}, {include-group = "baz"}]
|
||||||
|
|
||||||
|
|
||||||
[tool.uv.dependency-groups]
|
[tool.uv.dependency-groups]
|
||||||
foo = {requires-python="<3.13"}
|
foo = {requires-python="<3.13"}
|
||||||
bar = {requires-python=">=3.13"}
|
bar = {requires-python=">=3.13"}
|
||||||
|
@ -4923,8 +4921,8 @@ fn run_repeated() -> Result<()> {
|
||||||
Resolved 1 package in [TIME]
|
Resolved 1 package in [TIME]
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Re-running as a tool does require reinstalling `typing-extensions`, since the base venv is
|
// Re-running as a tool doesn't require reinstalling `typing-extensions`, since the environment
|
||||||
// different.
|
// is cached.
|
||||||
uv_snapshot!(
|
uv_snapshot!(
|
||||||
context.filters(),
|
context.filters(),
|
||||||
context.tool_run().arg("--with").arg("typing-extensions").arg("python").arg("-c").arg("import typing_extensions; import iniconfig"), @r#"
|
context.tool_run().arg("--with").arg("typing-extensions").arg("python").arg("-c").arg("import typing_extensions; import iniconfig"), @r#"
|
||||||
|
@ -4934,8 +4932,6 @@ fn run_repeated() -> Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Resolved 1 package in [TIME]
|
Resolved 1 package in [TIME]
|
||||||
Installed 1 package in [TIME]
|
|
||||||
+ typing-extensions==4.10.0
|
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "<string>", line 1, in <module>
|
File "<string>", line 1, in <module>
|
||||||
import typing_extensions; import iniconfig
|
import typing_extensions; import iniconfig
|
||||||
|
@ -4982,8 +4978,7 @@ fn run_without_overlay() -> Result<()> {
|
||||||
+ typing-extensions==4.10.0
|
+ typing-extensions==4.10.0
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Import `iniconfig` in the context of a `tool run` command, which should fail. Note that
|
// Import `iniconfig` in the context of a `tool run` command, which should fail.
|
||||||
// typing-extensions gets installed again, because the venv is not shared.
|
|
||||||
uv_snapshot!(
|
uv_snapshot!(
|
||||||
context.filters(),
|
context.filters(),
|
||||||
context.tool_run().arg("--with").arg("typing-extensions").arg("python").arg("-c").arg("import typing_extensions; import iniconfig"), @r#"
|
context.tool_run().arg("--with").arg("typing-extensions").arg("python").arg("-c").arg("import typing_extensions; import iniconfig"), @r#"
|
||||||
|
@ -4993,8 +4988,6 @@ fn run_without_overlay() -> Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Resolved 1 package in [TIME]
|
Resolved 1 package in [TIME]
|
||||||
Installed 1 package in [TIME]
|
|
||||||
+ typing-extensions==4.10.0
|
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "<string>", line 1, in <module>
|
File "<string>", line 1, in <module>
|
||||||
import typing_extensions; import iniconfig
|
import typing_extensions; import iniconfig
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue