Skip to content

Commit ec580dc

Browse files
committed
scripts_dir_from_site_packages: distinguish Windows venv vs user-site layout
Windows has two distinct site-packages layouts that the function previously conflated: * venv / system: <prefix>/Lib/site-packages (2 parents to prefix) * user-site: <root>/Python<ver>/site-packages (1 parent to the versioned Python dir whose Scripts we want) Both were being handled as site_packages.parent.parent, which for user-site returns ...\Roaming\Python instead of ...\Roaming\Python\Python312 — so PipProvider.setup_PATH's discovery of Windows user-installed pip scripts fell back to sysconfig.get_path('scripts') alone. Dispatch on the immediate parent's name (.lower() == 'lib' for venv/system, everything else for user-site). Flagged by devin-ai-integration on PR #31.
1 parent 79eac71 commit ec580dc

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

abxpkg/windows_compat.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -382,14 +382,25 @@ def venv_site_packages_dirs(venv_root: Path) -> list[Path]:
382382
def scripts_dir_from_site_packages(site_packages: Path) -> Path:
383383
"""Navigate from a ``site-packages`` path to the matching scripts dir.
384384
385-
Unix layout is ``<prefix>/lib/pythonX.Y/site-packages`` — three
386-
parents up lands at ``<prefix>``. Windows is ``<prefix>/Lib/
387-
site-packages`` — only two parents up. Appends the OS-appropriate
388-
``VENV_BIN_SUBDIR`` either way.
385+
Layouts (P = site-packages dir, each arrow shows the parent chain):
386+
387+
* Unix venv / system : ``<prefix>/lib/pythonX.Y/site-packages``
388+
→ 3 parents up = ``<prefix>``
389+
* Windows venv / system: ``<prefix>/Lib/site-packages``
390+
→ 2 parents up = ``<prefix>``
391+
* Windows user-site : ``<root>/Python<ver>/site-packages``
392+
→ 1 parent up = ``<root>/Python<ver>``, whose ``Scripts/`` dir
393+
is the correct user-scripts location.
394+
395+
Detect the Windows user-site case by checking whether the immediate
396+
parent dir is named ``Lib`` (venv/system) vs anything else (user
397+
site). Appends the OS-appropriate ``VENV_BIN_SUBDIR`` either way.
389398
"""
390-
prefix = (
391-
site_packages.parent.parent
392-
if IS_WINDOWS
393-
else site_packages.parent.parent.parent
394-
)
395-
return prefix / VENV_BIN_SUBDIR
399+
if not IS_WINDOWS:
400+
return site_packages.parent.parent.parent / VENV_BIN_SUBDIR
401+
# Windows: distinguish ``<prefix>/Lib/site-packages`` (venv/system,
402+
# 2 parents) from ``<root>/Python<ver>/site-packages`` (user site,
403+
# 1 parent) by the parent dir's name.
404+
if site_packages.parent.name.lower() == "lib":
405+
return site_packages.parent.parent / VENV_BIN_SUBDIR
406+
return site_packages.parent / VENV_BIN_SUBDIR

0 commit comments

Comments
 (0)