diff --git a/crates/gourgeist/src/bare.rs b/crates/gourgeist/src/bare.rs index fac848f53..1e9b4ad2e 100644 --- a/crates/gourgeist/src/bare.rs +++ b/crates/gourgeist/src/bare.rs @@ -66,6 +66,7 @@ pub fn create_bare_venv( location: &Utf8Path, interpreter: &Interpreter, prompt: Prompt, + system_site_packages: bool, extra_cfg: Vec<(String, String)>, ) -> Result { // We have to canonicalize the interpreter path, otherwise the home is set to the venv dir instead of the real root. @@ -251,7 +252,11 @@ pub fn create_bare_venv( ), ( "include-system-site-packages".to_string(), - "false".to_string(), + if system_site_packages { + "true".to_string() + } else { + "false".to_string() + }, ), ( "base-prefix".to_string(), diff --git a/crates/gourgeist/src/lib.rs b/crates/gourgeist/src/lib.rs index 4034c314f..0e4523579 100644 --- a/crates/gourgeist/src/lib.rs +++ b/crates/gourgeist/src/lib.rs @@ -51,12 +51,19 @@ pub fn create_venv( location: &Path, interpreter: Interpreter, prompt: Prompt, + system_site_packages: bool, extra_cfg: Vec<(String, String)>, ) -> Result { let location: &Utf8Path = location .try_into() .map_err(|err: FromPathError| err.into_io_error())?; - let paths = create_bare_venv(location, &interpreter, prompt, extra_cfg)?; + let paths = create_bare_venv( + location, + &interpreter, + prompt, + system_site_packages, + extra_cfg, + )?; Ok(PythonEnvironment::from_interpreter( interpreter, paths.root.as_std_path(), diff --git a/crates/gourgeist/src/main.rs b/crates/gourgeist/src/main.rs index 95af2f3a4..2e65d03d1 100644 --- a/crates/gourgeist/src/main.rs +++ b/crates/gourgeist/src/main.rs @@ -23,6 +23,8 @@ struct Cli { python: Option, #[clap(long)] prompt: Option, + #[clap(long)] + system_site_packages: bool, } fn run() -> Result<(), gourgeist::Error> { @@ -45,6 +47,7 @@ fn run() -> Result<(), gourgeist::Error> { &location, &interpreter, Prompt::from_args(cli.prompt), + cli.system_site_packages, Vec::new(), )?; Ok(()) diff --git a/crates/uv-build/src/lib.rs b/crates/uv-build/src/lib.rs index e65974adc..49c531cf5 100644 --- a/crates/uv-build/src/lib.rs +++ b/crates/uv-build/src/lib.rs @@ -402,6 +402,7 @@ impl SourceBuild { &temp_dir.path().join(".venv"), interpreter.clone(), gourgeist::Prompt::None, + false, Vec::new(), )?; diff --git a/crates/uv/src/commands/venv.rs b/crates/uv/src/commands/venv.rs index 04e7da5a3..55b1ece63 100644 --- a/crates/uv/src/commands/venv.rs +++ b/crates/uv/src/commands/venv.rs @@ -34,6 +34,7 @@ pub(crate) async fn venv( python_request: Option<&str>, index_locations: &IndexLocations, prompt: Prompt, + system_site_packages: bool, connectivity: Connectivity, seed: bool, exclude_newer: Option>, @@ -45,6 +46,7 @@ pub(crate) async fn venv( python_request, index_locations, prompt, + system_site_packages, connectivity, seed, exclude_newer, @@ -87,6 +89,7 @@ async fn venv_impl( python_request: Option<&str>, index_locations: &IndexLocations, prompt: Prompt, + system_site_packages: bool, connectivity: Connectivity, seed: bool, exclude_newer: Option>, @@ -123,7 +126,7 @@ async fn venv_impl( let extra_cfg = vec![("uv".to_string(), env!("CARGO_PKG_VERSION").to_string())]; // Create the virtual environment. - let venv = gourgeist::create_venv(path, interpreter, prompt, extra_cfg) + let venv = gourgeist::create_venv(path, interpreter, prompt, system_site_packages, extra_cfg) .map_err(VenvError::Creation)?; // Install seed packages. diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index 1efbeb567..8ee930992 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -936,6 +936,16 @@ struct VenvArgs { #[clap(long, verbatim_doc_comment)] prompt: Option, + /// Give the virtual environment access to the system site packages directory. + /// + /// Unlike `pip`, when a virtual environment is created with `--system-site-packages`, `uv` will + /// _not_ take system site packages into account when running commands like `uv pip list` or + /// `uv pip install`. The `--system-site-packages` flag will provide the virtual environment + /// with access to the system site packages directory at runtime, but it will not affect the + /// behavior of `uv` commands. + #[clap(long)] + system_site_packages: bool, + /// The URL of the Python package index (by default: ). /// /// The index given by this flag is given lower priority than all other @@ -1388,6 +1398,7 @@ async fn run() -> Result { args.python.as_deref(), &index_locations, gourgeist::Prompt::from_args(prompt), + args.system_site_packages, if args.offline { Connectivity::Offline } else {