Skip to content

Fix global Python scan missing uv and PDM installs (#449, #451) - #522

Merged
Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-python-global-tool-roots
Oct 2, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-python-global-tool-roots

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #449
Fixes #451

Summary

scan -g / get -g / apply -g / rollback -g / vex -g now find:

  • uv tool envs and uv-managed Pythons wherever uv puts them, and
  • PDM's global installs.

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:

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's StateStore::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;
    • the legacy roots: macOS ~/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 dir under each env var; a relative XDG_DATA_HOME is 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's project/config.py and Project.__init__, plus platformdirs. It covers:

    • the global project (global_project.path, default <user_config_dir>/pdm/global-project) and its .venv;
    • an out-of-tree <venv.location>/global-project-<hash>-<py> venv;
    • the interpreter recorded in its .pdm-python (the PDM 2.12 pdm use -g case);
    • every interpreter under python.install_root (default <user_data_dir>/pdm/python).

    The settings are read from $PDM_CONFIG_FILE or <user_config_dir>/pdm/config.toml, with ~ expanded. The user dirs follow platformdirs: $XDG_CONFIG_HOME / $XDG_DATA_HOME, ~/.config / ~/.local/share on Linux, ~/Library/Application Support/pdm on macOS, and %LOCALAPPDATA%\pdm\pdm on Windows.

  • The uv tool, uv Python and pipx scans now share find_child_env_site_packages, so lib64 multilib venvs are covered for uv too.

No wrapper changes are needed: npm/, pypi/ and gem/ 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:

  • With this PR: 58 passed, 0 failed.
  • With python_crawler.rs reverted to main: 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_appdata and ..._uv_python_under_appdata.

Per-issue checklist:

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 with chmod, 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 unmodified main here. None of them touch the Python crawler. CI runs as a non-root user.
  • cargo fmt --all -- --check: main itself 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

  • Bugbot (1a82a49) noted that ~ in PDM settings was expanded from HOME on Windows, while Python's expanduser uses USERPROFILE. Fixed in e5ab4b5, and the override test now covers it on Windows. Bugbot's review of e5ab4b5 found no issues.

Follow-ups

None. macOS's legacy ~/Library/Application Support/uv root is still scanned. I didn't add %APPDATA%\uv\data (the directories-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, so scan -g / get -g and 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, absolute XDG_DATA_HOME, default data dirs (~/.local/share/uv, %APPDATA%\uv on Windows), plus legacy roots. Tool envs and managed interpreters are scanned via shared find_child_env_site_packages (including lib64 on Unix).

PDM (#451): New pdm_global_site_packages resolves platformdirs-style config/data dirs, reads $PDM_CONFIG_FILE or default config.toml, and surfaces site-packages for the global project (in-tree .venv, out-of-tree venv.location envs, .pdm-python interpreter) and pdm python install trees under python.install_root.

E2E tests in crawler_python_e2e.rs isolate 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

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
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 2, 2026 02:56
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread crates/socket-patch-core/src/crawlers/python_crawler.rs
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
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] Ready for review at e5ab4b5.

  • CI: all 340 check runs have finished: 334 passed, 6 skipped, none failed.
  • Bugbot: its one finding on 1a82a49 (Windows ~ expansion) is fixed and resolved. Its review of e5ab4b5 found no new issues.
  • Every new Linux-applicable regression test fails when python_crawler.rs is reverted to main (11 of the 58 tests in the file).

Generated by Claude Code

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 2, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[burn-down agent] Labeled Ready for review at e5ab4b5d47.

  • CI: 340/340 check runs finished on the head, none failed (success, skipped, or neutral).
  • Bugbot: reviewed e5ab4b5d47, no new issues. No unresolved review threads.
  • Mergeable against main. Still needs a human approval.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Reviewed e5ab4b5d47d51f534464b43bda48bd303b12ba27. Recommendation: ready to merge as-is from code review.

No actionable regressions found in the global uv/PDM discovery changes. Checked relocated roots, platform branches, PDM config/interpreter resolution, regular-file reads, and lib64 handling.

Validation: cargo test -p socket-patch-core --test crawler_python_e2e — 59 passed on macOS, including the new relocation and PDM cases. Windows-only APPDATA cases and full workspace were not rerun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

3 participants