mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-03 13:14:41 +00:00
Query interpreter to determine correct virtualenv paths (#2188)
## Summary This PR migrates our virtualenv creation from a setup that assumes prior knowledge of the correct paths, to a technique borrowed from `virtualenv` whereby we use `sysconfig` and `distutils` to determine the paths. The general trick is to grab the expected paths with `sysconfig`, then make them all relative, then make them absolute for a given directory. Closes #2095. Closes #2153.
This commit is contained in:
parent
a8ac7b1eb4
commit
0f6fc117c1
6 changed files with 171 additions and 66 deletions
|
|
@ -28,11 +28,13 @@ pub struct Interpreter {
|
|||
platform: Platform,
|
||||
markers: Box<MarkerEnvironment>,
|
||||
scheme: Scheme,
|
||||
virtualenv: Scheme,
|
||||
prefix: PathBuf,
|
||||
base_exec_prefix: PathBuf,
|
||||
base_prefix: PathBuf,
|
||||
base_executable: Option<PathBuf>,
|
||||
sys_executable: PathBuf,
|
||||
stdlib: PathBuf,
|
||||
tags: OnceCell<Tags>,
|
||||
}
|
||||
|
||||
|
|
@ -51,11 +53,13 @@ impl Interpreter {
|
|||
platform,
|
||||
markers: Box::new(info.markers),
|
||||
scheme: info.scheme,
|
||||
virtualenv: info.virtualenv,
|
||||
prefix: info.prefix,
|
||||
base_exec_prefix: info.base_exec_prefix,
|
||||
base_prefix: info.base_prefix,
|
||||
base_executable: info.base_executable,
|
||||
sys_executable: info.sys_executable,
|
||||
stdlib: info.stdlib,
|
||||
tags: OnceCell::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -66,7 +70,13 @@ impl Interpreter {
|
|||
platform,
|
||||
markers: Box::new(markers),
|
||||
scheme: Scheme {
|
||||
stdlib: PathBuf::from("/dev/null"),
|
||||
purelib: PathBuf::from("/dev/null"),
|
||||
platlib: PathBuf::from("/dev/null"),
|
||||
include: PathBuf::from("/dev/null"),
|
||||
scripts: PathBuf::from("/dev/null"),
|
||||
data: PathBuf::from("/dev/null"),
|
||||
},
|
||||
virtualenv: Scheme {
|
||||
purelib: PathBuf::from("/dev/null"),
|
||||
platlib: PathBuf::from("/dev/null"),
|
||||
include: PathBuf::from("/dev/null"),
|
||||
|
|
@ -78,6 +88,7 @@ impl Interpreter {
|
|||
base_prefix: PathBuf::from("/dev/null"),
|
||||
base_executable: None,
|
||||
sys_executable: PathBuf::from("/dev/null"),
|
||||
stdlib: PathBuf::from("/dev/null"),
|
||||
tags: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
|
@ -240,7 +251,7 @@ impl Interpreter {
|
|||
return None;
|
||||
}
|
||||
|
||||
let Ok(contents) = fs::read_to_string(self.scheme.stdlib.join("EXTERNALLY-MANAGED")) else {
|
||||
let Ok(contents) = fs::read_to_string(self.stdlib.join("EXTERNALLY-MANAGED")) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
|
@ -345,6 +356,11 @@ impl Interpreter {
|
|||
&self.sys_executable
|
||||
}
|
||||
|
||||
/// Return the `stdlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||
pub fn stdlib(&self) -> &Path {
|
||||
&self.stdlib
|
||||
}
|
||||
|
||||
/// Return the `purelib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||
pub fn purelib(&self) -> &Path {
|
||||
&self.scheme.purelib
|
||||
|
|
@ -370,21 +386,9 @@ impl Interpreter {
|
|||
&self.scheme.include
|
||||
}
|
||||
|
||||
/// Return the `stdlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||
pub fn stdlib(&self) -> &Path {
|
||||
&self.scheme.stdlib
|
||||
}
|
||||
|
||||
/// Return the name of the Python directory used to build the path to the
|
||||
/// `site-packages` directory.
|
||||
///
|
||||
/// If one could not be determined, then `python` is returned.
|
||||
pub fn site_packages_python(&self) -> &str {
|
||||
if self.implementation_name() == "pypy" {
|
||||
"pypy"
|
||||
} else {
|
||||
"python"
|
||||
}
|
||||
/// Return the [`Scheme`] for a virtual environment created by this [`Interpreter`].
|
||||
pub fn virtualenv(&self) -> &Scheme {
|
||||
&self.virtualenv
|
||||
}
|
||||
|
||||
/// Return the [`Layout`] environment used to install wheels into this interpreter.
|
||||
|
|
@ -394,7 +398,6 @@ impl Interpreter {
|
|||
sys_executable: self.sys_executable().to_path_buf(),
|
||||
os_name: self.markers.os_name.clone(),
|
||||
scheme: Scheme {
|
||||
stdlib: self.stdlib().to_path_buf(),
|
||||
purelib: self.purelib().to_path_buf(),
|
||||
platlib: self.platlib().to_path_buf(),
|
||||
scripts: self.scripts().to_path_buf(),
|
||||
|
|
@ -403,8 +406,7 @@ impl Interpreter {
|
|||
// If the interpreter is a venv, then the `include` directory has a different structure.
|
||||
// See: https://github.com/pypa/pip/blob/0ad4c94be74cc24874c6feb5bb3c2152c398a18e/src/pip/_internal/locations/_sysconfig.py#L172
|
||||
self.prefix.join("include").join("site").join(format!(
|
||||
"{}{}.{}",
|
||||
self.site_packages_python(),
|
||||
"python{}.{}",
|
||||
self.python_major(),
|
||||
self.python_minor()
|
||||
))
|
||||
|
|
@ -435,11 +437,13 @@ impl ExternallyManaged {
|
|||
struct InterpreterInfo {
|
||||
markers: MarkerEnvironment,
|
||||
scheme: Scheme,
|
||||
virtualenv: Scheme,
|
||||
prefix: PathBuf,
|
||||
base_exec_prefix: PathBuf,
|
||||
base_prefix: PathBuf,
|
||||
base_executable: Option<PathBuf>,
|
||||
sys_executable: PathBuf,
|
||||
stdlib: PathBuf,
|
||||
}
|
||||
|
||||
impl InterpreterInfo {
|
||||
|
|
@ -635,13 +639,20 @@ mod tests {
|
|||
"base_prefix": "/home/ferris/.pyenv/versions/3.12.0",
|
||||
"prefix": "/home/ferris/projects/uv/.venv",
|
||||
"sys_executable": "/home/ferris/projects/uv/.venv/bin/python",
|
||||
"stdlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12",
|
||||
"scheme": {
|
||||
"data": "/home/ferris/.pyenv/versions/3.12.0",
|
||||
"include": "/home/ferris/.pyenv/versions/3.12.0/include",
|
||||
"platlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12/site-packages",
|
||||
"purelib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12/site-packages",
|
||||
"scripts": "/home/ferris/.pyenv/versions/3.12.0/bin",
|
||||
"stdlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12"
|
||||
"scripts": "/home/ferris/.pyenv/versions/3.12.0/bin"
|
||||
},
|
||||
"virtualenv": {
|
||||
"data": "",
|
||||
"include": "include",
|
||||
"platlib": "lib/python3.12/site-packages",
|
||||
"purelib": "lib/python3.12/site-packages",
|
||||
"scripts": "bin"
|
||||
}
|
||||
}
|
||||
"##};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue