Skip to content

Commit d3e20f6

Browse files
committed
add install_dir argument to ManagedPythonInstallations::from_settings
1 parent 0a01527 commit d3e20f6

File tree

10 files changed

+39
-32
lines changed

10 files changed

+39
-32
lines changed

crates/uv-cli/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,8 +3734,7 @@ pub struct PythonListArgs {
37343734
#[derive(Args)]
37353735
#[allow(clippy::struct_excessive_bools)]
37363736
pub struct PythonInstallArgs {
3737-
/// The directory where Python will be installed.
3738-
///
3737+
/// The directory to store the Python installation in.
37393738
#[arg(long, short, env = "UV_PYTHON_INSTALL_DIR")]
37403739
pub install_dir: Option<PathBuf>,
37413740

crates/uv-python/src/discovery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ fn python_executables_from_installed<'a>(
294294
preference: PythonPreference,
295295
) -> Box<dyn Iterator<Item = Result<(PythonSource, PathBuf), Error>> + 'a> {
296296
let from_managed_installations = std::iter::once_with(move || {
297-
ManagedPythonInstallations::from_settings()
297+
ManagedPythonInstallations::from_settings(None)
298298
.map_err(Error::from)
299299
.and_then(|installed_installations| {
300300
debug!(

crates/uv-python/src/installation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl PythonInstallation {
122122
cache: &Cache,
123123
reporter: Option<&dyn Reporter>,
124124
) -> Result<Self, Error> {
125-
let installations = ManagedPythonInstallations::from_settings()?.init()?;
125+
let installations = ManagedPythonInstallations::from_settings(None)?.init()?;
126126
let installations_dir = installations.root();
127127
let cache_dir = installations.cache();
128128
let _lock = installations.lock().await?;

crates/uv-python/src/managed.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub struct ManagedPythonInstallations {
6666

6767
impl ManagedPythonInstallations {
6868
/// A directory for Python installations at `root`.
69-
pub fn from_path(root: impl Into<PathBuf>) -> Self {
69+
fn from_path(root: impl Into<PathBuf>) -> Self {
7070
Self { root: root.into() }
7171
}
7272

@@ -77,11 +77,14 @@ impl ManagedPythonInstallations {
7777
}
7878

7979
/// Prefer, in order:
80-
/// 1. The specific Python directory specified by the user, i.e., `UV_PYTHON_INSTALL_DIR`
81-
/// 2. A directory in the system-appropriate user-level data directory, e.g., `~/.local/uv/python`
82-
/// 3. A directory in the local data directory, e.g., `./.uv/python`
83-
pub fn from_settings() -> Result<Self, Error> {
84-
if let Some(install_dir) = std::env::var_os(EnvVars::UV_PYTHON_INSTALL_DIR) {
80+
/// 1. The specific Python directory directly passed to the `install_dir` argument
81+
/// 2. The specific Python directory specified with the `UV_PYTHON_INSTALL_DIR` environment variable
82+
/// 3. A directory in the system-appropriate user-level data directory, e.g., `~/.local/uv/python`
83+
/// 4. A directory in the local data directory, e.g., `./.uv/python`
84+
pub fn from_settings(install_dir: Option<PathBuf>) -> Result<Self, Error> {
85+
if install_dir.is_some() {
86+
Ok(Self::from_path(install_dir.unwrap()))
87+
} else if let Some(install_dir) = std::env::var_os(EnvVars::UV_PYTHON_INSTALL_DIR) {
8588
Ok(Self::from_path(install_dir))
8689
} else {
8790
Ok(Self::from_path(
@@ -197,7 +200,7 @@ impl ManagedPythonInstallations {
197200
) -> Result<impl DoubleEndedIterator<Item = ManagedPythonInstallation>, Error> {
198201
let platform_key = platform_key_from_env()?;
199202

200-
let iter = ManagedPythonInstallations::from_settings()?
203+
let iter = ManagedPythonInstallations::from_settings(None)?
201204
.find_all()?
202205
.filter(move |installation| {
203206
installation

crates/uv/src/commands/python/dir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use uv_python::managed::ManagedPythonInstallations;
77

88
/// Show the toolchain directory.
99
pub(crate) fn dir() -> anyhow::Result<()> {
10-
let installed_toolchains = ManagedPythonInstallations::from_settings()
10+
let installed_toolchains = ManagedPythonInstallations::from_settings(None)
1111
.context("Failed to initialize toolchain settings")?;
1212
println!(
1313
"{}",

crates/uv/src/commands/python/install.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,8 @@ pub(crate) async fn install(
3333
) -> Result<ExitStatus> {
3434
let start = std::time::Instant::now();
3535

36-
let installations = if let Some(install_dir) = install_dir {
37-
ManagedPythonInstallations::from_path(install_dir)
38-
} else {
39-
ManagedPythonInstallations::from_settings()?
40-
}
41-
.init()?;
36+
let installations =
37+
ManagedPythonInstallations::from_settings(install_dir.map(|p| p.to_path_buf()))?.init()?;
4238
let installations_dir = installations.root();
4339
let cache_dir = installations.cache();
4440
let _lock = installations.lock().await?;

crates/uv/src/commands/python/uninstall.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ pub(crate) async fn uninstall(
2424

2525
printer: Printer,
2626
) -> Result<ExitStatus> {
27-
let installations = if let Some(install_dir) = install_dir {
28-
ManagedPythonInstallations::from_path(install_dir)
29-
} else {
30-
ManagedPythonInstallations::from_settings()?.init()?
31-
};
27+
// need to convert install_dir to Option<PathBuf> to match the function signature
28+
let installations =
29+
ManagedPythonInstallations::from_settings(install_dir.map(|p| p.to_path_buf()))?.init()?;
3230

3331
let _lock = installations.lock().await?;
3432

crates/uv/tests/it/common/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ pub fn venv_to_interpreter(venv: &Path) -> PathBuf {
990990

991991
/// Get the path to the python interpreter for a specific python version.
992992
pub fn get_python(version: &PythonVersion) -> PathBuf {
993-
ManagedPythonInstallations::from_settings()
993+
ManagedPythonInstallations::from_settings(None)
994994
.map(|installed_pythons| {
995995
installed_pythons
996996
.find_version(version)

crates/uv/tests/it/help.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,11 @@ fn help_subsubcommand() {
427427
See `uv help python` to view supported request formats.
428428
429429
Options:
430+
-i, --install-dir <INSTALL_DIR>
431+
The directory where Python will be installed
432+
433+
[env: UV_PYTHON_INSTALL_DIR=]
434+
430435
-r, --reinstall
431436
Reinstall the requested Python version, if it's already installed.
432437
@@ -620,7 +625,7 @@ fn help_flag_subcommand() {
620625
fn help_flag_subsubcommand() {
621626
let context = TestContext::new_with_versions(&[]);
622627

623-
uv_snapshot!(context.filters(), context.command().arg("python").arg("install").arg("--help"), @r###"
628+
uv_snapshot!(context.filters(), context.command().arg("python").arg("install").arg("--help"), @r#"
624629
success: true
625630
exit_code: 0
626631
----- stdout -----
@@ -632,7 +637,9 @@ fn help_flag_subsubcommand() {
632637
[TARGETS]... The Python version(s) to install
633638
634639
Options:
635-
-r, --reinstall Reinstall the requested Python version, if it's already installed
640+
-i, --install-dir <INSTALL_DIR> The directory where Python will be installed [env:
641+
UV_PYTHON_INSTALL_DIR=]
642+
-r, --reinstall Reinstall the requested Python version, if it's already installed
636643
637644
Cache options:
638645
-n, --no-cache Avoid reading from or writing to the cache, instead using a temporary
@@ -665,7 +672,7 @@ fn help_flag_subsubcommand() {
665672
-V, --version Display the uv version
666673
667674
----- stderr -----
668-
"###);
675+
"#);
669676
}
670677

671678
#[test]

crates/uv/tests/it/pip_sync.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,18 @@ fn missing_venv() -> Result<()> {
5757
requirements.write_str("anyio")?;
5858
fs::remove_dir_all(&context.venv)?;
5959

60-
uv_snapshot!(context.filters(), context.pip_sync().arg("requirements.txt"), @r###"
61-
success: false
62-
exit_code: 2
60+
uv_snapshot!(context.filters(), context.pip_sync().arg("requirements.txt"), @r#"
61+
success: true
62+
exit_code: 0
6363
----- stdout -----
6464
6565
----- stderr -----
66-
error: No virtual environment found; run `uv venv` to create an environment, or pass `--system` to install into a non-virtual environment
67-
"###);
66+
Using Python 3.12.[X] environment at /home/dan/.venv
67+
Resolved 1 package in [TIME]
68+
Prepared 1 package in [TIME]
69+
Installed 1 package in [TIME]
70+
+ anyio==4.3.0
71+
"#);
6872

6973
assert!(predicates::path::missing().eval(&context.venv));
7074

0 commit comments

Comments
 (0)