Skip to content

Fix virtualenv extraction from activate for newer virtualenvs#35

Closed
ymilki wants to merge 6 commits intomainfrom
fix_virtualenv_extraction_from_activate
Closed

Fix virtualenv extraction from activate for newer virtualenvs#35
ymilki wants to merge 6 commits intomainfrom
fix_virtualenv_extraction_from_activate

Conversation

@ymilki
Copy link
Copy Markdown
Member

@ymilki ymilki commented Jan 8, 2026

Problem

pypa/virtualenv#2996 (virtualenv==20.36.0) changes how the VIRTUAL_ENV variable is defined in the bash activate script. Our tool explicitly reads and parses the activate script for the value of VIRTUAL_ENV=, which no longer works with the change and breaks with

AssertionError: Could not find VIRTUAL_ENV= in activation script: venv/bin/activate

Fixes #34.

Solution

The parsing is very brittle against changes to the script. Instead, we explicitly source the script and extract the value of the exported env variable.

Validation

We added a new test test_get_orig_path. During development, we tested against both older and newer virtualenv. Our change is compatible with both so we don't need to explicitly test different virtualenvs.

Note

HLFH in #34 provided their own patch in their fork for this change in HLFH@4971532, but it seems to be targeting a different form of the activation script.

Comment thread virtualenv_tools.py
Comment on lines +255 to +256
result = subprocess.run(["bash", "-c", f"source {activate_path} && echo $VIRTUAL_ENV"], capture_output=True, text=True)
return result.stdout.strip()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this introduces several arbitrary code execution vulnerabilities:

  • activate_path is not properly quoted
  • the activate script itself is arbitrary code and may not be a virtualenv activate script

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is parsing then still the best option even though its brittle?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that is the only approach I would take personally -- you'll still have problems with substitution either way

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In #36, I'm doing a str.replace for the virtualenv path. Because the bash script now has 3 lines to update, the existing regex doesn't cover all the cases. Though, maybe I should just create 2 more regexes to be more explicit about the replacement.

@ymilki ymilki marked this pull request as draft January 8, 2026 20:06
Comment thread virtualenv_tools.py
activate_path
)

result = subprocess.run(["bash", "-c", f"source {activate_path} && echo $VIRTUAL_ENV"], capture_output=True, text=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You might want to consider using shlex.quote on the activate_path. I think this will fail for paths with spaces or other special characters in them.

@ymilki
Copy link
Copy Markdown
Member Author

ymilki commented Jan 8, 2026

As the tests show, sourcing the script doesn't work in the general case.

The changes in virtualenv give VIRTUAL_ENV a fallback pattern (the current dir) when the original path doesn't exist. So VIRTUAL_ENV is no longer idempotent.

@ymilki
Copy link
Copy Markdown
Member Author

ymilki commented Jan 20, 2026

Closing in favor on #36

@ymilki ymilki closed this Jan 20, 2026
@ymilki ymilki deleted the fix_virtualenv_extraction_from_activate branch March 3, 2026 18:53
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.

Conflict with venv on Python 3.12

5 participants