Skip to content

🐛 fix(env): break circular dependency in environment_variables resolution#3816

Merged
gaborbernat merged 3 commits intotox-dev:mainfrom
gaborbernat:bug
Feb 23, 2026
Merged

🐛 fix(env): break circular dependency in environment_variables resolution#3816
gaborbernat merged 3 commits intotox-dev:mainfrom
gaborbernat:bug

Conversation

@gaborbernat
Copy link
Member

@gaborbernat gaborbernat commented Feb 23, 2026

When set_env contains substitutions referencing {env_site_packages_dir}, {env_bin_dir}, or similar lazy constants, resolving them triggers virtualenv session creation. The session creation calls virtualenv_env_vars() which calls self.environment_variables, re-entering the property that's already mid-resolution. This causes a RecursionError which, being a subclass of RuntimeError, gets silently caught by _get_python -- making tox report "could not find python interpreter" when the interpreter is perfectly findable.

🔧 The fix adds a re-entrancy guard (_resolving_env_vars flag) to ToxEnv.environment_variables. When a recursive call is detected during set_env loading or key resolution, it returns pass_env + PATH without set_env values. This is sufficient for virtualenv's discovery and session creation, and the full set_env resolution completes normally once the session exists. The guard preserves full set_env support -- values set via set_env in tox.toml still work correctly for VIRTUALENV_* variables.

Additionally fixes test_virtualenv_api tests that unconditionally assert VirtualEnvOptions.copies, which is only present when the creator's meta reports can_copy. On platforms like macOS with Homebrew CPython, --copies is never added to argparse so the attribute doesn't exist.

@gaborbernat gaborbernat changed the title fix: break circular dependency in environment_variables 🐛 fix(env): break circular dependency in environment_variables resolution Feb 23, 2026
@gaborbernat gaborbernat added the bug:normal affects many people or has quite an impact label Feb 23, 2026
set_env substitutions like {env_site_packages_dir} trigger virtualenv
session creation which re-enters environment_variables, causing a
RecursionError silently caught as RuntimeError. Add a re-entrancy guard
that returns pass_env + PATH without set_env on recursive calls.

Also fix tests asserting VirtualEnvOptions.copies which is only present
when the creator's meta reports can_copy (not all platforms).
pre-commit-ci bot and others added 2 commits February 23, 2026 19:04
set_env substitutions like {env_site_packages_dir} trigger virtualenv
session creation which re-enters environment_variables, causing a
RecursionError silently caught as RuntimeError. Add a re-entrancy guard
that returns pass_env + PATH without set_env on recursive calls.

Also fix tests asserting VirtualEnvOptions.copies which is only present
when the creator's meta reports can_copy (not all platforms).
@gaborbernat gaborbernat enabled auto-merge (squash) February 23, 2026 19:31
@gaborbernat gaborbernat disabled auto-merge February 23, 2026 19:44
@gaborbernat gaborbernat merged commit ba0ab7c into tox-dev:main Feb 23, 2026
27 of 28 checks passed
@gaborbernat gaborbernat deleted the bug branch February 23, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided bug:normal affects many people or has quite an impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant