Skip to content

Commit 1bb543e

Browse files
committed
Make preview Python registration on Windows non-fatal
1 parent bb1e9a2 commit 1bb543e

6 files changed

Lines changed: 45 additions & 13 deletions

File tree

crates/uv-cli/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4954,6 +4954,17 @@ pub struct PythonInstallArgs {
49544954
#[arg(long, overrides_with("bin"), conflicts_with("default"))]
49554955
pub no_bin: bool,
49564956

4957+
/// Register the Python installation in the Windows registry.
4958+
///
4959+
/// This is the default behavior on Windows. If this flag is provided explicitly, uv will error if the
4960+
/// registry entry cannot be created.
4961+
#[arg(long, overrides_with("no_registry"), hide = true)]
4962+
pub registry: bool,
4963+
4964+
/// Do not register the Python installation in the Windows registry.
4965+
#[arg(long, overrides_with("registry"))]
4966+
pub no_registry: bool,
4967+
49574968
/// The Python version(s) to install.
49584969
///
49594970
/// If not provided, the requested Python version(s) will be read from the `UV_PYTHON`

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ pub(crate) async fn install(
152152
reinstall: bool,
153153
upgrade: bool,
154154
bin: Option<bool>,
155+
registry: Option<bool>,
155156
force: bool,
156157
python_install_mirror: Option<String>,
157158
pypy_install_mirror: Option<String>,
@@ -500,7 +501,7 @@ pub(crate) async fn install(
500501
);
501502
}
502503

503-
if preview.is_enabled() {
504+
if preview.is_enabled() && !matches!(registry, Some(false)) {
504505
#[cfg(windows)]
505506
{
506507
match uv_python::windows_registry::create_registry_entry(installation) {
@@ -670,11 +671,14 @@ pub(crate) async fn install(
670671
}
671672

672673
if !errors.is_empty() {
673-
// If there are only bin install errors and the user didn't opt-in, we're only going to warn
674-
let fatal = errors
675-
.iter()
676-
.all(|(kind, _, _)| matches!(kind, InstallErrorKind::Bin))
677-
&& bin.is_none();
674+
// If there are only side-effect install errors and the user didn't opt-in, we're only going
675+
// to warn
676+
let fatal = !errors.iter().all(|(kind, _, _)| match kind {
677+
InstallErrorKind::Bin => bin.is_none(),
678+
#[cfg(windows)]
679+
InstallErrorKind::Registry => registry.is_none(),
680+
InstallErrorKind::DownloadUnpack => false,
681+
});
678682

679683
for (kind, key, err) in errors
680684
.into_iter()
@@ -691,10 +695,14 @@ pub(crate) async fn install(
691695
(level, "install executable for")
692696
}
693697
#[cfg(windows)]
694-
InstallErrorKind::Registry => (
695-
"error".red().bold().to_string(),
696-
"install registry entry for",
697-
),
698+
InstallErrorKind::Registry => {
699+
let level = match registry {
700+
None => "warning".yellow().bold().to_string(),
701+
Some(false) => continue,
702+
Some(true) => "error".red().bold().to_string(),
703+
};
704+
(level, "install registry entry for")
705+
}
698706
};
699707

700708
writeln!(
@@ -714,10 +722,8 @@ pub(crate) async fn install(
714722
}
715723

716724
if fatal {
717-
return Ok(ExitStatus::Success);
725+
return Ok(ExitStatus::Failure);
718726
}
719-
720-
return Ok(ExitStatus::Failure);
721727
}
722728

723729
Ok(ExitStatus::Success)

crates/uv/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
14031403
args.reinstall,
14041404
upgrade,
14051405
args.bin,
1406+
args.registry,
14061407
args.force,
14071408
args.python_install_mirror,
14081409
args.pypy_install_mirror,
@@ -1432,6 +1433,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
14321433
reinstall,
14331434
upgrade,
14341435
args.bin,
1436+
args.registry,
14351437
args.force,
14361438
args.python_install_mirror,
14371439
args.pypy_install_mirror,

crates/uv/src/settings.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,7 @@ pub(crate) struct PythonInstallSettings {
934934
pub(crate) reinstall: bool,
935935
pub(crate) force: bool,
936936
pub(crate) bin: Option<bool>,
937+
pub(crate) registry: Option<bool>,
937938
pub(crate) python_install_mirror: Option<String>,
938939
pub(crate) pypy_install_mirror: Option<String>,
939940
pub(crate) python_downloads_json_url: Option<String>,
@@ -964,6 +965,8 @@ impl PythonInstallSettings {
964965
reinstall,
965966
bin,
966967
no_bin,
968+
registry,
969+
no_registry,
967970
force,
968971
mirror: _,
969972
pypy_mirror: _,
@@ -977,6 +980,7 @@ impl PythonInstallSettings {
977980
reinstall,
978981
force,
979982
bin: flag(bin, no_bin, "bin"),
983+
registry: flag(registry, no_registry, "registry"),
980984
python_install_mirror: python_mirror,
981985
pypy_install_mirror: pypy_mirror,
982986
python_downloads_json_url,
@@ -992,6 +996,7 @@ pub(crate) struct PythonUpgradeSettings {
992996
pub(crate) install_dir: Option<PathBuf>,
993997
pub(crate) targets: Vec<String>,
994998
pub(crate) force: bool,
999+
pub(crate) registry: Option<bool>,
9951000
pub(crate) python_install_mirror: Option<String>,
9961001
pub(crate) pypy_install_mirror: Option<String>,
9971002
pub(crate) python_downloads_json_url: Option<String>,
@@ -1019,6 +1024,7 @@ impl PythonUpgradeSettings {
10191024
let force = false;
10201025
let default = false;
10211026
let bin = None;
1027+
let registry = None;
10221028

10231029
let PythonUpgradeArgs {
10241030
install_dir,
@@ -1032,6 +1038,7 @@ impl PythonUpgradeSettings {
10321038
install_dir,
10331039
targets,
10341040
force,
1041+
registry,
10351042
python_install_mirror: python_mirror,
10361043
pypy_install_mirror: pypy_mirror,
10371044
python_downloads_json_url,

crates/uv/tests/it/help.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ fn help_subsubcommand() {
507507
--no-bin
508508
Do not install a Python executable into the `bin` directory
509509
510+
--no-registry
511+
Do not register the Python installation in the Windows registry
512+
510513
--mirror <MIRROR>
511514
Set the URL to use as the source for downloading Python installations.
512515
@@ -795,6 +798,8 @@ fn help_flag_subsubcommand() {
795798
The directory to store the Python installation in [env: UV_PYTHON_INSTALL_DIR=]
796799
--no-bin
797800
Do not install a Python executable into the `bin` directory
801+
--no-registry
802+
Do not register the Python installation in the Windows registry
798803
--mirror <MIRROR>
799804
Set the URL to use as the source for downloading Python installations [env:
800805
UV_PYTHON_INSTALL_MIRROR=]

docs/reference/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,7 @@ uv python install [OPTIONS] [TARGETS]...
28042804
<p>May also be set with the <code>UV_NO_MANAGED_PYTHON</code> environment variable.</p></dd><dt id="uv-python-install--no-progress"><a href="#uv-python-install--no-progress"><code>--no-progress</code></a></dt><dd><p>Hide all progress outputs.</p>
28052805
<p>For example, spinners or progress bars.</p>
28062806
<p>May also be set with the <code>UV_NO_PROGRESS</code> environment variable.</p></dd><dt id="uv-python-install--no-python-downloads"><a href="#uv-python-install--no-python-downloads"><code>--no-python-downloads</code></a></dt><dd><p>Disable automatic downloads of Python.</p>
2807+
</dd><dt id="uv-python-install--no-registry"><a href="#uv-python-install--no-registry"><code>--no-registry</code></a></dt><dd><p>Do not register the Python installation in the Windows registry</p>
28072808
</dd><dt id="uv-python-install--offline"><a href="#uv-python-install--offline"><code>--offline</code></a></dt><dd><p>Disable network access.</p>
28082809
<p>When disabled, uv will only use locally cached data and locally available files.</p>
28092810
<p>May also be set with the <code>UV_OFFLINE</code> environment variable.</p></dd><dt id="uv-python-install--project"><a href="#uv-python-install--project"><code>--project</code></a> <i>project</i></dt><dd><p>Run the command within the given project directory.</p>

0 commit comments

Comments
 (0)