mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
Use simpler pip-like Scheme
for install paths (#2173)
## Summary This will make it easier to use the paths returned by `distutils.py` (for some cases). No code or behavior changes; just removing some fields we don't need.
This commit is contained in:
parent
93f5609476
commit
5fed1f6259
13 changed files with 66 additions and 93 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -4508,6 +4508,7 @@ dependencies = [
|
||||||
"pep508_rs",
|
"pep508_rs",
|
||||||
"platform-host",
|
"platform-host",
|
||||||
"platform-tags",
|
"platform-tags",
|
||||||
|
"pypi-types",
|
||||||
"regex",
|
"regex",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"same-file",
|
"same-file",
|
||||||
|
@ -4615,6 +4616,7 @@ dependencies = [
|
||||||
"directories",
|
"directories",
|
||||||
"fs-err",
|
"fs-err",
|
||||||
"platform-host",
|
"platform-host",
|
||||||
|
"pypi-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
|
|
@ -13,6 +13,7 @@ use zip::ZipArchive;
|
||||||
use distribution_filename::WheelFilename;
|
use distribution_filename::WheelFilename;
|
||||||
use pep440_rs::Version;
|
use pep440_rs::Version;
|
||||||
use platform_host::{Arch, Os};
|
use platform_host::{Arch, Os};
|
||||||
|
use pypi_types::Scheme;
|
||||||
pub use uninstall::{uninstall_wheel, Uninstall};
|
pub use uninstall::{uninstall_wheel, Uninstall};
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_normalize::PackageName;
|
use uv_normalize::PackageName;
|
||||||
|
@ -28,20 +29,12 @@ mod wheel;
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
/// The Python interpreter, as returned by `sys.executable`.
|
/// The Python interpreter, as returned by `sys.executable`.
|
||||||
pub sys_executable: PathBuf,
|
pub sys_executable: PathBuf,
|
||||||
/// The `purelib` directory, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub purelib: PathBuf,
|
|
||||||
/// The `platlib` directory, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub platlib: PathBuf,
|
|
||||||
/// The `include` directory, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub include: PathBuf,
|
|
||||||
/// The `scripts` directory, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub scripts: PathBuf,
|
|
||||||
/// The `data` directory, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub data: PathBuf,
|
|
||||||
/// The Python version, as returned by `sys.version_info`.
|
/// The Python version, as returned by `sys.version_info`.
|
||||||
pub python_version: (u8, u8),
|
pub python_version: (u8, u8),
|
||||||
/// The `os.name` value for the current platform.
|
/// The `os.name` value for the current platform.
|
||||||
pub os_name: String,
|
pub os_name: String,
|
||||||
|
/// The [`Scheme`] paths for the interpreter.
|
||||||
|
pub scheme: Scheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note: The caller is responsible for adding the path of the wheel we're installing.
|
/// Note: The caller is responsible for adding the path of the wheel we're installing.
|
||||||
|
|
|
@ -69,8 +69,8 @@ pub fn install_wheel(
|
||||||
// > 1.d Else unpack archive into platlib (site-packages).
|
// > 1.d Else unpack archive into platlib (site-packages).
|
||||||
debug!(name, "Extracting file");
|
debug!(name, "Extracting file");
|
||||||
let site_packages = match lib_kind {
|
let site_packages = match lib_kind {
|
||||||
LibKind::Pure => &layout.purelib,
|
LibKind::Pure => &layout.scheme.purelib,
|
||||||
LibKind::Plat => &layout.platlib,
|
LibKind::Plat => &layout.scheme.platlib,
|
||||||
};
|
};
|
||||||
let num_unpacked = link_mode.link_wheel_files(site_packages, &wheel)?;
|
let num_unpacked = link_mode.link_wheel_files(site_packages, &wheel)?;
|
||||||
debug!(name, "Extracted {num_unpacked} files");
|
debug!(name, "Extracted {num_unpacked} files");
|
||||||
|
|
|
@ -236,9 +236,9 @@ pub(crate) fn write_script_entrypoints(
|
||||||
.to_string()
|
.to_string()
|
||||||
+ ".exe";
|
+ ".exe";
|
||||||
|
|
||||||
layout.scripts.join(script_name)
|
layout.scheme.scripts.join(script_name)
|
||||||
} else {
|
} else {
|
||||||
layout.scripts.join(&entrypoint.name)
|
layout.scheme.scripts.join(&entrypoint.name)
|
||||||
};
|
};
|
||||||
|
|
||||||
let entrypoint_relative = pathdiff::diff_paths(&entrypoint_absolute, site_packages)
|
let entrypoint_relative = pathdiff::diff_paths(&entrypoint_absolute, site_packages)
|
||||||
|
@ -440,7 +440,7 @@ fn install_script(
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_path = layout.scripts.join(file.file_name());
|
let target_path = layout.scheme.scripts.join(file.file_name());
|
||||||
|
|
||||||
let path = file.path();
|
let path = file.path();
|
||||||
let mut script = File::open(&path)?;
|
let mut script = File::open(&path)?;
|
||||||
|
@ -520,7 +520,7 @@ pub(crate) fn install_data(
|
||||||
match path.file_name().and_then(|name| name.to_str()) {
|
match path.file_name().and_then(|name| name.to_str()) {
|
||||||
Some("data") => {
|
Some("data") => {
|
||||||
// Move the content of the folder to the root of the venv
|
// Move the content of the folder to the root of the venv
|
||||||
move_folder_recorded(&path, &layout.data, site_packages, record)?;
|
move_folder_recorded(&path, &layout.scheme.data, site_packages, record)?;
|
||||||
}
|
}
|
||||||
Some("scripts") => {
|
Some("scripts") => {
|
||||||
for file in fs::read_dir(path)? {
|
for file in fs::read_dir(path)? {
|
||||||
|
@ -546,14 +546,14 @@ pub(crate) fn install_data(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some("headers") => {
|
Some("headers") => {
|
||||||
let target_path = layout.include.join(dist_name);
|
let target_path = layout.scheme.include.join(dist_name);
|
||||||
move_folder_recorded(&path, &target_path, site_packages, record)?;
|
move_folder_recorded(&path, &target_path, site_packages, record)?;
|
||||||
}
|
}
|
||||||
Some("purelib") => {
|
Some("purelib") => {
|
||||||
move_folder_recorded(&path, &layout.purelib, site_packages, record)?;
|
move_folder_recorded(&path, &layout.scheme.purelib, site_packages, record)?;
|
||||||
}
|
}
|
||||||
Some("platlib") => {
|
Some("platlib") => {
|
||||||
move_folder_recorded(&path, &layout.platlib, site_packages, record)?;
|
move_folder_recorded(&path, &layout.scheme.platlib, site_packages, record)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidWheel(format!(
|
return Err(Error::InvalidWheel(format!(
|
||||||
|
|
|
@ -2,10 +2,12 @@ pub use base_url::*;
|
||||||
pub use direct_url::*;
|
pub use direct_url::*;
|
||||||
pub use lenient_requirement::*;
|
pub use lenient_requirement::*;
|
||||||
pub use metadata::*;
|
pub use metadata::*;
|
||||||
|
pub use scheme::*;
|
||||||
pub use simple_json::*;
|
pub use simple_json::*;
|
||||||
|
|
||||||
mod base_url;
|
mod base_url;
|
||||||
mod direct_url;
|
mod direct_url;
|
||||||
mod lenient_requirement;
|
mod lenient_requirement;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
|
mod scheme;
|
||||||
mod simple_json;
|
mod simple_json;
|
||||||
|
|
|
@ -2,17 +2,17 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// The installation paths returned by `sysconfig.get_paths()`.
|
/// The paths associated with an installation scheme, typically returned by `sysconfig.get_paths()`.
|
||||||
|
///
|
||||||
|
/// See: <https://github.com/pypa/pip/blob/ae5fff36b0aad6e5e0037884927eaa29163c0611/src/pip/_internal/models/scheme.py#L12>
|
||||||
///
|
///
|
||||||
/// See: <https://docs.python.org/3.12/library/sysconfig.html#installation-paths>
|
/// See: <https://docs.python.org/3.12/library/sysconfig.html#installation-paths>
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct SysconfigPaths {
|
pub struct Scheme {
|
||||||
pub stdlib: PathBuf,
|
pub stdlib: PathBuf,
|
||||||
pub platstdlib: PathBuf,
|
|
||||||
pub purelib: PathBuf,
|
pub purelib: PathBuf,
|
||||||
pub platlib: PathBuf,
|
pub platlib: PathBuf,
|
||||||
pub include: PathBuf,
|
|
||||||
pub platinclude: PathBuf,
|
|
||||||
pub scripts: PathBuf,
|
pub scripts: PathBuf,
|
||||||
pub data: PathBuf,
|
pub data: PathBuf,
|
||||||
|
pub include: PathBuf,
|
||||||
}
|
}
|
|
@ -14,13 +14,14 @@ workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cache-key = { path = "../cache-key" }
|
cache-key = { path = "../cache-key" }
|
||||||
|
install-wheel-rs = { path = "../install-wheel-rs" }
|
||||||
pep440_rs = { path = "../pep440-rs" }
|
pep440_rs = { path = "../pep440-rs" }
|
||||||
pep508_rs = { path = "../pep508-rs", features = ["serde"] }
|
pep508_rs = { path = "../pep508-rs", features = ["serde"] }
|
||||||
platform-host = { path = "../platform-host" }
|
platform-host = { path = "../platform-host" }
|
||||||
platform-tags = { path = "../platform-tags" }
|
platform-tags = { path = "../platform-tags" }
|
||||||
|
pypi-types = { path = "../pypi-types" }
|
||||||
uv-cache = { path = "../uv-cache" }
|
uv-cache = { path = "../uv-cache" }
|
||||||
uv-fs = { path = "../uv-fs" }
|
uv-fs = { path = "../uv-fs" }
|
||||||
install-wheel-rs = { path = "../install-wheel-rs" }
|
|
||||||
|
|
||||||
configparser = { workspace = true }
|
configparser = { workspace = true }
|
||||||
fs-err = { workspace = true, features = ["tokio"] }
|
fs-err = { workspace = true, features = ["tokio"] }
|
||||||
|
|
|
@ -90,6 +90,6 @@ interpreter_info = {
|
||||||
"prefix": sys.prefix,
|
"prefix": sys.prefix,
|
||||||
"base_executable": getattr(sys, "_base_executable", None),
|
"base_executable": getattr(sys, "_base_executable", None),
|
||||||
"sys_executable": sys.executable,
|
"sys_executable": sys.executable,
|
||||||
"sysconfig_paths": sysconfig.get_paths(),
|
"scheme": sysconfig.get_paths(),
|
||||||
}
|
}
|
||||||
print(json.dumps(interpreter_info))
|
print(json.dumps(interpreter_info))
|
||||||
|
|
|
@ -15,12 +15,12 @@ use pep440_rs::Version;
|
||||||
use pep508_rs::MarkerEnvironment;
|
use pep508_rs::MarkerEnvironment;
|
||||||
use platform_host::Platform;
|
use platform_host::Platform;
|
||||||
use platform_tags::{Tags, TagsError};
|
use platform_tags::{Tags, TagsError};
|
||||||
|
use pypi_types::Scheme;
|
||||||
use uv_cache::{Cache, CacheBucket, CachedByTimestamp, Freshness, Timestamp};
|
use uv_cache::{Cache, CacheBucket, CachedByTimestamp, Freshness, Timestamp};
|
||||||
use uv_fs::write_atomic_sync;
|
use uv_fs::write_atomic_sync;
|
||||||
|
|
||||||
use crate::python_environment::{detect_python_executable, detect_virtual_env};
|
use crate::python_environment::{detect_python_executable, detect_virtual_env};
|
||||||
use crate::python_query::try_find_default_python;
|
use crate::python_query::try_find_default_python;
|
||||||
use crate::sysconfig::SysconfigPaths;
|
|
||||||
use crate::{find_requested_python, Error, PythonVersion, Virtualenv};
|
use crate::{find_requested_python, Error, PythonVersion, Virtualenv};
|
||||||
|
|
||||||
/// A Python executable and its associated platform markers.
|
/// A Python executable and its associated platform markers.
|
||||||
|
@ -28,7 +28,7 @@ use crate::{find_requested_python, Error, PythonVersion, Virtualenv};
|
||||||
pub struct Interpreter {
|
pub struct Interpreter {
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
markers: Box<MarkerEnvironment>,
|
markers: Box<MarkerEnvironment>,
|
||||||
sysconfig_paths: SysconfigPaths,
|
scheme: Scheme,
|
||||||
prefix: PathBuf,
|
prefix: PathBuf,
|
||||||
base_exec_prefix: PathBuf,
|
base_exec_prefix: PathBuf,
|
||||||
base_prefix: PathBuf,
|
base_prefix: PathBuf,
|
||||||
|
@ -51,7 +51,7 @@ impl Interpreter {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
platform,
|
platform,
|
||||||
markers: Box::new(info.markers),
|
markers: Box::new(info.markers),
|
||||||
sysconfig_paths: info.sysconfig_paths,
|
scheme: info.scheme,
|
||||||
prefix: info.prefix,
|
prefix: info.prefix,
|
||||||
base_exec_prefix: info.base_exec_prefix,
|
base_exec_prefix: info.base_exec_prefix,
|
||||||
base_prefix: info.base_prefix,
|
base_prefix: info.base_prefix,
|
||||||
|
@ -66,13 +66,11 @@ impl Interpreter {
|
||||||
Self {
|
Self {
|
||||||
platform,
|
platform,
|
||||||
markers: Box::new(markers),
|
markers: Box::new(markers),
|
||||||
sysconfig_paths: SysconfigPaths {
|
scheme: Scheme {
|
||||||
stdlib: PathBuf::from("/dev/null"),
|
stdlib: PathBuf::from("/dev/null"),
|
||||||
platstdlib: PathBuf::from("/dev/null"),
|
|
||||||
purelib: PathBuf::from("/dev/null"),
|
purelib: PathBuf::from("/dev/null"),
|
||||||
platlib: PathBuf::from("/dev/null"),
|
platlib: PathBuf::from("/dev/null"),
|
||||||
include: PathBuf::from("/dev/null"),
|
include: PathBuf::from("/dev/null"),
|
||||||
platinclude: PathBuf::from("/dev/null"),
|
|
||||||
scripts: PathBuf::from("/dev/null"),
|
scripts: PathBuf::from("/dev/null"),
|
||||||
data: PathBuf::from("/dev/null"),
|
data: PathBuf::from("/dev/null"),
|
||||||
},
|
},
|
||||||
|
@ -89,7 +87,7 @@ impl Interpreter {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_virtualenv(self, virtualenv: Virtualenv) -> Self {
|
pub fn with_virtualenv(self, virtualenv: Virtualenv) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sysconfig_paths: virtualenv.sysconfig_paths,
|
scheme: virtualenv.scheme,
|
||||||
sys_executable: virtualenv.executable,
|
sys_executable: virtualenv.executable,
|
||||||
prefix: virtualenv.root,
|
prefix: virtualenv.root,
|
||||||
..self
|
..self
|
||||||
|
@ -262,9 +260,7 @@ impl Interpreter {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Ok(contents) =
|
let Ok(contents) = fs::read_to_string(self.scheme.stdlib.join("EXTERNALLY-MANAGED")) else {
|
||||||
fs::read_to_string(self.sysconfig_paths.stdlib.join("EXTERNALLY-MANAGED"))
|
|
||||||
else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -371,37 +367,32 @@ impl Interpreter {
|
||||||
|
|
||||||
/// Return the `purelib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `purelib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn purelib(&self) -> &Path {
|
pub fn purelib(&self) -> &Path {
|
||||||
&self.sysconfig_paths.purelib
|
&self.scheme.purelib
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the `platlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `platlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn platlib(&self) -> &Path {
|
pub fn platlib(&self) -> &Path {
|
||||||
&self.sysconfig_paths.platlib
|
&self.scheme.platlib
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the `scripts` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `scripts` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn scripts(&self) -> &Path {
|
pub fn scripts(&self) -> &Path {
|
||||||
&self.sysconfig_paths.scripts
|
&self.scheme.scripts
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the `data` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `data` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn data(&self) -> &Path {
|
pub fn data(&self) -> &Path {
|
||||||
&self.sysconfig_paths.data
|
&self.scheme.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the `include` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `include` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn include(&self) -> &Path {
|
pub fn include(&self) -> &Path {
|
||||||
&self.sysconfig_paths.include
|
&self.scheme.include
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the `platinclude` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
|
||||||
pub fn platinclude(&self) -> &Path {
|
|
||||||
&self.sysconfig_paths.platinclude
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the `stdlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
/// Return the `stdlib` path for this Python interpreter, as returned by `sysconfig.get_paths()`.
|
||||||
pub fn stdlib(&self) -> &Path {
|
pub fn stdlib(&self) -> &Path {
|
||||||
&self.sysconfig_paths.stdlib
|
&self.scheme.stdlib
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the name of the Python directory used to build the path to the
|
/// Return the name of the Python directory used to build the path to the
|
||||||
|
@ -421,23 +412,26 @@ impl Interpreter {
|
||||||
Layout {
|
Layout {
|
||||||
python_version: self.python_tuple(),
|
python_version: self.python_tuple(),
|
||||||
sys_executable: self.sys_executable().to_path_buf(),
|
sys_executable: self.sys_executable().to_path_buf(),
|
||||||
purelib: self.purelib().to_path_buf(),
|
|
||||||
platlib: self.platlib().to_path_buf(),
|
|
||||||
scripts: self.scripts().to_path_buf(),
|
|
||||||
data: self.data().to_path_buf(),
|
|
||||||
include: if self.is_virtualenv() {
|
|
||||||
// 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(),
|
|
||||||
self.python_major(),
|
|
||||||
self.python_minor()
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
self.include().to_path_buf()
|
|
||||||
},
|
|
||||||
os_name: self.markers.os_name.clone(),
|
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(),
|
||||||
|
data: self.data().to_path_buf(),
|
||||||
|
include: if self.is_virtualenv() {
|
||||||
|
// 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(),
|
||||||
|
self.python_major(),
|
||||||
|
self.python_minor()
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
self.include().to_path_buf()
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,7 +454,7 @@ impl ExternallyManaged {
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
struct InterpreterInfo {
|
struct InterpreterInfo {
|
||||||
markers: MarkerEnvironment,
|
markers: MarkerEnvironment,
|
||||||
sysconfig_paths: SysconfigPaths,
|
scheme: Scheme,
|
||||||
prefix: PathBuf,
|
prefix: PathBuf,
|
||||||
base_exec_prefix: PathBuf,
|
base_exec_prefix: PathBuf,
|
||||||
base_prefix: PathBuf,
|
base_prefix: PathBuf,
|
||||||
|
@ -661,15 +655,13 @@ mod tests {
|
||||||
"base_prefix": "/home/ferris/.pyenv/versions/3.12.0",
|
"base_prefix": "/home/ferris/.pyenv/versions/3.12.0",
|
||||||
"prefix": "/home/ferris/projects/uv/.venv",
|
"prefix": "/home/ferris/projects/uv/.venv",
|
||||||
"sys_executable": "/home/ferris/projects/uv/.venv/bin/python",
|
"sys_executable": "/home/ferris/projects/uv/.venv/bin/python",
|
||||||
"sysconfig_paths": {
|
"scheme": {
|
||||||
"data": "/home/ferris/.pyenv/versions/3.12.0",
|
"data": "/home/ferris/.pyenv/versions/3.12.0",
|
||||||
"include": "/home/ferris/.pyenv/versions/3.12.0/include",
|
"include": "/home/ferris/.pyenv/versions/3.12.0/include",
|
||||||
"platinclude": "/home/ferris/.pyenv/versions/3.12.0/include",
|
|
||||||
"platlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12/site-packages",
|
"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",
|
"purelib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12/site-packages",
|
||||||
"scripts": "/home/ferris/.pyenv/versions/3.12.0/bin",
|
"scripts": "/home/ferris/.pyenv/versions/3.12.0/bin",
|
||||||
"stdlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12",
|
"stdlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12"
|
||||||
"platstdlib": "/home/ferris/.pyenv/versions/3.12.0/lib/python3.12"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"##};
|
"##};
|
||||||
|
|
|
@ -9,7 +9,6 @@ pub use crate::interpreter::Interpreter;
|
||||||
pub use crate::python_environment::PythonEnvironment;
|
pub use crate::python_environment::PythonEnvironment;
|
||||||
pub use crate::python_query::{find_default_python, find_requested_python};
|
pub use crate::python_query::{find_default_python, find_requested_python};
|
||||||
pub use crate::python_version::PythonVersion;
|
pub use crate::python_version::PythonVersion;
|
||||||
pub use crate::sysconfig::SysconfigPaths;
|
|
||||||
pub use crate::virtualenv::Virtualenv;
|
pub use crate::virtualenv::Virtualenv;
|
||||||
|
|
||||||
mod cfg;
|
mod cfg;
|
||||||
|
@ -17,7 +16,6 @@ mod interpreter;
|
||||||
mod python_environment;
|
mod python_environment;
|
||||||
mod python_query;
|
mod python_query;
|
||||||
mod python_version;
|
mod python_version;
|
||||||
mod sysconfig;
|
|
||||||
mod virtualenv;
|
mod virtualenv;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::sysconfig::SysconfigPaths;
|
use pypi_types::Scheme;
|
||||||
|
|
||||||
/// The layout of a virtual environment.
|
/// The layout of a virtual environment.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -12,6 +12,6 @@ pub struct Virtualenv {
|
||||||
/// (Unix, Python 3.11).
|
/// (Unix, Python 3.11).
|
||||||
pub executable: PathBuf,
|
pub executable: PathBuf,
|
||||||
|
|
||||||
/// The `sysconfig` paths for the virtualenv, as returned by `sysconfig.get_paths()`.
|
/// The [`Scheme`] paths for the virtualenv, as returned by (e.g.) `sysconfig.get_paths()`.
|
||||||
pub sysconfig_paths: SysconfigPaths,
|
pub scheme: Scheme,
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
platform-host = { path = "../platform-host" }
|
platform-host = { path = "../platform-host" }
|
||||||
|
pypi-types = { path = "../pypi-types" }
|
||||||
uv-cache = { path = "../uv-cache" }
|
uv-cache = { path = "../uv-cache" }
|
||||||
uv-fs = { path = "../uv-fs" }
|
uv-fs = { path = "../uv-fs" }
|
||||||
uv-interpreter = { path = "../uv-interpreter" }
|
uv-interpreter = { path = "../uv-interpreter" }
|
||||||
|
|
|
@ -9,9 +9,10 @@ use std::path::Path;
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
use fs_err::File;
|
use fs_err::File;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use uv_fs::Simplified;
|
|
||||||
|
|
||||||
use uv_interpreter::{Interpreter, SysconfigPaths, Virtualenv};
|
use pypi_types::Scheme;
|
||||||
|
use uv_fs::Simplified;
|
||||||
|
use uv_interpreter::{Interpreter, Virtualenv};
|
||||||
|
|
||||||
use crate::{Error, Prompt};
|
use crate::{Error, Prompt};
|
||||||
|
|
||||||
|
@ -292,38 +293,21 @@ pub fn create_bare_venv(
|
||||||
unimplemented!("Only Windows and Unix are supported")
|
unimplemented!("Only Windows and Unix are supported")
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construct the path to the `platstdlib` directory.
|
|
||||||
let platstdlib = if cfg!(windows) {
|
|
||||||
location.join("Lib")
|
|
||||||
} else {
|
|
||||||
location
|
|
||||||
.join("lib")
|
|
||||||
.join(format!(
|
|
||||||
"{}{}.{}",
|
|
||||||
interpreter.site_packages_python(),
|
|
||||||
interpreter.python_major(),
|
|
||||||
interpreter.python_minor()
|
|
||||||
))
|
|
||||||
.join("site-packages")
|
|
||||||
};
|
|
||||||
|
|
||||||
// Populate `site-packages` with a `_virtualenv.py` file.
|
// Populate `site-packages` with a `_virtualenv.py` file.
|
||||||
fs::create_dir_all(&site_packages)?;
|
fs::create_dir_all(&site_packages)?;
|
||||||
fs::write(site_packages.join("_virtualenv.py"), VIRTUALENV_PATCH)?;
|
fs::write(site_packages.join("_virtualenv.py"), VIRTUALENV_PATCH)?;
|
||||||
fs::write(site_packages.join("_virtualenv.pth"), "import _virtualenv")?;
|
fs::write(site_packages.join("_virtualenv.pth"), "import _virtualenv")?;
|
||||||
|
|
||||||
Ok(Virtualenv {
|
Ok(Virtualenv {
|
||||||
sysconfig_paths: SysconfigPaths {
|
scheme: Scheme {
|
||||||
// Paths that were already constructed above.
|
// Paths that were already constructed above.
|
||||||
scripts,
|
scripts,
|
||||||
platstdlib,
|
|
||||||
// Set `purelib` and `platlib` to the same value.
|
// Set `purelib` and `platlib` to the same value.
|
||||||
purelib: site_packages.clone(),
|
purelib: site_packages.clone(),
|
||||||
platlib: site_packages,
|
platlib: site_packages,
|
||||||
// Inherited from the interpreter.
|
// Inherited from the interpreter.
|
||||||
stdlib: interpreter.stdlib().to_path_buf(),
|
stdlib: interpreter.stdlib().to_path_buf(),
|
||||||
include: interpreter.include().to_path_buf(),
|
include: interpreter.include().to_path_buf(),
|
||||||
platinclude: interpreter.platinclude().to_path_buf(),
|
|
||||||
data: location.clone(),
|
data: location.clone(),
|
||||||
},
|
},
|
||||||
root: location,
|
root: location,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue