From 37883089fac2d7529cb2fa07ebab6a46b9b26564 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 10 Feb 2024 20:12:42 -0300 Subject: [PATCH] Consider paths and pathlists relative to cwd in case of an absent ini-file Previously this would trigger an `AssertionError`. While it could be considered a bug-fix, but given it now can be relied upon, it is probably better to consider it an improvement. Fix #11311 --- changelog/11311.improvement.rst | 4 ++++ src/_pytest/config/__init__.py | 4 +--- src/_pytest/config/argparsing.py | 7 +++++++ testing/test_config.py | 12 ++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 changelog/11311.improvement.rst diff --git a/changelog/11311.improvement.rst b/changelog/11311.improvement.rst new file mode 100644 index 00000000000..0072f39743a --- /dev/null +++ b/changelog/11311.improvement.rst @@ -0,0 +1,4 @@ +When using ``--override-ini`` for paths in invocations without a configuration file defined, the current working directory is used +as the relative directory. + +Previoulsy this would raise an :class:`AssertionError`. diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index cada2aa0978..46b1ba3d99a 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1563,9 +1563,7 @@ def _getini(self, name: str): # in this case, we already have a list ready to use. # if type == "paths": - # TODO: This assert is probably not valid in all cases. - assert self.inipath is not None - dp = self.inipath.parent + dp = self.inipath.parent if self.inipath is not None else Path.cwd() input_values = shlex.split(value) if isinstance(value, str) else value return [dp / x for x in input_values] elif type == "args": diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index da05acf398e..d98f1ae9a12 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -198,9 +198,16 @@ def addini( * ``paths``: a list of :class:`pathlib.Path`, separated as in a shell * ``pathlist``: a list of ``py.path``, separated as in a shell + For ``paths`` and ``pathlist`` types, they are considered relative to the ini-file. + In case the execution is happening without an ini-file defined, + they will be considered relative to the current working directory (for example with ``--override-ini``). + .. versionadded:: 7.0 The ``paths`` variable type. + .. versionadded:: 8.1 + Use the current working directory to resolve ``paths`` and ``pathlist`` in the absence of an ini-file. + Defaults to ``string`` if ``None`` or not passed. :param default: Default value if no ini-file option exists but is queried. diff --git a/testing/test_config.py b/testing/test_config.py index ead693cf48b..4377257b12e 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1874,6 +1874,18 @@ def test(): assert "ERROR:" not in result.stderr.str() result.stdout.fnmatch_lines(["collected 1 item", "*= 1 passed in *="]) + def test_override_ini_without_config_file(self, pytester: Pytester) -> None: + pytester.makepyfile(**{"src/override_ini_without_config_file.py": ""}) + pytester.makepyfile( + **{ + "tests/test_override_ini_without_config_file.py": ( + "import override_ini_without_config_file\ndef test(): pass" + ), + } + ) + result = pytester.runpytest("--override-ini", "pythonpath=src") + assert result.parseoutcomes() == {"passed": 1} + def test_help_via_addopts(pytester: Pytester) -> None: pytester.makeini(