Skip to content

Commit 9aaec0c

Browse files
yarikopticclaudepre-commit-ci[bot]
authored
fix: handle OSError in pos_args path existence check (#3847)
When positional arguments exceed the filesystem's filename length limit (typically 255 characters), `Path.exists()` raises `OSError: [Errno 36] File name too long` instead of returning `False`. This causes `tox` to crash with an internal error when **long** `-k` expressions are passed via `{posargs}`, e.g.: tox -e py3 -- -k "test_foo or test_bar or test_baz or ..." The traceback is: File ".../tox/config/main.py", line 58, in pos_args if path_arg.exists() and not path_arg.is_absolute(): OSError: [Errno 36] File name too long: 'test_foo or test_bar or ...' This is because `pos_args()` checks each argument with `path_arg.exists()` to determine whether to rewrite relative paths for `changedir`. An argument that is too long for the filesystem clearly cannot be a path, so the fix catches `OSError` and treats such arguments as non-paths. <!-- Thank you for your contribution! Please, make sure you address all the checklists (for details on how see [development documentation](http://tox.readthedocs.org/en/latest/development.html#development))! --> - [ ] ran the linter to address style issues (`tox -e fix`) [XXX] - [x] wrote descriptive pull request text - [x] ensured there are test(s) validating the fix - [x] added news fragment in `docs/changelog` folder -- - [ ] updated/extended the documentation <details><summary>[XXX]: tried but failed to install sphinx... might try again later</summary> ``` [INFO] Using pre-commit with uv 0.10.7 via pre-commit-uv 4.2.1 An unexpected error has occurred: CalledProcessError: command: ('/home/yoh/proj/misc/tox/.tox/fix/bin/uv', '--project', '/home/yoh/proj/misc/tox', 'pip', 'install', '.', 'sphinx>=9.1') return code: 1 stdout: (none) stderr: Using Python 3.11.12 environment at: py_env-python3 × No solution found when resolving dependencies: ╰─▶ Because the current Python version (3.11.12) does not satisfy Python>=3.12 and sphinx==9.1.0 depends on Python>=3.12, we can conclude that sphinx==9.1.0 cannot be used. And because only sphinx<=9.1.0 is available and you require sphinx>=9.1, we can conclude that your requirements are unsatisfiable. Check the log at /home/yoh/.cache/pre-commit/pre-commit.log fix: exit 3 (24.65 seconds) /home/yoh/proj/misc/tox> pre-commit run --all-files --show-diff-on-failure pid=4127791 fix: FAIL code 3 (25.28=setup[0.62]+cmd[24.65] seconds) evaluation failed :( (25.34 seconds) ``` </details> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a0aefaf commit 9aaec0c

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

docs/changelog/3847.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Handle ``OSError`` when checking if positional arguments are existing paths in ``pos_args()`` — long arguments (e.g.,
2+
pytest ``-k`` expressions exceeding the 255-character filesystem name limit) no longer crash with ``OSError: [Errno 36]
3+
File name too long`` - by :user:`yarikoptic`.

src/tox/config/main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import logging
34
import os
45
from collections import OrderedDict, defaultdict
56
from itertools import chain, tee
@@ -62,7 +63,12 @@ def pos_args(self, to_path: Path | None) -> tuple[str, ...] | None:
6263
to_path_str = os.path.abspath(str(to_path)) # noqa: PTH100
6364
for arg in self._pos_args:
6465
path_arg = Path(arg)
65-
if path_arg.exists() and not path_arg.is_absolute():
66+
try:
67+
is_existing_path = path_arg.exists()
68+
except OSError:
69+
logging.debug("could not check if %r is an existing path", arg)
70+
is_existing_path = False
71+
if is_existing_path and not path_arg.is_absolute():
6672
# we use os.path to unroll .. in path without resolve
6773
path_arg_str = os.path.abspath(str(path_arg)) # noqa: PTH100
6874
try:

tests/config/test_main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ def test_args_are_paths_when_from_child_dir(tox_project: ToxProjectCreator) -> N
235235
assert result.out == f"[testenv:py]\ncommands = magic.py {project.path} tox.ini . ..\n"
236236

237237

238+
def test_args_are_paths_long_arg(tox_project: ToxProjectCreator) -> None:
239+
project = tox_project({"tox.ini": "[testenv]\npackage=skip\ncommands={posargs}", "w": {"a.txt": "a"}})
240+
long_arg = "a" * 300 # exceeds filesystem filename length limit (typically 255)
241+
result = project.run("c", "-e", "py", "-k", "commands", "--", long_arg, from_cwd=project.path / "w")
242+
result.assert_success()
243+
assert result.out == f"[testenv:py]\ncommands = {long_arg}\n"
244+
245+
238246
def test_args_are_paths_when_with_change_dir(tox_project: ToxProjectCreator) -> None:
239247
project = tox_project({"tox.ini": "[testenv]\npackage=skip\ncommands={posargs}\nchange_dir=w", "w": {"a.txt": "a"}})
240248
args = "magic.py", str(project.path), "tox.ini", f"w{os.sep}a.txt", "w", "."

0 commit comments

Comments
 (0)