diff --git a/AUTHORS b/AUTHORS index ba5672d4c51..093d5fd472a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -87,6 +87,7 @@ croc100 Cal Leeming Carl Friedrich Bolz Carlos Jenkins +Cen Fangyu (Dmao233) Ceridwen Charles Cloud Charles Machalow diff --git a/changelog/14953.bugfix.rst b/changelog/14953.bugfix.rst new file mode 100644 index 00000000000..bacb105878e --- /dev/null +++ b/changelog/14953.bugfix.rst @@ -0,0 +1 @@ +The :confval:`max_warnings` configuration option now accepts integer values in TOML configuration files, while still accepting strings for backward compatibility. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index 362d5c917e2..b81be5b5a3a 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -1705,7 +1705,7 @@ passed multiple times. The expected format is ``name=value``. For example:: .. confval:: max_warnings - :type: ``int`` + :type: ``str | int`` .. versionadded:: 9.1 @@ -3671,7 +3671,7 @@ All the command-line flags can also be obtained by running ``pytest --help``:: Each line specifies a pattern for warnings.filterwarnings. Processed after -W/--pythonwarnings. - max_warnings (string): + max_warnings (string | int): Exit with error if all tests pass but the number of warnings exceeds this threshold norecursedirs (args): Directory patterns to avoid for recursion diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 1b337e20c7e..6bcc21b6161 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -141,9 +141,13 @@ def pytest_addoption(parser: Parser) -> None: "warnings.filterwarnings. " "Processed after -W/--pythonwarnings.", ) + # ``str | int`` (not plain ``int``) so INI files and ``-o`` keep returning + # strings, while native TOML integers are still accepted. parser.addini( "max_warnings", help="Exit with error if all tests pass but the number of warnings exceeds this threshold", + type=str | int, + default="", ) group = parser.getgroup("collect", "collection") diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 825435225b3..c1ee3f12ff6 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -1093,9 +1093,9 @@ def _get_max_warnings(self) -> int | None: if value is not None: return int(value) ini_value = self.config.getini("max_warnings") - if ini_value: - return int(ini_value) - return None + if ini_value == "": + return None + return int(ini_value) # # Summaries for sessionfinish. diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 017781c2355..2b92670e15e 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -1145,6 +1145,28 @@ def test_one(): result.assert_outcomes(passed=1, warnings=1) assert result.ret == ExitCode.OK + @pytest.mark.filterwarnings("default::UserWarning") + def test_max_warnings_toml_native_int_zero(self, pytester: Pytester) -> None: + """Unquoted native TOML integer 0 is accepted and enforced (#14953).""" + pytester.maketoml( + """ + [pytest] + max_warnings = 0 + """ + ) + pytester.makepyfile( + """ + import warnings + def test_warning(): + warnings.warn(UserWarning("example warning")) + """ + ) + result = pytester.runpytest() + assert result.ret == ExitCode.MAX_WARNINGS_ERROR + result.stdout.fnmatch_lines( + ["*Tests pass, but maximum allowed warnings exceeded: 1 > 0*"] + ) + def test_pythonwarnings_not_duplicated(pytester: Pytester) -> None: """Regression test for #13484: -W values should not be duplicated in