Skip to content

fix(venv): escape glob characters in the venv lookup prefix - #3869

Merged
frostming merged 1 commit into
pdm-project:mainfrom
MohammedAlkindi:fix/venv-lookup-glob-escape
Aug 30, 2026
Merged

fix(venv): escape glob characters in the venv lookup prefix#3869
frostming merged 1 commit into
pdm-project:mainfrom
MohammedAlkindi:fix/venv-lookup-glob-escape

Conversation

@MohammedAlkindi

Copy link
Copy Markdown
Contributor

get_venv_prefix builds the prefix from the project directory name, and venv create writes that name to disk literally. iter_venvs then feeds the same string to Path.glob, where [ and ] are pattern metacharacters and are legal in Windows directory names. A project in my[project], or the common browser-download form downloads[1], produces a pattern that never matches its own venv, so venv list, venv remove, venv activate, pdm use --venv and interpreter discovery all silently see nothing. No error is raised.

On the unpatched source the added test reports:

assert {} == {'3.13': WindowsPath('.../venvs/downloads[1]-dS0SdxMQ-3.13')}

iter_venvs yields nothing while the venv it should find is on disk.

glob.escape rather than iterdir() and startswith, because glob returns empty for a missing venv parent directory while iterdir() raises FileNotFoundError, which is the normal state on a fresh machine. The ident slice keeps the unescaped length, since it indexes the real on-disk name rather than the pattern.

Scoped suite on Windows 11, CPython 3.13.5: 481 passed, 5 skipped.

get_venv_prefix builds the prefix from the project directory name, and venv create writes that name to disk literally. iter_venvs fed the same string to Path.glob, where [ and ] are pattern metacharacters and are legal in Windows directory names. A project in my[project] or downloads[1] produced a pattern that never matched its own venv, so venv list, venv remove, venv activate and interpreter discovery all silently saw nothing.

The ident slice keeps the unescaped length because it indexes the real on-disk name, not the pattern.
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.79%. Comparing base (bf6f64b) to head (3b5744c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3869   +/-   ##
=======================================
  Coverage   88.79%   88.79%           
=======================================
  Files         120      120           
  Lines       13321    13322    +1     
  Branches     2265     2265           
=======================================
+ Hits        11828    11829    +1     
  Misses        931      931           
  Partials      562      562           
Flag Coverage Δ
unittests 88.68% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
@frostming
frostming merged commit b6acd0e into pdm-project:main Aug 30, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants