Fix global Python scan missing uv and PDM installs (#449, #451) - #522
Conversation
Assisted-by: Claude Code:claude-opus-5-5
scan -g, get -g, apply -g, rollback -g and vex -g looked for uv tool envs and uv-managed Pythons only at fixed paths, and never looked for PDM's global installs at all. On Windows every uv tool env was missed (uv uses %APPDATA%, not %LOCALAPPDATA%). On every OS, UV_TOOL_DIR, UV_PYTHON_INSTALL_DIR and XDG_DATA_HOME were ignored. `pdm add -g` packages in the global project venv, and packages in PDM-managed interpreters, were silently left out. Global discovery now follows each tool's own path rules: uv's override env vars and state dir, and PDM's platformdirs config/data dirs plus the global_project.path, python.install_root and venv.location settings and the global project's .pdm-python. Fixes #449 Fixes #451 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
PDM expands a `~` in global_project.path or python.install_root with Python's expanduser, which uses USERPROFILE on Windows and ignores HOME. Under Git Bash, HOME is an MSYS path, so the relocated global project or interpreter root was looked for in the wrong place. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e5ab4b5. Configure here.
|
[agent] Ready for review at
Generated by Claude Code |
|
[burn-down agent] Labeled Ready for review at
Generated by Claude Code |
|
Reviewed No actionable regressions found in the global uv/PDM discovery changes. Checked relocated roots, platform branches, PDM config/interpreter resolution, regular-file reads, and Validation: |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #449
Fixes #451
Summary
scan -g/get -g/apply -g/rollback -g/vex -gnow find:Before this change they were silently skipped and the run still exited 0.
Root cause
get_global_python_site_packages(crates/socket-patch-core/src/crawlers/python_crawler.rs) hard-coded where Python tools keep their global environments. It didn't follow each tool's own path resolution:%LOCALAPPDATA%\uv\toolson Windows, but uv uses%APPDATA%\uv\tools.UV_TOOL_DIR,UV_PYTHON_INSTALL_DIRandXDG_DATA_HOMEwere never read.pdm add -gpackages are silently left out with exit 0 #451): there were no PDM entries at all.Fix
New helpers sit next to the existing
pipx_home_candidates. They return every root the tool may use, and global discovery scans the ones that exist:uv_dir_candidates(home, override_var, bucket)mirrors uv'sStateStore::from_settings. The candidates are:$UV_TOOL_DIR/$UV_PYTHON_INSTALL_DIR, made absolute against the cwd as uv does;$XDG_DATA_HOME/uv/<bucket>(absolute only);~/.local/share/uv/<bucket>on Unix;%APPDATA%\uv\<bucket>on Windows;~/Library/Application Support/uv, and Windows%LOCALAPPDATA%\uv, which earlier releases scanned.I checked these rules against real uv 0.8.17 (
uv tool dir/uv python dirunder each env var; a relativeXDG_DATA_HOMEis ignored). The Windows default is the one reported in Global scan (-g) misses uv tool environments on Windows (looks in %LOCALAPPDATA%\uv\tools, uv uses %APPDATA%\uv\tools) and on every OS when UV_TOOL_DIR, XDG_DATA_HOME or UV_PYTHON_INSTALL_DIR is set #449.pdm_global_site_packages(home)mirrors PDM 2.29'sproject/config.pyandProject.__init__, plus platformdirs. It covers:global_project.path, default<user_config_dir>/pdm/global-project) and its.venv;<venv.location>/global-project-<hash>-<py>venv;.pdm-python(the PDM 2.12pdm use -gcase);python.install_root(default<user_data_dir>/pdm/python).The settings are read from
$PDM_CONFIG_FILEor<user_config_dir>/pdm/config.toml, with~expanded. The user dirs follow platformdirs:$XDG_CONFIG_HOME/$XDG_DATA_HOME,~/.config/~/.local/shareon Linux,~/Library/Application Support/pdmon macOS, and%LOCALAPPDATA%\pdm\pdmon Windows.The uv tool, uv Python and pipx scans now share
find_child_env_site_packages, solib64multilib venvs are covered for uv too.No wrapper changes are needed:
npm/,pypi/andgem/only dispatch the binary.Test evidence
Tests are in
crates/socket-patch-core/tests/crawler_python_e2e.rs. They pin HOME and every relocating env var, so ambient host values can't decide the result.cargo test -p socket-patch-core --test crawler_python_e2e, Linux:python_crawler.rsreverted tomain: 11 failed, which is every new Linux-applicable test.Two more tests are Windows-only (
cfg(windows)) and run on the Windows CI leg:..._uv_tools_under_appdataand..._uv_python_under_appdata.Per-issue checklist:
UV_TOOL_DIR:get_global_python_site_packages_discovers_uv_tools_under_uv_tool_dir(red → green)XDG_DATA_HOMEtools:..._discovers_uv_tools_under_xdg_data_home(red → green)UV_PYTHON_INSTALL_DIR:..._discovers_uv_python_under_install_dir(red → green)XDG_DATA_HOMEpython:..._discovers_uv_python_under_xdg_data_home(red → green)%APPDATA%\uv\tools/\python:..._uv_tools_under_appdata,..._uv_python_under_appdata(Windows CI)pdm add -gpackages are silently left out with exit 0 #451 global project.venv:..._discovers_pdm_global_project_venv(red → green)pdm add -gpackages are silently left out with exit 0 #451XDG_CONFIG_HOME:..._discovers_pdm_global_project_under_xdg_config_home(red → green)pdm add -gpackages are silently left out with exit 0 #451 PDM-managed interpreters:..._discovers_pdm_managed_interpreters(red → green)pdm add -gpackages are silently left out with exit 0 #451global_project.path/python.install_rootoverrides viaPDM_CONFIG_FILE:..._follows_pdm_config_overrides(red → green)pdm add -gpackages are silently left out with exit 0 #451 defaultconfig.toml:..._reads_pdm_default_config_file(red → green)pdm add -gpackages are silently left out with exit 0 #451.pdm-pythoninterpreter (PDM 2.12 no-venv case):..._follows_pdm_global_project_interpreter(red → green)pdm add -gpackages are silently left out with exit 0 #451venv.locationout-of-tree global venv, and other projects' venvs excluded:..._discovers_pdm_global_project_out_of_tree_venv(red → green)Local checks:
cargo clippy --workspace --all-features -- -D warnings: clean.cargo test --workspace --all-features --no-fail-fast: 9,479 passed, 12 failed. Every failure is a write-failure test that makes a dir read-only withchmod, which root (this sandbox) ignores:covgap_commands_vendor×3,in_process_redirect×3,repair×2, core lib ×4. The same core lib failures reproduce on unmodifiedmainhere. None of them touch the Python crawler. CI runs as a non-root user.cargo fmt --all -- --check:mainitself isn't rustfmt-clean with the pinned 1.93.1 toolchain, and CI doesn't run it. I formatted only the hunks this PR touches.Review rounds
1a82a49) noted that~in PDM settings was expanded fromHOMEon Windows, while Python'sexpanduserusesUSERPROFILE. Fixed ine5ab4b5, and the override test now covers it on Windows. Bugbot's review ofe5ab4b5found no issues.Follow-ups
None. macOS's legacy
~/Library/Application Support/uvroot is still scanned. I didn't add%APPDATA%\uv\data(thedirectories-crate legacy root on Windows) because I couldn't confirm uv ever used it.🤖 Generated with Claude Code
https://claude.ai/code/session_011Y5WmyS6GcEUtn5VVPwYXu
Note
Medium Risk
Changes only global filesystem discovery paths (no patching logic), but broader scanning can include more site-packages trees and mis-resolved paths could add noise or miss edge layouts.
Overview
Global Python discovery (
get_global_python_site_packages) no longer hard-codes uv install roots and now includes PDM global installs, soscan -g/get -gand related flows can see packages in those environments instead of skipping them silently.uv (#449): Inline macOS/Windows/Linux path blocks are replaced by
uv_dir_candidates, which follows uv’s layout:UV_TOOL_DIR/UV_PYTHON_INSTALL_DIR, absoluteXDG_DATA_HOME, default data dirs (~/.local/share/uv,%APPDATA%\uvon Windows), plus legacy roots. Tool envs and managed interpreters are scanned via sharedfind_child_env_site_packages(includinglib64on Unix).PDM (#451): New
pdm_global_site_packagesresolves platformdirs-style config/data dirs, reads$PDM_CONFIG_FILEor defaultconfig.toml, and surfaces site-packages for the global project (in-tree.venv, out-of-treevenv.locationenvs,.pdm-pythoninterpreter) andpdm python installtrees underpython.install_root.E2E tests in
crawler_python_e2e.rsisolate relocating env vars (TOOL_DIR_VARS,global_site_packages_with_vars) so host settings cannot mask regressions.Reviewed by Cursor Bugbot for commit e5ab4b5. Configure here.
Generated by Claude Code