From bcd4f9ba6857d9f7e8879c1eccfb024a2e3ecac7 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 10 Sep 2025 09:59:37 +0300 Subject: [PATCH] main: reject arguments like `pytest x.py[1]` instead of ignoring the `[]` Fix #13716. --- changelog/13716.bugfix.rst | 1 + src/_pytest/main.py | 6 ++++-- testing/test_main.py | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 changelog/13716.bugfix.rst diff --git a/changelog/13716.bugfix.rst b/changelog/13716.bugfix.rst new file mode 100644 index 00000000000..5eeef4b7624 --- /dev/null +++ b/changelog/13716.bugfix.rst @@ -0,0 +1 @@ +Fixed a bug where a nonsensical invocation like ``pytest x.py[a]`` (a file cannot be parametrized) was silently treated as ``pytest x.py``. This is now a usage error. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 6e35c887814..b1eb22f1f61 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -1066,9 +1066,11 @@ def resolve_collection_argument( If the path doesn't exist, raise UsageError. If the path is a directory and selection parts are present, raise UsageError. """ - base, squacket, rest = str(arg).partition("[") + base, squacket, rest = arg.partition("[") strpath, *parts = base.split("::") - if parts: + if squacket: + if not parts: + raise UsageError(f"path cannot contain [] parametrization: {arg}") parts[-1] = f"{parts[-1]}{squacket}{rest}" module_name = None if as_pypath: diff --git a/testing/test_main.py b/testing/test_main.py index 4a5591bb361..3f173ec4e9f 100644 --- a/testing/test_main.py +++ b/testing/test_main.py @@ -220,6 +220,20 @@ def test_parametrized_name_with_colons(self, invocation_path: Path) -> None: module_name=None, ) + @pytest.mark.parametrize( + "arg", ["x.py[a]", "x.py[a]::foo", "x/y.py[a]::foo::bar", "x.py[a]::foo[b]"] + ) + def test_path_parametrization_not_allowed( + self, invocation_path: Path, arg: str + ) -> None: + with pytest.raises( + UsageError, match=r"path cannot contain \[\] parametrization" + ): + resolve_collection_argument( + invocation_path, + arg, + ) + def test_does_not_exist(self, invocation_path: Path) -> None: """Given a file/module that does not exist raises UsageError.""" with pytest.raises(