diff --git a/changelog/13484.bugfix.rst b/changelog/13484.bugfix.rst new file mode 100644 index 00000000000..7a37410bce9 --- /dev/null +++ b/changelog/13484.bugfix.rst @@ -0,0 +1 @@ +Fixed ``known_args_namespace`` containing duplicate values for append-action arguments like ``-W`` due to re-parsing into the same namespace. diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 21dc35219d8..0c7c5e1a58e 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1358,7 +1358,7 @@ def _validate_args(self, args: list[str], via: str) -> list[str]: self._parser.extra_info["config source"] = via try: self._parser.parse_known_and_unknown_args( - args, namespace=copy.copy(self.option) + args, namespace=copy.deepcopy(self.option) ) finally: self._parser.extra_info.pop("config source", None) @@ -1500,7 +1500,7 @@ def parse(self, args: list[str], addopts: bool = True) -> None: + args ) - ns = self._parser.parse_known_args(args, namespace=copy.copy(self.option)) + ns = self._parser.parse_known_args(args, namespace=copy.deepcopy(self.option)) rootpath, inipath, inicfg, ignored_config_files = determine_setup( inifile=ns.inifilename, override_ini=ns.override_ini, @@ -1533,7 +1533,7 @@ def parse(self, args: list[str], addopts: bool = True) -> None: ) self.known_args_namespace = self._parser.parse_known_args( - args, namespace=copy.copy(self.option) + args, namespace=copy.deepcopy(self.option) ) self._checkversion() self._consider_importhook() @@ -1550,7 +1550,9 @@ def parse(self, args: list[str], addopts: bool = True) -> None: # are going to be loaded. self.pluginmanager.consider_env() - self._parser.parse_known_args(args, namespace=self.known_args_namespace) + self.known_args_namespace = self._parser.parse_known_args( + args, namespace=copy.deepcopy(self.option) + ) self._validate_plugins() self._warn_about_skipped_plugins() diff --git a/testing/test_config.py b/testing/test_config.py index de11e3fa13a..fbd3b9ece5a 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -2327,6 +2327,12 @@ def test_addopts_from_ini_not_concatenated(self, pytester: Pytester) -> None: ) assert result.ret == _pytest.config.ExitCode.USAGE_ERROR + def test_append_args_not_duplicated(self, _config_for_test, _sys_snapshot) -> None: + """Append-action args should not be duplicated after multiple parses (#13484).""" + config = _config_for_test + config.parse(["-Werror"], addopts=True) + assert config.known_args_namespace.pythonwarnings == ["error"] + def test_override_ini_does_not_contain_paths( self, _config_for_test, _sys_snapshot ) -> None: