diff --git a/crates/uv/tests/it/python_module.rs b/crates/uv/tests/it/python_module.rs index 06545ffd0..316dbe237 100644 --- a/crates/uv/tests/it/python_module.rs +++ b/crates/uv/tests/it/python_module.rs @@ -143,7 +143,7 @@ fn find_uv_bin_prefix() { ----- stderr ----- Traceback (most recent call last): File "", line 1, in - File "[TEMP_DIR]/prefix/[PYTHON-LIB]/site-packages/uv/_find_uv.py", line 36, in find_uv_bin + File "[TEMP_DIR]/prefix/[PYTHON-LIB]/site-packages/uv/_find_uv.py", line 37, in find_uv_bin raise FileNotFoundError(path) FileNotFoundError: [USER_SCHEME]/[BIN]/uv "# @@ -187,18 +187,14 @@ fn find_uv_bin_base_prefix() { uv_snapshot!(context.filters(), context.python_command() .arg("-c") .arg(format!(r#"import sys, uv; sys.base_prefix = "{}"; print(uv.find_uv_bin())"#, base_venv.path().portable_display())) - .env(EnvVars::PYTHONPATH, site_packages_path(base_venv.path(), "python3.12")), @r#" - success: false - exit_code: 1 + .env(EnvVars::PYTHONPATH, site_packages_path(base_venv.path(), "python3.12")), @r" + success: true + exit_code: 0 ----- stdout ----- + [TEMP_DIR]/base-venv/[BIN]/uv ----- stderr ----- - Traceback (most recent call last): - File "", line 1, in - File "[TEMP_DIR]/base-venv/[PYTHON-LIB]/site-packages/uv/_find_uv.py", line 36, in find_uv_bin - raise FileNotFoundError(path) - FileNotFoundError: [USER_SCHEME]/[BIN]/uv - "# + " ); } @@ -241,7 +237,7 @@ fn find_uv_bin_in_ephemeral_environment() -> anyhow::Result<()> { + uv==0.1.0 (from file://[WORKSPACE]/scripts/packages/fake-uv) Traceback (most recent call last): File "", line 1, in - File "[CACHE_DIR]/archive-v0/[HASH]/[PYTHON-LIB]/site-packages/uv/_find_uv.py", line 36, in find_uv_bin + File "[CACHE_DIR]/archive-v0/[HASH]/[PYTHON-LIB]/site-packages/uv/_find_uv.py", line 37, in find_uv_bin raise FileNotFoundError(path) FileNotFoundError: [USER_SCHEME]/[BIN]/uv "# @@ -299,7 +295,7 @@ fn find_uv_bin_in_parent_of_ephemeral_environment() -> anyhow::Result<()> { + sniffio==1.3.1 Traceback (most recent call last): File "", line 1, in - File "[SITE_PACKAGES]/uv/_find_uv.py", line 36, in find_uv_bin + File "[SITE_PACKAGES]/uv/_find_uv.py", line 37, in find_uv_bin raise FileNotFoundError(path) FileNotFoundError: [USER_SCHEME]/[BIN]/uv "# diff --git a/python/uv/_find_uv.py b/python/uv/_find_uv.py index 00b7d8873..0c45aff1a 100644 --- a/python/uv/_find_uv.py +++ b/python/uv/_find_uv.py @@ -10,20 +10,21 @@ def find_uv_bin() -> str: uv_exe = "uv" + sysconfig.get_config_var("EXE") + # Search in the scripts directory for the current prefix path = os.path.join(sysconfig.get_path("scripts"), uv_exe) if os.path.isfile(path): return path - if sys.version_info >= (3, 10): - user_scheme = sysconfig.get_preferred_scheme("user") - elif os.name == "nt": - user_scheme = "nt_user" - elif sys.platform == "darwin" and sys._framework: - user_scheme = "osx_framework_user" - else: - user_scheme = "posix_user" + # If in a virtual environment, also search in the base prefix's scripts directory + if sys.prefix != sys.base_prefix: + path = os.path.join( + sysconfig.get_path("scripts", vars={"base": sys.base_prefix}), uv_exe + ) + if os.path.isfile(path): + return path - path = os.path.join(sysconfig.get_path("scripts", scheme=user_scheme), uv_exe) + # Search in the user scheme scripts directory, e.g., `~/.local/bin` + path = os.path.join(sysconfig.get_path("scripts", scheme=_user_scheme()), uv_exe) if os.path.isfile(path): return path @@ -34,3 +35,15 @@ def find_uv_bin() -> str: return target_path raise FileNotFoundError(path) + + +def _user_scheme() -> str: + if sys.version_info >= (3, 10): + user_scheme = sysconfig.get_preferred_scheme("user") + elif os.name == "nt": + user_scheme = "nt_user" + elif sys.platform == "darwin" and sys._framework: + user_scheme = "osx_framework_user" + else: + user_scheme = "posix_user" + return user_scheme