diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index b13161174b678..f70f0a14d685f 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -120,11 +120,13 @@ pub struct GlobalArgs { )] pub python_preference: Option, - /// Allow automatically downloading Python when required. + #[allow(clippy::doc_markdown)] + /// Allow automatically downloading Python when required. [env: "UV_PYTHON_DOWNLOADS=auto"] #[arg(global = true, long, help_heading = "Python options", hide = true)] pub allow_python_downloads: bool, - /// Disable automatic downloads of Python. + #[allow(clippy::doc_markdown)] + /// Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] #[arg(global = true, long, help_heading = "Python options")] pub no_python_downloads: bool, diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index 8a9552f27fbef..ae36283a97423 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -89,6 +89,19 @@ pub enum PythonDownloads { Never, } +impl FromStr for PythonDownloads { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_ascii_lowercase().as_str() { + "auto" | "automatic" | "true" | "1" => Ok(PythonDownloads::Automatic), + "manual" => Ok(PythonDownloads::Manual), + "never" | "false" | "0" => Ok(PythonDownloads::Never), + _ => Err(format!("Invalid value for `python-download`: '{s}'")), + } + } +} + impl From for PythonDownloads { fn from(value: bool) -> Self { if value { diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index fcbb3895c3502..b119a19d56a95 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -117,6 +117,7 @@ impl GlobalSettings { .unwrap_or_else(PythonPreference::default_from_env), python_downloads: flag(args.allow_python_downloads, args.no_python_downloads) .map(PythonDownloads::from) + .combine(env(env::UV_PYTHON_DOWNLOADS)) .combine(workspace.and_then(|workspace| workspace.globals.python_downloads)) .unwrap_or_default(), no_progress: args.no_progress, @@ -2174,6 +2175,11 @@ mod env { pub(super) const CONCURRENT_INSTALLS: (&str, &str) = ("UV_CONCURRENT_INSTALLS", "a non-zero integer"); + + pub(super) const UV_PYTHON_DOWNLOADS: (&str, &str) = ( + "UV_PYTHON_DOWNLOADS", + "one of 'auto', 'true', 'manual', 'never', or 'false'", + ); } /// Attempt to load and parse an environment variable with the given name. diff --git a/crates/uv/tests/help.rs b/crates/uv/tests/help.rs index 8e7fa6f727b7b..29d665c74149b 100644 --- a/crates/uv/tests/help.rs +++ b/crates/uv/tests/help.rs @@ -42,7 +42,7 @@ fn help() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -104,7 +104,7 @@ fn help_flag() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -165,7 +165,7 @@ fn help_short_flag() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -286,7 +286,7 @@ fn help_subcommand() { installations --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet @@ -435,7 +435,7 @@ fn help_subsubcommand() { installations --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet @@ -538,7 +538,7 @@ fn help_flag_subcommand() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -590,7 +590,7 @@ fn help_flag_subsubcommand() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -722,7 +722,7 @@ fn help_with_global_option() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output @@ -821,7 +821,7 @@ fn help_with_no_pager() { Whether to prefer uv-managed or system Python installations [env: UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system, only-system] --no-python-downloads - Disable automatic downloads of Python + Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet Do not print any output diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index 37c07d5aabe26..43316b2a7acc3 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -58,6 +58,9 @@ uv accepts the following command-line arguments as environment variables: exclude distributions published after the specified date. - `UV_PYTHON_PREFERENCE`: Equivalent to the `--python-preference` command-line argument. Whether uv should prefer system or managed Python versions. +- `UV_PYTHON_DOWNLOADS`: Equivalent to the + [`python-downloads`](../reference/settings.md#python-downloads) setting and, when disabled, the + `--no-python-downloads` option. Whether uv should allow Python downloads. In each case, the corresponding command-line argument takes precedence over an environment variable. diff --git a/docs/reference/cli.md b/docs/reference/cli.md index e377ee147b023..4ca9cfaecc0dd 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -235,7 +235,7 @@ uv run [OPTIONS]

If a virtual environment is active or found in a current or parent directory, it will be used as if there was no project or workspace.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -406,7 +406,7 @@ uv init [OPTIONS] [PATH]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-readme

Do not create a README.md file

@@ -634,7 +634,7 @@ uv add [OPTIONS] >

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -908,7 +908,7 @@ uv remove [OPTIONS] ...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -1174,7 +1174,7 @@ uv sync [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -1412,7 +1412,7 @@ uv lock [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -1645,7 +1645,7 @@ uv tree [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -1966,7 +1966,7 @@ uv tool run [OPTIONS] [COMMAND]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -2206,7 +2206,7 @@ uv tool install [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -2444,7 +2444,7 @@ uv tool upgrade [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -2639,7 +2639,7 @@ uv tool uninstall [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -2726,7 +2726,7 @@ uv tool update-shell [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -2831,7 +2831,7 @@ uv tool dir [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -2997,7 +2997,7 @@ uv python list [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -3102,7 +3102,7 @@ uv python install [OPTIONS] [TARGETS]...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -3203,7 +3203,7 @@ uv python find [OPTIONS] [REQUEST]

Otherwise, when no request is provided, the Python requirement of a project in the current directory or parent directories will be used.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -3298,7 +3298,7 @@ uv python pin [OPTIONS] [REQUEST]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-workspace

Avoid validating the Python pin is compatible with the workspace.

@@ -3393,7 +3393,7 @@ uv python dir [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -3484,7 +3484,7 @@ uv python uninstall [OPTIONS] ...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -3745,7 +3745,7 @@ uv pip compile [OPTIONS] ...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -4072,7 +4072,7 @@ uv pip sync [OPTIONS] ...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -4379,7 +4379,7 @@ uv pip install [OPTIONS] |--editable For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-sources

Ignore the tool.uv.sources table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources

@@ -4626,7 +4626,7 @@ uv pip uninstall [OPTIONS] >

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -4727,7 +4727,7 @@ uv pip freeze [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -4840,7 +4840,7 @@ uv pip list [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -4941,7 +4941,7 @@ uv pip show [OPTIONS] [PACKAGE]...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5043,7 +5043,7 @@ uv pip tree [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--no-system
--offline

Disable network access.

@@ -5144,7 +5144,7 @@ uv pip check [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5322,7 +5322,7 @@ uv venv [OPTIONS] [NAME]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5457,7 +5457,7 @@ uv cache clean [OPTIONS] [PACKAGE]...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5544,7 +5544,7 @@ uv cache prune [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5633,7 +5633,7 @@ uv cache dir [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5714,7 +5714,7 @@ uv version [OPTIONS]

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.

@@ -5819,7 +5819,7 @@ uv help [OPTIONS] [COMMAND]...

For example, spinners or progress bars.

-
--no-python-downloads

Disable automatic downloads of Python

+
--no-python-downloads

Disable automatic downloads of Python. [env: "UVPYTHONDOWNLOADS=never"]

--offline

Disable network access.