From 6e7da336387fdc6403d3d9847e5a47602c52a6cc Mon Sep 17 00:00:00 2001 From: Friday Date: Wed, 18 Feb 2026 03:55:48 +0000 Subject: [PATCH 1/2] Fix known_args_namespace containing duplicate append-action values The third parse_known_args call re-parsed into the existing known_args_namespace, causing append-action arguments like -W to be duplicated. Additionally, replace copy.copy with copy.deepcopy for all namespace copies to prevent shared mutable state between parses. Fixes #13484 Co-Authored-By: Claude Opus 4.6 --- changelog/13484.bugfix.rst | 1 + src/_pytest/config/__init__.py | 10 ++++++---- testing/test_config.py | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 changelog/13484.bugfix.rst 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..00e914e8c88 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -2327,6 +2327,14 @@ 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: From 079e69e35be19ee90dfa7a197b583e85c80d384a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 03:56:33 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- testing/test_config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing/test_config.py b/testing/test_config.py index 00e914e8c88..fbd3b9ece5a 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -2327,9 +2327,7 @@ 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: + 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)