Skip to content

v4.67.5

Latest

Choose a tag to compare

@github-actions github-actions released this 31 Oct 04:31
Immutable release. Only release title and notes can be modified.

Bug fixes

  • A packaging environment whose base_python (or default_base_python) is not installed no longer crashes with KeyError: 'skip_missing_interpreters'. It now fails with the missing interpreter, or skips the run environment when skip_missing_interpreters is true, as tox did before 4.36.0 (#4213) by @gaborbernat. (#4212)
  • Keep environment markers when a package extra refers to another extra of the same package. For example, demo[dev]; python_version < '3.10' keeps the version condition on dependencies from dev (#4216) by @ericdelorefice and @gaborbernat.
  • A pylock.toml or a tox user configuration file (TOX_USER_CONFIG_FILE) saved with a UTF-8 byte order mark, as some Windows editors do, is now read instead of failing with a TOML decode error or being ignored with failed to read config file (#4217) by @pcbeingused333.
  • With args_are_paths enabled, a positional argument naming an existing file whose rewritten path relative to change_dir starts with - (for example tests/--config=evil.cfg) is now prefixed with ./ so the command still receives a path instead of an option (#4317) by @rahuldevikar and @gaborbernat. (#4218)
  • An extending TOML replace table with a nonempty marker now raises an error instead of adding its internal value and marker keys to deps or requires. Markers on set_env values remain supported (#4320) by @rahuldevikar and @gaborbernat. (#4220)
  • A TOML type mismatch no longer includes an expanded string or container value. A malformed commands setting with {env:...} reports its type instead of the substituted text (#4327) by @rahuldevikar and @gaborbernat. (#4221)
  • Keep artifacts supplied with --installpkg out of tox's provisioning environment while installing them in the requested test environments (#4304) by @Pratham2511 and @gaborbernat. (#4222)
  • A file: URI passed to --installpkg is now percent-decoded once instead of twice, so a path containing a literal % sequence, such as a directory named feature%2Flogin, selects the package the user named (#4300) by @pcbeingused333 and @gaborbernat. (#4223)
  • A relative TOX_INSTALL_PKG or user configuration install_pkg path is now resolved against the invocation directory, as --installpkg already was, so tox inspects and installs from the same path (#4333) by @rahuldevikar and @gaborbernat. (#4224)
  • tox refuses a symlink or Windows junction at meta_dir because the build frontend empties that directory during metadata preparation (#4332) by @rahuldevikar and @gaborbernat. (#4225)
  • An explicitly empty base_python (for example {env:TOXPYTHON:python3.11} with TOXPYTHON empty) now fails during configuration with base_python for env <name> is empty. Blank entries in a base_python list are ignored (#4326) by @rahuldevikar and @gaborbernat. (#4226)
  • A path setting that expands to an empty value, such as env_tmp_dir = {env:SCRATCH_DIR} with SCRATCH_DIR unset, now fails with a configuration error instead of resolving to the current directory, which tox could then clear (#4330) by @rahuldevikar and @gaborbernat. (#4227)
  • Keep every value of a multi-value command line flag, such as -f py legacy, with that flag. The command scanner took a later value matching a subcommand as the command, causing environments without that factor to run (#4319) by @rahuldevikar and @gaborbernat. (#4228)
  • Unreadable wheels, invalid wheel metadata, and unreadable or empty source archives supplied through --installpkg now produce errors that name the artifact instead of internal error tracebacks (#4287) by @santhiprakash and @gaborbernat. (#4230)
  • Reject NUL characters in set_env file assignments with a handled input error instead of a subprocess traceback (#4279) by @Doomguy-BFG9000 and @gaborbernat. (#4231)
  • Limit each requirement or constraint file to 10 MiB, so oversized and endless includes fail with a size error. For remote files, tox checks a 120-second deadline between response body reads. Slow HTTP framing can delay that check (#4312) by @rahuldevikar and @gaborbernat. (#4232)
  • tox now validates inline script dependencies as requirements before installing them. An invalid entry such as a pip option fails before tox passes the dependencies to pip (#4306) by @santhiprakash and @gaborbernat. (#4233)
  • Read static package dependencies and the editable-legacy install path from the packaging environment's package_root instead of the core one, so a package_root set in [testenv:.pkg] no longer pairs the built package with the dependencies declared next to tox.ini (#4321) by @rahuldevikar and @gaborbernat. (#4234)
  • A package environment path that is already a symlink no longer causes tox list to create file.lock under the link target (#4311) by @rahuldevikar and @gaborbernat. (#4235)
  • tox now expands ${VAR} in requirements and constraints files using the environment running pip, including pass_env and set_env, instead of the tox process. A variable absent from that environment stays literal, so tox cannot put its host value in a fetched URL. To retain expansion, add it to pass_env or define it with set_env (#4323) by @rahuldevikar and @gaborbernat. (#4236)
  • Mask values when a flag or environment variable name contains a secret keyword after a newline (#4259) by @haigou-web and @gaborbernat. (#4237)
  • tox -h no longer prints secret-looking --key=value values from TOX_OVERRIDE. Conversion warnings also mask those values in invalid TOX_ options (#4303) by @faresrafat3 and @gaborbernat. (#4238)
  • A tox.toml or pyproject.toml string with literal braces around text containing a colon, such as a JSON argument holding a URL or a time, is now kept as written, as in tox.ini, instead of being read as a {key:default} reference. Positional arguments such as set_env:x passed into such braces through {posargs} no longer expand into the value of that setting (#4269) by @Anandb71 and @gaborbernat. (#4239)
  • Reject wheel metadata entries over 8 MiB uncompressed, limiting memory use during package installation (#4328) by @rahuldevikar and @gaborbernat. (#4240)
  • Recreate an environment when its .tox-info.json contains a non-mapping value for a section that requires a mapping (#4258) by @haigou-web and @gaborbernat. (#4241)
  • Preserve empty positional arguments when rewriting relative paths for change_dir (#4256) by @Fire162 and @gaborbernat. (#4242)
  • base_python_file rejects non-regular files, undecodable content, and version lines over 1024 characters with a handled error naming the file. It reads comments in bounded chunks, so a long comment can still precede the version (#4325) by @rahuldevikar and @gaborbernat. (#4243)
  • base_python_file now accepts only a Python version specifier (such as 3.13 or pypy3.10) from the version file. A path or program name there no longer makes tox start that program during interpreter discovery, and the rejected line is not echoed in the error message (#4324) by @rahuldevikar and @gaborbernat. (#4244)
  • An inline deps or constraints entry that directly substitutes a host variable via {env:NAME} or a TOML replace = "env" table now passes ${OTHER} text in that value to pip unchanged. A TOML reference to the loaded entry keeps the same behavior. A ${NAME} reference written in the configuration or a substitution default still expands (#4329) by @rahuldevikar and @gaborbernat. (#4245)
  • pylock now evaluates Python and platform markers using a complete environment from the target interpreter. Previously, missing values such as implementation_version came from the Python running tox, which could select a package locked for the wrong interpreter (#4331) by @rahuldevikar and @gaborbernat. (#4246)
  • For active packages in a pylock.toml, reject whitespace or control characters in hash tokens, archive or VCS URLs, commit IDs, and subdirectories before writing pip requirements. A line break in one of these fields could add a pip option such as --index-url. The check also covers values pip expands from ${VAR} references. Changing a referenced value reinstalls the locked packages (#4315) by @rahuldevikar and @gaborbernat. (#4247)
  • A direct URL entry in requires (such as tox @ file:///path/to/tox.whl) now triggers provisioning unless the installed distribution's direct_url.json records the requested source, including a supported archive hash, subdirectory, or VCS revision. pip discards fragment fields such as egg; these no longer trigger repeat provisioning. When the installer omits credentials from the origin record, a credentialed direct URL without a requested archive hash fails with an explanation instead of hanging during provisioning (#4314) by @rahuldevikar and @gaborbernat. (#4248)
  • tox now rejects sdist members whose paths or link targets escape the extraction directory. On Python versions without the tarfile data filter, tox checks each member as it extracts the archive (#4316) by @rahuldevikar and @gaborbernat. (#4249)
  • Report the file and line number for an invalid set_env file line, since its content may contain a secret (#4298) by @r3wretrhy and @gaborbernat. (#4250)
  • Keep input bytes out of tox config INI, JSON, and TOML output when a configuration key reads non-UTF-8 data (#4302) by @ducanhnguyen223, ducanhnguyen223 and @gaborbernat. (#4251)
  • A pre-existing symlink at .tox-info.json no longer supplies cached state. When tox writes state, it replaces the link and leaves its target untouched (#4322) by @rahuldevikar and @gaborbernat. (#4253)
  • When rebuilding a stale bootstrap environment for virtualenv_spec, tox removes a link at the cache path and creates the replacement without venv's clear option. A link placed there after cleanup and before directory creation stops the rebuild without emptying its target (#4313) by @rahuldevikar and @gaborbernat. (#4254)
  • Redirected Windows output now escapes characters its code page cannot encode instead of raising UnicodeEncodeError. The stream keeps its encoding (#4257) by @haigou-web and @gaborbernat. (#4255)
  • Read the Docs now fetches Git history and tags before installing tox, so VCS version detection can satisfy tox-uv (#4337) by @gaborbernat. (#4336)
  • A host variable substituted through set_env into deps or constraints now keeps ${NAME} text literal for pip. A ${NAME} written in the configuration still expands (#4342) by @gaborbernat. (#4338)
  • On Windows, building a virtualenv_spec bootstrap environment no longer writes through a junction swapped into its cache entry. A linked project work directory still works; the work directory must allow temporary subdirectories (#4341) by @gaborbernat. (#4339)
  • test_parallel_general uses an absolute missing-interpreter path to avoid Windows registry probes in CI (#4346) by @gaborbernat. (#4344)
  • A set_env line with a substituted key keeps its value in one variable, even when the input contains a line break. A key that expands to = or a line separator raises an error (#4265) by @gaborbernat.
  • A host environment value selected by {env:NAME} that references itself twice could stall tox during recursive expansion. tox now stops expansion at the first depth-limit hit, logs one warning, and leaves the remaining text unexpanded (#4272) by @gaborbernat.
  • An included set_env keeps {env:...} values intact when the source environment inherits the setting, uses setenv or comes from a generative section. The TOML string form "{[env.name]set_env}" does the same. Line breaks, ; and file| text inside values no longer become set_env syntax (#4268) by @gaborbernat.
  • An invalid pylock.toml, including malformed TOML or non-UTF-8 bytes, now reports invalid pylock file with the filename and the parser or decoder error instead of an internal traceback (#4215) by @PRINCE2-AI, Prince and @gaborbernat.
  • Help with an invalid -c configuration now looks for an inline plugin in the requested file's parent directory or inside the selected directory (#4267) by @gaborbernat.
  • INI commands now keep a path reference such as {tox_root}, {env_tmp_dir} or {env_python} within one argument, including when the path contains spaces, quotes or backslashes. The same applies to tox-provided values such as {host_python} and {tox_root_name}, entries of a list such as {base_python}, and file names matched by {glob:PATTERN}. Command values set with -x or TOX_OVERRIDE follow the same rule (#4290) by @gaborbernat.
  • INI commands that reference deps now preserve each pip option operand as one argument. A substituted --find-links path containing spaces can no longer add options to the command. The tox config display escapes spaces, quotes and backslashes in those operands (#4276) by @gaborbernat.
  • Keep a substitution within the quoted INI command argument it is part of: "--title={env:TITLE}" is one argument even when the value of TITLE holds quotes or whitespace, as it is for a TOML argument array. tox used to paste the value into the command text before splitting it, so a quote in the value ended the argument and the rest of the value arrived as further arguments of the command. install_command and list_dependencies_command get the same handling (#4283) by @gaborbernat.
  • Mask credentials in requires direct URLs in missing-requirement messages and echoed provisioning commands (#4334) by @gaborbernat.
  • Mask secret-looking inline flag values in result JSON command lists, retry warnings, subprocess start errors, path debug logs, unknown-argument errors, and ExecuteRequest representations (#4264) by @gaborbernat.
  • On POSIX, tox now pins each directory on the path to the project root while reading or changing a .venv redirect. A concurrent path swap can no longer redirect removal or replacement into another directory (#4308) by @gaborbernat.
  • On POSIX, tox now resolves relative commands and PATH entries from the command's working directory. The allowlist_externals check and TOX_LIMITED_SHEBANG interpreter selection use the file that the child executes (#4275) by @gaborbernat.
  • On Windows, INI command references such as {[testenv:a]commands} now preserve argument boundaries when a positional argument contains an apostrophe or backslash. tox config displays the command with the same quoting tox uses to parse a reference (#4277) by @gaborbernat.
  • On Windows, tox pins the project path while reading or changing a .venv redirect. A concurrent directory rename or junction added to an empty project directory cannot redirect a write or removal into another project. Redirect writes replace .venv with a temporary file, leaving the target of a swapped .venv symlink or hard link unchanged (#4335) by @gaborbernat.
  • On Windows, tox quotes arguments passed to .bat and .cmd commands for cmd.exe. Values containing shell operators or percent signs reach the batch file without starting another command or expanding environment variables. Batch scripts that inspect raw %1 may now see surrounding quotes for arguments that need them (#4288) by @gaborbernat.
  • Pass each base_python entry to virtualenv as a separate --python argument. virtualenv split the old VIRTUALENV_PYTHON value on commas and os.pathsep, then tried the first candidate last; that could start an unintended program (#4292) by @gaborbernat.
  • Prefix normalized dependency paths whose first component starts with - using ./ on POSIX or .\ on Windows. The resulting pip argument no longer starts with - (#4266) by @gaborbernat.
  • Preserve # in INI references to paths, so change_dir, env_dir and set_env = file|... use the checkout directory when its name contains #. On POSIX, requirement-file paths with a space before # remain readable (#4285) by @gaborbernat.
  • Preserve frozen dependency constraints when using --no-capture or setting up an environment with tox exec (#4301) by @Pratham2511 and @gaborbernat.
  • Reject a bootstrap cache parent that already resolves outside the work directory before opening its lock or creating an environment (#4345) by @gaborbernat.
  • Reject a line break in a substitution within one deps or constraints entry, and a backslash ending a substituted requirement line. Also reject line breaks and trailing backslashes in globbed requirement paths and provisioning requirements. These values can no longer add pip options or consume the following entry (#4295) by @gaborbernat.
  • Reject an entry separator supplied by a substitution within an INI list, set, dictionary or env_list entry. This prevents a value inside one requires entry from adding a requirement, and a value inside one env_list entry from selecting another environment. A substitution that occupies a whole entry can still expand to several entries. The same check applies to text overrides supplied with -x or TOX_OVERRIDE (#4284) by @gaborbernat.
  • Replace line breaks in positional arguments before quoting them for {posargs} and INI command references. This prevents a line break in one argument from starting another command (#4294) by @gaborbernat.
  • Shell completion now uses the -c/--conf path from the typed line when loading toxfile.py and offering environments. While that path is incomplete, completion loads no inline plugin (#4278) by @gaborbernat.
  • The provisioned tox now starts with Python's safe path option. During its -m tox re-exec, Python no longer puts the start directory first on sys.path, where an unrelated file could replace tox or a dependency (#4270) by @gaborbernat.
  • Validate built-in command options before selecting an inline plugin. An invalid option value no longer causes tox to import a plugin from an unselected project. Put -c/--conf or --root before options defined by an inline plugin (#4281) by @gaborbernat.
  • Values expanded from secret-named environment variables in requirements files no longer appear in the install cache, recreation warnings, or file-read errors. tox may recreate an existing environment once to replace a cache written by an older version (#4280) by @gaborbernat.
  • When positional arguments supply the command, as in tox exec or commands = {posargs}, tox now leaves a bare program name such as python unchanged. It also leaves a bare executable first positional value unchanged, including when a command uses that value as data, because wrappers can run it as a program. A same-named file in the start directory no longer replaces the environment's program. An explicit path such as ./python still follows args_are_paths (#4289) by @gaborbernat.
  • With TOX_LIMITED_SHEBANG enabled, tox now keeps quote and backslash characters in an unquoted shebang interpreter path. They no longer change the executable tox starts. The existing double-quoted form for paths with spaces remains supported (#4274) by @gaborbernat.
  • With args_are_paths on POSIX, tox now rewrites positional paths from the resolved change_dir. A linked .tox can no longer redirect a positional path to a file beside the link target (#4273) by @gaborbernat.
  • pylock and dependency_groups now use package_root when a run has no package environment. They previously used tox_root in that case (#4299) by @pcbeingused333 and @gaborbernat.
  • tox now rejects environment names that are not a single path component before creating an environment. This prevents a substituted env_list, label or package environment name from selecting a directory outside work_dir (#4271) by @gaborbernat.
  • tox now resolves relative env_dir, env_tmp_dir, env_log_dir, work_dir, temp_dir, package_root, meta_dir, pkg_dir and package_glob values against tox_root. With tox -c path/to/tox.ini started elsewhere, it no longer clears or reuses those directories in the start directory or selects a package from there (#4291) by @gaborbernat.
  • tox passes positional arguments, {glob:PATTERN} matches and TOX_FACTOR_<label> overrides literally in INI configuration: a {...} or [] in them is no longer substituted again, so tox run -- '{env:SECRET}' hands the command {env:SECRET} instead of the variable's value and tox run -- '{posargs} -x' stays one argument. The DEFAULTS of {posargs:DEFAULTS} and referenced keys still expand their own substitutions (#4286) by @gaborbernat.

Security

  • Keep virtualenv's pip seeder debug line visible and mask secret-named environment values before tox prints it (#4293) by @gaborbernat.
  • Mask secret-looking inline flags inside a command argument when INI parsing leaves several words in that argument (#4263) by @gaborbernat.
  • Reject pip options added through partial deps or constraints substitutions, including ${VAR} expansion. tox still accepts options written on the same line in either setting (#4297) by @gaborbernat.
  • Replace stale package staging links under the work directory and reject staging paths another account can change. Create the staged package exclusively so a substituted destination link cannot overwrite its target (#4305) by @gaborbernat.
  • Validate virtualenv_spec as a virtualenv requirement with optional version specifiers before invoking pip (#4261) by @gaborbernat.
  • Where descriptor-based rmtree and O_DIRECTORY/O_NOFOLLOW are available, clean environment, log, and temporary directories relative to an open directory descriptor so a symlink swap cannot redirect deletions outside tox's work directory. Replace a link already at the cleanup path without emptying its target (#4296) by @gaborbernat.
  • set_env environment files now split entries only at LF or CR line endings. Embedded Unicode separators no longer start a new variable (#4260) by @gaborbernat.

New Contributors

PyPI release

Full Changelog