From 323aa8f3324a2faaf286ad3a6bb84113c2d69e52 Mon Sep 17 00:00:00 2001 From: samypr100 <3933065+samypr100@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:11:28 -0400 Subject: [PATCH] =?UTF-8?q?chore(=F0=9F=A7=B9):=20cleanup=20env=20var=20us?= =?UTF-8?q?age=20(#15247)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Split the cleanup fixes from https://github.com/astral-sh/uv/pull/15196 into a separate PR for easier review. This cleans up some minor env var usage / references throughout tests and runtime code. ## Test Plan Existing Tests. No functional changes. --- crates/uv-installer/src/compile.rs | 2 +- crates/uv-static/src/env_vars.rs | 28 +++++++++++++++++++ crates/uv/src/commands/pip/compile.rs | 3 +- crates/uv/tests/it/build.rs | 5 ++-- crates/uv/tests/it/edit.rs | 10 +++---- crates/uv/tests/it/export.rs | 4 +-- crates/uv/tests/it/lock.rs | 8 +++--- crates/uv/tests/it/pip_compile.rs | 10 +++---- crates/uv/tests/it/pip_install.rs | 24 ++++++++-------- crates/uv/tests/it/pip_sync.rs | 2 +- crates/uv/tests/it/python_install.rs | 20 +++++++------- crates/uv/tests/it/python_list.rs | 14 +++++----- crates/uv/tests/it/python_pin.rs | 3 +- crates/uv/tests/it/run.rs | 6 ++-- crates/uv/tests/it/show_settings.rs | 2 +- crates/uv/tests/it/sync.rs | 40 +++++++++++++-------------- crates/uv/tests/it/tool_install.rs | 30 ++++++++++---------- crates/uv/tests/it/tool_upgrade.rs | 12 ++++---- docs/reference/environment.md | 13 +++++++++ 19 files changed, 140 insertions(+), 96 deletions(-) diff --git a/crates/uv-installer/src/compile.rs b/crates/uv-installer/src/compile.rs index 8704d9542..0bde5c342 100644 --- a/crates/uv-installer/src/compile.rs +++ b/crates/uv-installer/src/compile.rs @@ -97,7 +97,7 @@ pub async fn compile_tree( Ok(duration) => Some(duration), Err(_) => { return Err(CompileError::EnvironmentError { - var: "UV_COMPILE_BYTECODE_TIMEOUT", + var: EnvVars::UV_COMPILE_BYTECODE_TIMEOUT, message: format!("Expected an integer number of seconds, got \"{value}\""), }); } diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs index d2a42e46f..42bb7c554 100644 --- a/crates/uv-static/src/env_vars.rs +++ b/crates/uv-static/src/env_vars.rs @@ -562,6 +562,10 @@ impl EnvVars { #[attr_hidden] pub const GIT_ALLOW_PROTOCOL: &'static str = "GIT_ALLOW_PROTOCOL"; + /// Sets the SSH command used when Git tries to establish a connection using SSH. + #[attr_hidden] + pub const GIT_SSH_COMMAND: &'static str = "GIT_SSH_COMMAND"; + /// Disable interactive git prompts in terminals, e.g., for credentials. Does not disable /// GUI prompts. #[attr_hidden] @@ -642,6 +646,18 @@ impl EnvVars { /// for more. pub const RUST_LOG: &'static str = "RUST_LOG"; + /// If set, it can be used to display more stack trace details when a panic occurs. + /// This is used by uv particularly on windows to show more details during a platform exception. + /// + /// For example: + /// + /// * `RUST_BACKTRACE=1` will print a short backtrace. + /// * `RUST_BACKTRACE=full` will print a full backtrace. + /// + /// See the [Rust backtrace documentation](https://doc.rust-lang.org/std/backtrace/index.html) + /// for more. + pub const RUST_BACKTRACE: &'static str = "RUST_BACKTRACE"; + /// Add additional context and structure to log messages. /// /// If logging is not enabled, e.g., with `RUST_LOG` or `-v`, this has no effect. @@ -702,6 +718,10 @@ impl EnvVars { #[attr_hidden] pub const ROOT_PATH: &'static str = "ROOT_PATH"; + /// Used in testing extra build dependencies. + #[attr_hidden] + pub const EXPECTED_ANYIO_VERSION: &'static str = "EXPECTED_ANYIO_VERSION"; + /// Used to set test credentials for keyring tests. #[attr_hidden] pub const KEYRING_TEST_CREDENTIALS: &'static str = "KEYRING_TEST_CREDENTIALS"; @@ -717,6 +737,14 @@ impl EnvVars { #[attr_hidden] pub const UV_TEST_INDEX_URL: &'static str = "UV_TEST_INDEX_URL"; + /// Used for testing named indexes in tests. + #[attr_hidden] + pub const UV_INDEX_MY_INDEX_USERNAME: &'static str = "UV_INDEX_MY_INDEX_USERNAME"; + + /// Used for testing named indexes in tests. + #[attr_hidden] + pub const UV_INDEX_MY_INDEX_PASSWORD: &'static str = "UV_INDEX_MY_INDEX_PASSWORD"; + /// Used to set the GitHub fast-path url for tests. #[attr_hidden] pub const UV_GITHUB_FAST_PATH_URL: &'static str = "UV_GITHUB_FAST_PATH_URL"; diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index 56261cbe7..241d0aea3 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -44,6 +44,7 @@ use uv_resolver::{ InMemoryIndex, OptionsBuilder, PrereleaseMode, PylockToml, PythonRequirement, ResolutionMode, ResolverEnvironment, }; +use uv_static::EnvVars; use uv_torch::{TorchMode, TorchStrategy}; use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy}; use uv_warnings::{warn_user, warn_user_once}; @@ -166,7 +167,7 @@ pub(crate) async fn pip_compile( // Respect `UV_PYTHON` if python.is_none() && python_version.is_none() { - if let Ok(request) = std::env::var("UV_PYTHON") { + if let Ok(request) = std::env::var(EnvVars::UV_PYTHON) { if !request.is_empty() { python = Some(request); } diff --git a/crates/uv/tests/it/build.rs b/crates/uv/tests/it/build.rs index 1956e8b85..b4e860329 100644 --- a/crates/uv/tests/it/build.rs +++ b/crates/uv/tests/it/build.rs @@ -7,6 +7,7 @@ use indoc::indoc; use insta::assert_snapshot; use predicates::prelude::predicate; use std::env::current_dir; +use uv_static::EnvVars; use zip::ZipArchive; #[test] @@ -1997,7 +1998,7 @@ fn force_pep517() -> Result<()> { build-backend = "uv_build" "#})?; - uv_snapshot!(context.filters(), context.build().env("RUST_BACKTRACE", "0"), @r" + uv_snapshot!(context.filters(), context.build().env(EnvVars::RUST_BACKTRACE, "0"), @r" success: false exit_code: 2 ----- stdout ----- @@ -2008,7 +2009,7 @@ fn force_pep517() -> Result<()> { ╰─▶ Expected a Python module at: `src/does_not_exist/__init__.py` "); - uv_snapshot!(context.filters(), context.build().arg("--force-pep517").env("RUST_BACKTRACE", "0"), @r" + uv_snapshot!(context.filters(), context.build().arg("--force-pep517").env(EnvVars::RUST_BACKTRACE, "0"), @r" success: false exit_code: 2 ----- stdout ----- diff --git a/crates/uv/tests/it/edit.rs b/crates/uv/tests/it/edit.rs index ca7dd0a5e..78f2dd602 100644 --- a/crates/uv/tests/it/edit.rs +++ b/crates/uv/tests/it/edit.rs @@ -519,7 +519,7 @@ async fn add_git_private_rate_limited_by_github_rest_api_403_response() -> Resul uv_snapshot!(context.filters(), context .add() .arg(format!("uv-private-pypackage @ git+https://{token}@github.com/astral-test/uv-private-pypackage")) - .env("UV_GITHUB_FAST_PATH_URL", server.uri()), @r" + .env(EnvVars::UV_GITHUB_FAST_PATH_URL, server.uri()), @r" success: true exit_code: 0 ----- stdout ----- @@ -12336,8 +12336,8 @@ fn add_auth_policy_always_with_credentials() -> Result<()> { })?; uv_snapshot!(context.add().arg("anyio") - .env("UV_INDEX_MY_INDEX_USERNAME", "public") - .env("UV_INDEX_MY_INDEX_PASSWORD", "heron"), @r" + .env(EnvVars::UV_INDEX_MY_INDEX_USERNAME, "public") + .env(EnvVars::UV_INDEX_MY_INDEX_PASSWORD, "heron"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12496,8 +12496,8 @@ fn add_auth_policy_never_with_env_var_credentials() -> Result<()> { })?; uv_snapshot!(context.add().arg("anyio") - .env("UV_INDEX_MY_INDEX_USERNAME", "public") - .env("UV_INDEX_MY_INDEX_PASSWORD", "heron"), @r" + .env(EnvVars::UV_INDEX_MY_INDEX_USERNAME, "public") + .env(EnvVars::UV_INDEX_MY_INDEX_PASSWORD, "heron"), @r" success: false exit_code: 1 ----- stdout ----- diff --git a/crates/uv/tests/it/export.rs b/crates/uv/tests/it/export.rs index c109f016f..c8a2f7cc7 100644 --- a/crates/uv/tests/it/export.rs +++ b/crates/uv/tests/it/export.rs @@ -1253,7 +1253,7 @@ fn requirements_txt_ssh_git_username() -> Result<()> { "", )); filters.push(("failed to clone into: .*", "failed to clone into: [PATH]")); - uv_snapshot!(filters, context.export().env("GIT_SSH_COMMAND", failing_git_ssh_command), @r#" + uv_snapshot!(filters, context.export().env(EnvVars::GIT_SSH_COMMAND, failing_git_ssh_command), @r#" success: false exit_code: 1 ----- stdout ----- @@ -1284,7 +1284,7 @@ fn requirements_txt_ssh_git_username() -> Result<()> { ssh_deploy_key.portable_display() ); - uv_snapshot!(context.filters(), context.export().env("GIT_SSH_COMMAND", git_ssh_command), @r" + uv_snapshot!(context.filters(), context.export().env(EnvVars::GIT_SSH_COMMAND, git_ssh_command), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index c85f7e673..4117d05c2 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -8937,8 +8937,8 @@ fn lock_index_workspace_member() -> Result<()> { "); uv_snapshot!(context.filters(), context.lock() - .env("UV_INDEX_MY_INDEX_USERNAME", "public") - .env("UV_INDEX_MY_INDEX_PASSWORD", "heron"), @r" + .env(EnvVars::UV_INDEX_MY_INDEX_USERNAME, "public") + .env(EnvVars::UV_INDEX_MY_INDEX_PASSWORD, "heron"), @r" success: true exit_code: 0 ----- stdout ----- @@ -9003,8 +9003,8 @@ fn lock_index_workspace_member() -> Result<()> { // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock() - .env("UV_INDEX_MY_INDEX_USERNAME", "public") - .env("UV_INDEX_MY_INDEX_PASSWORD", "heron") + .env(EnvVars::UV_INDEX_MY_INDEX_USERNAME, "public") + .env(EnvVars::UV_INDEX_MY_INDEX_PASSWORD, "heron") .arg("--locked"), @r###" success: true exit_code: 0 diff --git a/crates/uv/tests/it/pip_compile.rs b/crates/uv/tests/it/pip_compile.rs index 2971930ca..345ea3c70 100644 --- a/crates/uv/tests/it/pip_compile.rs +++ b/crates/uv/tests/it/pip_compile.rs @@ -1372,7 +1372,7 @@ fn compile_python_312() -> Result<()> { // And `UV_PYTHON` uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") - .env("UV_PYTHON", "3.12"), @r###" + .env(EnvVars::UV_PYTHON, "3.12"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1614,7 +1614,7 @@ fn compile_python_conflicts() -> Result<()> { .arg("requirements.in") .arg("-p") .arg("3.12") - .env("UV_PYTHON", "3.11"), @r###" + .env(EnvVars::UV_PYTHON, "3.11"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1643,7 +1643,7 @@ fn compile_python_conflicts() -> Result<()> { .arg("requirements.in") .arg("--python") .arg("3.12") - .env("UV_PYTHON", "3.11"), @r###" + .env(EnvVars::UV_PYTHON, "3.11"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1672,7 +1672,7 @@ fn compile_python_conflicts() -> Result<()> { .arg("requirements.in") .arg("--python-version") .arg("3.12") - .env("UV_PYTHON", "3.11"), @r###" + .env(EnvVars::UV_PYTHON, "3.11"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1892,7 +1892,7 @@ fn compile_fallback_interpreter_broken_in_path() -> Result<()> { .arg("--python-version") .arg("3.12") // In tests, we ignore `PATH` during Python discovery so we need to add the context `bin` - .env("UV_TEST_PYTHON_PATH", context.bin_dir.as_os_str()), @r###" + .env(EnvVars::UV_TEST_PYTHON_PATH, context.bin_dir.as_os_str()), @r###" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index d3c9d4e9f..1ac8eb22e 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -2101,7 +2101,7 @@ async fn install_git_public_rate_limited_by_github_rest_api_403_response() { uv_snapshot!(context.filters(), context .pip_install() .arg("uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage") - .env("UV_GITHUB_FAST_PATH_URL", server.uri()), @r" + .env(EnvVars::UV_GITHUB_FAST_PATH_URL, server.uri()), @r" success: true exit_code: 0 ----- stdout ----- @@ -2636,7 +2636,7 @@ fn install_no_binary_env() { let context = TestContext::new("3.12"); let mut command = context.pip_install(); - command.arg("anyio").env("UV_NO_BINARY", "1"); + command.arg("anyio").env(EnvVars::UV_NO_BINARY, "1"); uv_snapshot!( command, @r###" @@ -2658,7 +2658,7 @@ fn install_no_binary_env() { command .arg("anyio") .arg("--reinstall") - .env("UV_NO_BINARY", "anyio"); + .env(EnvVars::UV_NO_BINARY, "anyio"); uv_snapshot!( command, @r###" @@ -2684,7 +2684,7 @@ fn install_no_binary_env() { .arg("anyio") .arg("--reinstall") .arg("idna") - .env("UV_NO_BINARY_PACKAGE", "idna"); + .env(EnvVars::UV_NO_BINARY_PACKAGE, "idna"); uv_snapshot!( command, @r###" @@ -8352,7 +8352,7 @@ fn install_incompatible_python_version_interpreter_broken_in_path() -> Result<() .arg("-p").arg("3.12") .arg("anyio") // In tests, we ignore `PATH` during Python discovery so we need to add the context `bin` - .env("UV_TEST_PYTHON_PATH", path.as_os_str()), @r###" + .env(EnvVars::UV_TEST_PYTHON_PATH, path.as_os_str()), @r###" success: false exit_code: 2 ----- stdout ----- @@ -8379,7 +8379,7 @@ fn install_incompatible_python_version_interpreter_broken_in_path() -> Result<() .arg("-p").arg("3.12") .arg("anyio") // In tests, we ignore `PATH` during Python discovery so we need to add the context `bin` - .env("UV_TEST_PYTHON_PATH", path.as_os_str()), @r###" + .env(EnvVars::UV_TEST_PYTHON_PATH, path.as_os_str()), @r###" success: false exit_code: 2 ----- stdout ----- @@ -11955,7 +11955,7 @@ fn install_python_preference() { // This also works with `VIRTUAL_ENV` unset uv_snapshot!(context.filters(), context.pip_install() - .arg("anyio").arg("--no-managed-python").env_remove("VIRTUAL_ENV"), @r" + .arg("anyio").arg("--no-managed-python").env_remove(EnvVars::VIRTUAL_ENV), @r" success: true exit_code: 0 ----- stdout ----- @@ -12329,7 +12329,7 @@ fn pip_install_build_dependencies_respect_locked_versions() -> Result<()> { "#})?; // Ensure our build backend is checking the version correctly - uv_snapshot!(context.filters(), context.pip_install().arg(".").env("EXPECTED_ANYIO_VERSION", "3.0"), @r" + uv_snapshot!(context.filters(), context.pip_install().arg(".").env(EnvVars::EXPECTED_ANYIO_VERSION, "3.0"), @r" success: false exit_code: 1 ----- stdout ----- @@ -12363,7 +12363,7 @@ fn pip_install_build_dependencies_respect_locked_versions() -> Result<()> { "#})?; // The child should be built with anyio 4.0 - uv_snapshot!(context.filters(), context.pip_install().arg(".").env("EXPECTED_ANYIO_VERSION", "4.0"), @r" + uv_snapshot!(context.filters(), context.pip_install().arg(".").env(EnvVars::EXPECTED_ANYIO_VERSION, "4.0"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12397,7 +12397,7 @@ fn pip_install_build_dependencies_respect_locked_versions() -> Result<()> { // The child should be rebuilt with anyio 3.7, without `--reinstall` uv_snapshot!(context.filters(), context.pip_install().arg(".") - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "4.0"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "4.0"), @r" success: false exit_code: 1 ----- stdout ----- @@ -12417,7 +12417,7 @@ fn pip_install_build_dependencies_respect_locked_versions() -> Result<()> { "); uv_snapshot!(context.filters(), context.pip_install().arg(".") - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "3.7"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "3.7"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12438,7 +12438,7 @@ fn pip_install_build_dependencies_respect_locked_versions() -> Result<()> { uv_snapshot!(context.filters(), context.pip_install().arg(".") .arg("--preview-features").arg("extra-build-dependencies") .arg("--reinstall-package").arg("child") - .env("EXPECTED_ANYIO_VERSION", "3.7"), @r" + .env(EnvVars::EXPECTED_ANYIO_VERSION, "3.7"), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/pip_sync.rs b/crates/uv/tests/it/pip_sync.rs index 5278d5f6c..3c4bd8243 100644 --- a/crates/uv/tests/it/pip_sync.rs +++ b/crates/uv/tests/it/pip_sync.rs @@ -56,7 +56,7 @@ fn missing_venv() -> Result<()> { assert!(predicates::path::missing().eval(&context.venv)); // If not "active", we hint to create one - uv_snapshot!(context.filters(), context.pip_sync().arg("requirements.txt").env_remove("VIRTUAL_ENV"), @r###" + uv_snapshot!(context.filters(), context.pip_sync().arg("requirements.txt").env_remove(EnvVars::VIRTUAL_ENV), @r###" success: false exit_code: 2 ----- stdout ----- diff --git a/crates/uv/tests/it/python_install.rs b/crates/uv/tests/it/python_install.rs index e9ea92f3b..670bd738b 100644 --- a/crates/uv/tests/it/python_install.rs +++ b/crates/uv/tests/it/python_install.rs @@ -238,7 +238,7 @@ fn python_install_automatic() { // With downloads disabled, the automatic install should fail uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("--no-python-downloads") .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r" success: false @@ -253,7 +253,7 @@ fn python_install_automatic() { // Otherwise, we should fetch the latest Python version uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r###" success: true exit_code: 0 @@ -265,7 +265,7 @@ fn python_install_automatic() { // Subsequently, we can use the interpreter even with downloads disabled uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("--no-python-downloads") .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r###" success: true @@ -278,7 +278,7 @@ fn python_install_automatic() { // We should respect the Python request uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("-p").arg("3.12") .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r###" success: true @@ -291,7 +291,7 @@ fn python_install_automatic() { // But some requests cannot be mapped to a download uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("-p").arg("foobar") .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r###" success: false @@ -322,9 +322,9 @@ fn python_install_automatic() { // We should ignore the broken executable and download a version still uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) // In tests, we ignore `PATH` during Python discovery so we need to add the context `bin` - .env("UV_TEST_PYTHON_PATH", context.bin_dir.as_os_str()) + .env(EnvVars::UV_TEST_PYTHON_PATH, context.bin_dir.as_os_str()) .arg("-p").arg("3.11") .arg("python").arg("-c").arg("import sys; print(sys.version_info[:2])"), @r###" success: true @@ -361,7 +361,7 @@ fn regression_cpython() { // We should respect the Python request uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") + .env_remove(EnvVars::VIRTUAL_ENV) .arg("-p").arg("3.12") .arg("mre.py"), @r###" success: true @@ -2156,7 +2156,7 @@ fn python_install_314() { #[test] fn python_install_cached() { // Skip this test if the developer has set `UV_PYTHON_CACHE_DIR` locally since it's slow - if env::var_os("UV_PYTHON_CACHE_DIR").is_some() && env::var_os("CI").is_none() { + if env::var_os(EnvVars::UV_PYTHON_CACHE_DIR).is_some() && env::var_os(EnvVars::CI).is_none() { debug!("Skipping test because `UV_PYTHON_CACHE_DIR` is set"); return; } @@ -2250,7 +2250,7 @@ fn python_install_cached() { #[test] fn python_install_no_cache() { // Skip this test if the developer has set `UV_PYTHON_CACHE_DIR` locally since it's slow - if env::var_os("UV_PYTHON_CACHE_DIR").is_some() && env::var_os("CI").is_none() { + if env::var_os(EnvVars::UV_PYTHON_CACHE_DIR).is_some() && env::var_os(EnvVars::CI).is_none() { debug!("Skipping test because `UV_PYTHON_CACHE_DIR` is set"); return; } diff --git a/crates/uv/tests/it/python_list.rs b/crates/uv/tests/it/python_list.rs index 5c23a3e93..f1b249b35 100644 --- a/crates/uv/tests/it/python_list.rs +++ b/crates/uv/tests/it/python_list.rs @@ -361,7 +361,7 @@ fn python_list_downloads() { // Instead, we choose a Python version where our available distributions are stable // Test the default display, which requires reverting the test context disabling Python downloads - uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -373,7 +373,7 @@ fn python_list_downloads() { "); // Show patch versions - uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--all-versions").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--all-versions").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -419,7 +419,7 @@ fn python_list_downloads_installed() { // Instead, we choose a Python version where our available distributions are stable // First, the download is shown as available - uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -434,7 +434,7 @@ fn python_list_downloads_installed() { // the URL // But not if `--only-installed` is used - uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--only-installed").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--only-installed").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -446,7 +446,7 @@ fn python_list_downloads_installed() { context.python_install().arg("3.10").assert().success(); // Then, it should be listed as installed instead of available - uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -458,7 +458,7 @@ fn python_list_downloads_installed() { "); // But, the display should be reverted if `--only-downloads` is used - uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--only-downloads").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--only-downloads").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- @@ -470,7 +470,7 @@ fn python_list_downloads_installed() { "); // And should not be shown if `--no-managed-python` is used - uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--no-managed-python").env_remove("UV_PYTHON_DOWNLOADS"), @r" + uv_snapshot!(context.filters(), context.python_list().arg("3.10").arg("--no-managed-python").env_remove(EnvVars::UV_PYTHON_DOWNLOADS), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/python_pin.rs b/crates/uv/tests/it/python_pin.rs index 0f01a0011..b2c548b16 100644 --- a/crates/uv/tests/it/python_pin.rs +++ b/crates/uv/tests/it/python_pin.rs @@ -7,6 +7,7 @@ use assert_fs::fixture::{FileWriteStr, PathChild, PathCreateDir}; use insta::assert_snapshot; use uv_platform::{Arch, Os}; use uv_python::{PYTHON_VERSION_FILENAME, PYTHON_VERSIONS_FILENAME}; +use uv_static::EnvVars; #[test] fn python_pin() { @@ -822,7 +823,7 @@ fn python_pin_install() { warning: No interpreter found for Python 3.12 in [PYTHON SOURCES] "); - uv_snapshot!(context.filters(), context.python_pin().arg("3.12").env("UV_PYTHON_DOWNLOADS", "auto"), @r" + uv_snapshot!(context.filters(), context.python_pin().arg("3.12").env(EnvVars::UV_PYTHON_DOWNLOADS, "auto"), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/run.rs b/crates/uv/tests/it/run.rs index b883a8ada..c519bef5e 100644 --- a/crates/uv/tests/it/run.rs +++ b/crates/uv/tests/it/run.rs @@ -4105,7 +4105,7 @@ fn run_linked_environment_path() -> Result<()> { // `sys.prefix` and `sys.executable` should be from the `target` directory uv_snapshot!(context.filters(), context.run() - .env_remove("VIRTUAL_ENV") // Ignore the test context's active virtual environment + .env_remove(EnvVars::VIRTUAL_ENV) // Ignore the test context's active virtual environment .env(EnvVars::UV_PROJECT_ENVIRONMENT, "target") .arg("python").arg("-c").arg("import sys; print(sys.prefix); print(sys.executable)"), @r" success: true @@ -5447,7 +5447,7 @@ fn detect_infinite_recursion() -> Result<()> { context.add_shared_env(&mut cmd, false); // Set the max recursion depth to a lower amount to speed up testing. - cmd.env("UV_RUN_MAX_RECURSION_DEPTH", "5"); + cmd.env(EnvVars::UV_RUN_MAX_RECURSION_DEPTH, "5"); uv_snapshot!(context.filters(), cmd, @r###" success: false @@ -5949,7 +5949,7 @@ fn run_python_preference_no_project() { "); // If we remove the `VIRTUAL_ENV` variable, we should get the unmanaged Python - uv_snapshot!(context.filters(), context.run().arg("--no-managed-python").arg("python").arg("--version").env_remove("VIRTUAL_ENV"), @r" + uv_snapshot!(context.filters(), context.run().arg("--no-managed-python").arg("python").arg("--version").env_remove(EnvVars::VIRTUAL_ENV), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/show_settings.rs b/crates/uv/tests/it/show_settings.rs index 92fcc829f..0af0db387 100644 --- a/crates/uv/tests/it/show_settings.rs +++ b/crates/uv/tests/it/show_settings.rs @@ -4355,7 +4355,7 @@ fn valid_conflicts() -> anyhow::Result<()> { ] "#})?; uv_snapshot!(context.filters(), add_shared_args(context.lock(), context.temp_dir.path()) - .env("XDG_CONFIG_HOME", xdg.path()), @r###" + .env(EnvVars::XDG_CONFIG_HOME, xdg.path()), @r###" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index b2ff3a16a..c63bc154f 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -2154,7 +2154,7 @@ fn sync_extra_build_dependencies_index() -> Result<()> { "#})?; // Ensure our build backend is checking the version correctly - uv_snapshot!(context.filters(), context.sync().env("EXPECTED_ANYIO_VERSION", "3.0"), @r" + uv_snapshot!(context.filters(), context.sync().env(EnvVars::EXPECTED_ANYIO_VERSION, "3.0"), @r" success: false exit_code: 1 ----- stdout ----- @@ -2173,7 +2173,7 @@ fn sync_extra_build_dependencies_index() -> Result<()> { "); // Ensure that we're resolving to `4.3.0`, the "latest" on PyPI. - uv_snapshot!(context.filters(), context.sync().env("EXPECTED_ANYIO_VERSION", "4.3"), @r" + uv_snapshot!(context.filters(), context.sync().env(EnvVars::EXPECTED_ANYIO_VERSION, "4.3"), @r" success: true exit_code: 0 ----- stdout ----- @@ -2208,7 +2208,7 @@ fn sync_extra_build_dependencies_index() -> Result<()> { // The child should be rebuilt with `3.5` on reinstall, the "latest" on Test PyPI. uv_snapshot!(context.filters(), context.sync() - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "4.3"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "4.3"), @r" success: false exit_code: 1 ----- stdout ----- @@ -2228,7 +2228,7 @@ fn sync_extra_build_dependencies_index() -> Result<()> { "); uv_snapshot!(context.filters(), context.sync() - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "3.5"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "3.5"), @r" success: true exit_code: 0 ----- stdout ----- @@ -6549,7 +6549,7 @@ fn no_binary() -> Result<()> { ~ iniconfig==2.0.0 "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY_PACKAGE", "iniconfig"), @r" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BINARY_PACKAGE, "iniconfig"), @r" success: true exit_code: 0 ----- stdout ----- @@ -6562,7 +6562,7 @@ fn no_binary() -> Result<()> { ~ iniconfig==2.0.0 "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "1"), @r" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BINARY, "1"), @r" success: true exit_code: 0 ----- stdout ----- @@ -6575,7 +6575,7 @@ fn no_binary() -> Result<()> { ~ iniconfig==2.0.0 "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "iniconfig"), @r###" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BINARY, "iniconfig"), @r###" success: false exit_code: 2 ----- stdout ----- @@ -6652,7 +6652,7 @@ fn no_build() -> Result<()> { assert!(context.temp_dir.child("uv.lock").exists()); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD_PACKAGE", "iniconfig"), @r" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BUILD_PACKAGE, "iniconfig"), @r" success: true exit_code: 0 ----- stdout ----- @@ -6705,7 +6705,7 @@ fn no_build_error() -> Result<()> { error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD", "1"), @r" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BUILD, "1"), @r" success: false exit_code: 2 ----- stdout ----- @@ -6715,7 +6715,7 @@ fn no_build_error() -> Result<()> { error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD_PACKAGE", "django-allauth"), @r" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BUILD_PACKAGE, "django-allauth"), @r" success: false exit_code: 2 ----- stdout ----- @@ -6725,7 +6725,7 @@ fn no_build_error() -> Result<()> { error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution "); - uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD", "django-allauth"), @r###" + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env(EnvVars::UV_NO_BUILD, "django-allauth"), @r###" success: false exit_code: 2 ----- stdout ----- @@ -11518,7 +11518,7 @@ fn sync_required_environment_hint() -> Result<()> { packse_index_url() })?; - uv_snapshot!(context.filters(), context.lock().env_remove("UV_EXCLUDE_NEWER"), @r" + uv_snapshot!(context.filters(), context.lock().env_remove(EnvVars::UV_EXCLUDE_NEWER), @r" success: true exit_code: 0 ----- stdout ----- @@ -11533,7 +11533,7 @@ fn sync_required_environment_hint() -> Result<()> { "You're on [PLATFORM] (`[TAG]`)", )); - uv_snapshot!(filters, context.sync().env_remove("UV_EXCLUDE_NEWER"), @r" + uv_snapshot!(filters, context.sync().env_remove(EnvVars::UV_EXCLUDE_NEWER), @r" success: false exit_code: 2 ----- stdout ----- @@ -12563,7 +12563,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { "#})?; // Ensure our build backend is checking the version correctly - uv_snapshot!(context.filters(), context.sync().env("EXPECTED_ANYIO_VERSION", "3.0"), @r" + uv_snapshot!(context.filters(), context.sync().env(EnvVars::EXPECTED_ANYIO_VERSION, "3.0"), @r" success: false exit_code: 1 ----- stdout ----- @@ -12597,7 +12597,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { "#})?; // The child should be built with anyio 4.0 - uv_snapshot!(context.filters(), context.sync().env("EXPECTED_ANYIO_VERSION", "4.0"), @r" + uv_snapshot!(context.filters(), context.sync().env(EnvVars::EXPECTED_ANYIO_VERSION, "4.0"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12630,7 +12630,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { // The child should be rebuilt with anyio 3.7, without `--reinstall` uv_snapshot!(context.filters(), context.sync() - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "4.0"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "4.0"), @r" success: false exit_code: 1 ----- stdout ----- @@ -12650,7 +12650,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { "); uv_snapshot!(context.filters(), context.sync() - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "3.7"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "3.7"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12670,7 +12670,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { uv_snapshot!(context.filters(), context.sync() .arg("--preview-features").arg("extra-build-dependencies") .arg("--reinstall-package").arg("child") - .env("EXPECTED_ANYIO_VERSION", "3.7"), @r" + .env(EnvVars::EXPECTED_ANYIO_VERSION, "3.7"), @r" success: true exit_code: 0 ----- stdout ----- @@ -12713,7 +12713,7 @@ fn sync_build_dependencies_respect_locked_versions() -> Result<()> { // This should fail uv_snapshot!(context.filters(), context.sync() - .arg("--reinstall-package").arg("child").env("EXPECTED_ANYIO_VERSION", "4.1"), @r" + .arg("--reinstall-package").arg("child").env(EnvVars::EXPECTED_ANYIO_VERSION, "4.1"), @r" success: false exit_code: 1 ----- stdout ----- @@ -12824,7 +12824,7 @@ fn sync_extra_build_variables() -> Result<()> { "); // Ensure our build backend is checking the version correctly. - uv_snapshot!(context.filters(), context.sync().env("EXPECTED_ANYIO_VERSION", "3.0"), @r" + uv_snapshot!(context.filters(), context.sync().env(EnvVars::EXPECTED_ANYIO_VERSION, "3.0"), @r" success: false exit_code: 1 ----- stdout ----- diff --git a/crates/uv/tests/it/tool_install.rs b/crates/uv/tests/it/tool_install.rs index cd080f404..848694d6c 100644 --- a/crates/uv/tests/it/tool_install.rs +++ b/crates/uv/tests/it/tool_install.rs @@ -3553,9 +3553,9 @@ fn tool_install_python() { // Install `python` uv_snapshot!(context.filters(), context.tool_install() .arg("python") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r###" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r###" success: false exit_code: 2 ----- stdout ----- @@ -3567,9 +3567,9 @@ fn tool_install_python() { // Install `python@` uv_snapshot!(context.filters(), context.tool_install() .arg("python@3.12") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r###" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r###" success: false exit_code: 2 ----- stdout ----- @@ -3849,9 +3849,9 @@ fn tool_install_with_executables_from() { .arg("--with-executables-from") .arg("ansible-core,black") .arg("ansible==9.3.0") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r" success: true exit_code: 0 ----- stdout ----- @@ -3914,9 +3914,9 @@ fn tool_install_with_executables_from() { uv_snapshot!(context.filters(), context.tool_uninstall() .arg("ansible") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r###" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3940,9 +3940,9 @@ fn tool_install_with_executables_from_no_entrypoints() { .arg("--with-executables-from") .arg("requests") .arg("flask") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r###" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r###" success: true exit_code: 0 ----- stdout ----- diff --git a/crates/uv/tests/it/tool_upgrade.rs b/crates/uv/tests/it/tool_upgrade.rs index 74ae4befd..a7e1f82e9 100644 --- a/crates/uv/tests/it/tool_upgrade.rs +++ b/crates/uv/tests/it/tool_upgrade.rs @@ -853,9 +853,9 @@ fn test_tool_upgrade_additional_entrypoints() { .arg("--with-executables-from") .arg("black") .arg("babel==2.14.0") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r" success: true exit_code: 0 ----- stdout ----- @@ -881,9 +881,9 @@ fn test_tool_upgrade_additional_entrypoints() { .arg("--python") .arg("3.12") .arg("babel") - .env("UV_TOOL_DIR", tool_dir.as_os_str()) - .env("XDG_BIN_HOME", bin_dir.as_os_str()) - .env("PATH", bin_dir.as_os_str()), @r" + .env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str()) + .env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()) + .env(EnvVars::PATH, bin_dir.as_os_str()), @r" success: true exit_code: 0 ----- stdout ----- diff --git a/docs/reference/environment.md b/docs/reference/environment.md index 0c370d91c..2a5131048 100644 --- a/docs/reference/environment.md +++ b/docs/reference/environment.md @@ -652,6 +652,19 @@ See [`PycInvalidationMode`](https://docs.python.org/3/library/py_compile.html#py Adds directories to Python module search path (e.g., `PYTHONPATH=/path/to/modules`). +### `RUST_BACKTRACE` + +If set, it can be used to display more stack trace details when a panic occurs. +This is used by uv particularly on windows to show more details during a platform exception. + +For example: + +* `RUST_BACKTRACE=1` will print a short backtrace. +* `RUST_BACKTRACE=full` will print a full backtrace. + +See the [Rust backtrace documentation](https://doc.rust-lang.org/std/backtrace/index.html) +for more. + ### `RUST_LOG` If set, uv will use this value as the log level for its `--verbose` output. Accepts