diff --git a/crates/uv-macros/src/lib.rs b/crates/uv-macros/src/lib.rs index d32e908fe..db2cc9853 100644 --- a/crates/uv-macros/src/lib.rs +++ b/crates/uv-macros/src/lib.rs @@ -143,6 +143,21 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To return quote! { #ast #(#added_in_errors)* }.into(); } + let env_var_names = ast.items.iter().filter_map(|item| { + if let ImplItem::Const(item) = item { + let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = &item.expr + else { + return None; + }; + Some(lit.value()) + } else { + None + } + }); + let struct_name = &ast.self_ty; let pairs = constants.iter().map(|(name, doc, added_in, _span)| { if let Some(added_in) = added_in { @@ -160,6 +175,11 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To pub fn metadata<'a>() -> &'a [(&'static str, &'static str, Option<&'static str>)] { &[#(#pairs),*] } + + /// Returns all environment variable names defined as constants (including hidden ones). + pub fn all_names() -> &'static [&'static str] { + &[#(#env_var_names),*] + } } }; diff --git a/crates/uv/tests/it/common/mod.rs b/crates/uv/tests/it/common/mod.rs index 85e7e290f..a742793a6 100644 --- a/crates/uv/tests/it/common/mod.rs +++ b/crates/uv/tests/it/common/mod.rs @@ -1444,6 +1444,9 @@ impl TestContext { command } + /// The path to the Python interpreter in the venv. + /// + /// Don't use this for `Command::new`, use `Self::python_command` instead. pub fn interpreter(&self) -> PathBuf { let venv = &self.venv; if cfg!(unix) { @@ -1726,8 +1729,39 @@ impl TestContext { /// Creates a new `Command` that is intended to be suitable for use in /// all tests, but with the given binary. + /// + /// Clears environment variables defined in [`EnvVars`] to avoid reading + /// test host settings. fn new_command_with(bin: &Path) -> Command { - Command::new(bin) + let mut command = Command::new(bin); + + let passthrough = [ + // For debugging tests. + EnvVars::RUST_LOG, + EnvVars::RUST_BACKTRACE, + // Windows System configuration. + EnvVars::SYSTEMDRIVE, + // Work around small default stack sizes and large futures in debug builds. + EnvVars::RUST_MIN_STACK, + EnvVars::UV_STACK_SIZE, + // Allow running tests with custom network settings. + EnvVars::ALL_PROXY, + EnvVars::HTTPS_PROXY, + EnvVars::HTTP_PROXY, + EnvVars::NO_PROXY, + EnvVars::SSL_CERT_DIR, + EnvVars::SSL_CERT_FILE, + EnvVars::UV_NATIVE_TLS, + ]; + + for env_var in EnvVars::all_names() + .iter() + .filter(|name| !passthrough.contains(name)) + { + command.env_remove(env_var); + } + + command } } @@ -1790,7 +1824,7 @@ pub fn get_python(version: &PythonVersion) -> PathBuf { /// Create a virtual environment at the given path. pub fn create_venv_from_executable>(path: P, cache_dir: &ChildPath, python: &Path) { - assert_cmd::Command::new(get_bin()) + TestContext::new_command_with(&get_bin()) .arg("venv") .arg(path.as_ref().as_os_str()) .arg("--clear")