Skip to content

Require a path separator when detecting the active virtualenv - #11001

Open
tarann26 wants to merge 1 commit into
python-poetry:mainfrom
tarann26:fix-10357-venv-path-boundary
Open

Require a path separator when detecting the active virtualenv#11001
tarann26 wants to merge 1 commit into
python-poetry:mainfrom
tarann26:fix-10357-venv-path-boundary

Conversation

@tarann26

Copy link
Copy Markdown

Pull Request Check List

Resolves: #10357

  • Added tests for changed code.
  • Updated documentation for changed code.

Problem

When Poetry is itself hosted in a virtualenv whose name is a textual prefix-superset of the project venv — for example Poetry runs from .venv-poetry while the project venv is .venvcreate_venv() mistakes the two for the same environment and installs the project's dependencies into the base/system Python instead of the project venv.

After building the target venv, create_venv() walks sys.executable's symlink chain to decide whether Poetry is already running inside it:

p_venv = os.path.normcase(str(venv))
if any(p.startswith(p_venv) for p in paths):
    # Running properly in the virtualenv, don't need to do anything
    return self.get_system_env()

str.startswith has no path boundary, so ".../.venv-poetry/bin/python".startswith(".../.venv") is True. Poetry wrongly concludes it is inside .venv, returns get_system_env(), and the install lands in the base Python.

Fix

Require a path-separator boundary:

if any(p == p_venv or p.startswith(p_venv + os.sep) for p in paths):

A real in-venv interpreter (<venv>/bin/python) still matches via p_venv + os.sep, while a sibling such as .venv-poetry no longer does. Both p and p_venv are already passed through os.path.normcase, so os.sep is the correct native boundary on POSIX and Windows.

A regression test covering the sibling-venv scenario is included.

create_venv() used a plain string startswith() check to decide whether
Poetry is already running inside the venv it just built, so a sibling
venv whose name textually extends the target's (e.g. hosting Poetry
from .venv-poetry while the project venv is .venv) false-matched and
Poetry silently installed the project into the system Python instead.

@sourcery-ai sourcery-ai 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.

Hey - I've left some high level feedback:

  • In the new regression test, consider using os.environ.pop("VIRTUAL_ENV", None) instead of del os.environ["VIRTUAL_ENV"] to avoid a potential KeyError when the variable is absent.
  • The test hardcodes a bin/python3.9 path which is POSIX-specific; if the test suite is expected to run on Windows, you may want to construct the sibling executable path in a platform-aware way.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the new regression test, consider using `os.environ.pop("VIRTUAL_ENV", None)` instead of `del os.environ["VIRTUAL_ENV"]` to avoid a potential `KeyError` when the variable is absent.
- The test hardcodes a `bin/python3.9` path which is POSIX-specific; if the test suite is expected to run on Windows, you may want to construct the sibling executable path in a platform-aware way.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project dependencies get installed in system while they should not.

1 participant