From ee57a2ad451e813b99ac49e8ead1657f57b8d420 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Sat, 14 Jan 2023 22:28:33 +0300 Subject: [PATCH 1/4] Check if config args and args_source exist --- AUTHORS | 1 + changelog/10626.bugfix.rst | 1 + src/_pytest/main.py | 2 +- src/_pytest/terminal.py | 6 ++++-- testing/python/fixtures.py | 4 ++++ 5 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 changelog/10626.bugfix.rst diff --git a/AUTHORS b/AUTHORS index 7cf1748e606..f345c0cab93 100644 --- a/AUTHORS +++ b/AUTHORS @@ -290,6 +290,7 @@ Prashant Sharma Pulkit Goyal Punyashloka Biswal Quentin Pradet +q0w Ralf Schmitt Ralph Giles Ram Rachum diff --git a/changelog/10626.bugfix.rst b/changelog/10626.bugfix.rst new file mode 100644 index 00000000000..510b05cdfc1 --- /dev/null +++ b/changelog/10626.bugfix.rst @@ -0,0 +1 @@ +Check if ``Config.args`` and ``Config.args_source`` exist. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 61fb7eaa4e3..8bbc1eec14b 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -619,7 +619,7 @@ def perform_collect( # noqa: F811 and ``session.items`` is empty. """ if args is None: - args = self.config.args + args = self.config.args if hasattr(self.config, "args") else () self.trace("perform_collect", self, args) self.trace.root.indent += 1 diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index d967a3ee6f1..34bc9719eee 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -737,8 +737,10 @@ def pytest_report_header(self, config: Config) -> List[str]: if config.inipath: line += ", configfile: " + bestrelpath(config.rootpath, config.inipath) - - if config.args_source == Config.ArgsSource.TESTPATHS: + if ( + hasattr(config, "args_source") + and config.args_source == Config.ArgsSource.TESTPATHS + ): testpaths: List[str] = config.getini("testpaths") line += ", testpaths: {}".format(", ".join(testpaths)) diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 3ce5cb34ddd..d996f80bb93 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -3338,6 +3338,10 @@ def test_funcarg_compat(self, pytester: Pytester) -> None: config = pytester.parseconfigure("--funcargs") assert config.option.showfixtures + def test_show_help(self, pytester: Pytester) -> None: + result = pytester.runpytest("--fixtures", "--help") + assert not result.ret + def test_show_fixtures(self, pytester: Pytester) -> None: result = pytester.runpytest("--fixtures") result.stdout.fnmatch_lines( From 00c8beab45589849a3a8fe6f6ca080f2c65e630b Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:27:45 +0300 Subject: [PATCH 2/4] Update changelog/10626.bugfix.rst Co-authored-by: Bruno Oliveira --- changelog/10626.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/10626.bugfix.rst b/changelog/10626.bugfix.rst index 510b05cdfc1..c3c7ef77840 100644 --- a/changelog/10626.bugfix.rst +++ b/changelog/10626.bugfix.rst @@ -1 +1 @@ -Check if ``Config.args`` and ``Config.args_source`` exist. +Fix crash if ``--fixtures`` and ``--help`` are passed at the same time. From 72918bc05049d99c4dcceed261bb25b87ea25982 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Fri, 20 Jan 2023 01:50:22 +0300 Subject: [PATCH 3/4] Init config args and args_source --- src/_pytest/config/__init__.py | 3 ++- src/_pytest/main.py | 2 +- src/_pytest/terminal.py | 6 ++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 25f156f8b20..e9f7d3cf29c 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -998,6 +998,7 @@ def __init__( self.hook.pytest_addoption.call_historic( kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager) ) + self.args_source = Config.ArgsSource.ARGS if TYPE_CHECKING: from _pytest.cacheprovider import Cache @@ -1368,7 +1369,7 @@ def parse(self, args: List[str], addopts: bool = True) -> None: self.args = args self.args_source = source except PrintHelp: - pass + self.args = [] def issue_config_time_warning(self, warning: Warning, stacklevel: int) -> None: """Issue and handle a warning during the "configure" stage. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 8bbc1eec14b..61fb7eaa4e3 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -619,7 +619,7 @@ def perform_collect( # noqa: F811 and ``session.items`` is empty. """ if args is None: - args = self.config.args if hasattr(self.config, "args") else () + args = self.config.args self.trace("perform_collect", self, args) self.trace.root.indent += 1 diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 34bc9719eee..d967a3ee6f1 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -737,10 +737,8 @@ def pytest_report_header(self, config: Config) -> List[str]: if config.inipath: line += ", configfile: " + bestrelpath(config.rootpath, config.inipath) - if ( - hasattr(config, "args_source") - and config.args_source == Config.ArgsSource.TESTPATHS - ): + + if config.args_source == Config.ArgsSource.TESTPATHS: testpaths: List[str] = config.getini("testpaths") line += ", testpaths: {}".format(", ".join(testpaths)) From 656fafc7434fbf5debe97f7db268b07cd4becbf0 Mon Sep 17 00:00:00 2001 From: pytest bot Date: Sat, 21 Jan 2023 07:51:29 -0300 Subject: [PATCH 4/4] Init args in __init__ as well --- src/_pytest/config/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index e9f7d3cf29c..bd2611df6b1 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -999,6 +999,7 @@ def __init__( kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager) ) self.args_source = Config.ArgsSource.ARGS + self.args: List[str] = [] if TYPE_CHECKING: from _pytest.cacheprovider import Cache @@ -1338,8 +1339,8 @@ def _get_unknown_ini_keys(self) -> List[str]: def parse(self, args: List[str], addopts: bool = True) -> None: # Parse given cmdline arguments into this config object. - assert not hasattr( - self, "args" + assert ( + self.args == [] ), "can only parse cmdline args at most once per Config object" self.hook.pytest_addhooks.call_historic( kwargs=dict(pluginmanager=self.pluginmanager) @@ -1369,7 +1370,7 @@ def parse(self, args: List[str], addopts: bool = True) -> None: self.args = args self.args_source = source except PrintHelp: - self.args = [] + pass def issue_config_time_warning(self, warning: Warning, stacklevel: int) -> None: """Issue and handle a warning during the "configure" stage.