From b9aec6777a8a3ac5db2cbbbb37fa0b6498094037 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 27 Jul 2025 13:55:12 +0200 Subject: [PATCH] tests: Fix monkeypatching of sys.flags on Python 3.14 With Python 3.14, since argparse enabled coloring by default: https://github.com/python/cpython/commit/17c5959aa3daee4b63d78e944a1d355daa651e52 running test_cmdutils.py failed with a lengthy traceback finishing in: ``` INTERNALERROR> pluggy.PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown. INTERNALERROR> Plugin: /home/florian/proj/qutebrowser/git/tests/conftest.py, Hook: pytest_runtest_makereport INTERNALERROR> PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown. INTERNALERROR> Plugin: rerunfailures, Hook: pytest_runtest_makereport INTERNALERROR> PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown. INTERNALERROR> Plugin: hypothesispytest, Hook: pytest_runtest_makereport INTERNALERROR> PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown. INTERNALERROR> Plugin: pytest-bdd, Hook: pytest_runtest_makereport INTERNALERROR> AttributeError: 'types.SimpleNamespace' object has no attribute 'verbose' ``` with one part pointing to Python internals: ```pytb INTERNALERROR> File "/home/florian/proj/qutebrowser/git/.tox/py314-pyqt68/lib/python3.14/site-packages/_pytest/_code/code.py", line 669, in exconly INTERNALERROR> lines = format_exception_only(self.type, self.value) INTERNALERROR> File "/usr/lib/python3.14/traceback.py", line 180, in format_exception_only INTERNALERROR> te = TracebackException(type(value), value, None, compact=True) INTERNALERROR> File "/usr/lib/python3.14/traceback.py", line 1106, in __init__ INTERNALERROR> suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) INTERNALERROR> File "/usr/lib/python3.14/traceback.py", line 1653, in _compute_suggestion_error INTERNALERROR> import _suggestions INTERNALERROR> File "", line 1371, in _find_and_load INTERNALERROR> File "", line 1342, in _find_and_load_unlocked INTERNALERROR> File "", line 951, in _load_unlocked INTERNALERROR> File "", line 496, in _verbose_message INTERNALERROR> AttributeError: 'types.SimpleNamespace' object has no attribute 'verbose' ``` This happens when Python tries to access sys.flags.verbose, but we replaced it with a fake object that does not have a .verbose attribute anymore (only temporarily, but for some reason that's enough to trigger the issue anyways). Since we can't mutate sys.flags, instead we create an object that copies all sys.flags attributes, and then use that as a nicer replacement. See #8529 --- tests/unit/api/test_cmdutils.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/unit/api/test_cmdutils.py b/tests/unit/api/test_cmdutils.py index 799ddfcab..61c9534b5 100644 --- a/tests/unit/api/test_cmdutils.py +++ b/tests/unit/api/test_cmdutils.py @@ -8,6 +8,7 @@ import sys import logging import types import enum +import inspect import textwrap import pytest @@ -440,7 +441,15 @@ class TestArgument: def test_no_docstring_with_optimize(self, monkeypatch): """With -OO we'd get a warning on start, but no warning afterwards.""" - monkeypatch.setattr(sys, 'flags', types.SimpleNamespace(optimize=2)) + sys_flags_fake = types.SimpleNamespace( + { + k: v + for k, v in inspect.getmembers(sys.flags) + if not k.startswith("_") and k not in {"count", "index"} + } + ) + sys_flags_fake.optimize = 2 + monkeypatch.setattr(sys, 'flags', sys_flags_fake) @cmdutils.register() def fun():