From a4a189ad99b2a7c3536de30009bb8111a0cf176e Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Fri, 23 Jun 2023 14:36:48 +0300 Subject: [PATCH] Change PytestRemovedIn8Warning to error by default Per our backward compatibility policy. --- changelog/7363.breaking.rst | 22 ++++++++++++++++++++++ src/_pytest/warnings.py | 2 ++ testing/acceptance_test.py | 6 ++---- testing/deprecated_test.py | 14 +++++++------- testing/test_config.py | 2 +- testing/test_nose.py | 22 ++++++++++++++++------ testing/test_warnings.py | 3 ++- 7 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 changelog/7363.breaking.rst diff --git a/changelog/7363.breaking.rst b/changelog/7363.breaking.rst new file mode 100644 index 000000000..93d87b1b1 --- /dev/null +++ b/changelog/7363.breaking.rst @@ -0,0 +1,22 @@ +**PytestRemovedIn8Warning deprecation warnings are now errors by default.** + +Following our plan to remove deprecated features with as little disruption as +possible, all warnings of type ``PytestRemovedIn8Warning`` now generate errors +instead of warning messages by default. + +**The affected features will be effectively removed in pytest 8.1**, so please consult the +:ref:`deprecations` section in the docs for directions on how to update existing code. + +In the pytest ``8.0.X`` series, it is possible to change the errors back into warnings as a +stopgap measure by adding this to your ``pytest.ini`` file: + +.. code-block:: ini + + [pytest] + filterwarnings = + ignore::pytest.PytestRemovedIn8Warning + +But this will stop working when pytest ``8.1`` is released. + +**If you have concerns** about the removal of a specific feature, please add a +comment to :issue:`7363`. diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index 4aaa94452..bb293ec08 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -49,6 +49,8 @@ def catch_warnings_for_item( warnings.filterwarnings("always", category=DeprecationWarning) warnings.filterwarnings("always", category=PendingDeprecationWarning) + warnings.filterwarnings("error", category=pytest.PytestRemovedIn8Warning) + apply_warning_filters(config_filters, cmdline_filters) # apply filters from "filterwarnings" marks diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 5658f2fd6..de9e92d00 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1164,7 +1164,6 @@ def test_usage_error_code(pytester: Pytester) -> None: assert result.ret == ExitCode.USAGE_ERROR -@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning") def test_warn_on_async_function(pytester: Pytester) -> None: # In the below we .close() the coroutine only to avoid # "RuntimeWarning: coroutine 'test_2' was never awaited" @@ -1181,7 +1180,7 @@ def test_warn_on_async_function(pytester: Pytester) -> None: return coro """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Wdefault") result.stdout.fnmatch_lines( [ "test_async.py::test_1", @@ -1197,7 +1196,6 @@ def test_warn_on_async_function(pytester: Pytester) -> None: ) -@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning") def test_warn_on_async_gen_function(pytester: Pytester) -> None: pytester.makepyfile( test_async=""" @@ -1209,7 +1207,7 @@ def test_warn_on_async_gen_function(pytester: Pytester) -> None: return test_2() """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Wdefault") result.stdout.fnmatch_lines( [ "test_async.py::test_1", diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 3ceed7f5a..50eedb83c 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -103,7 +103,7 @@ def test_strict_option_is_deprecated(pytester: Pytester) -> None: def test_foo(): pass """ ) - result = pytester.runpytest("--strict") + result = pytester.runpytest("--strict", "-Wdefault::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines( [ "'unknown' not found in `markers` configuration option", @@ -189,7 +189,7 @@ class TestSkipMsgArgumentDeprecated: pytest.skip(msg="skippedmsg") """ ) - result = pytester.runpytest(p) + result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines( [ "*PytestRemovedIn8Warning: pytest.skip(msg=...) is now deprecated, " @@ -208,7 +208,7 @@ class TestSkipMsgArgumentDeprecated: pytest.fail(msg="failedmsg") """ ) - result = pytester.runpytest(p) + result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines( [ "*PytestRemovedIn8Warning: pytest.fail(msg=...) is now deprecated, " @@ -227,7 +227,7 @@ class TestSkipMsgArgumentDeprecated: pytest.exit(msg="exitmsg") """ ) - result = pytester.runpytest(p) + result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines( [ "*PytestRemovedIn8Warning: pytest.exit(msg=...) is now deprecated, " @@ -245,7 +245,7 @@ def test_deprecation_of_cmdline_preparse(pytester: Pytester) -> None: """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Wdefault::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines( [ "*PytestRemovedIn8Warning: The pytest_cmdline_preparse hook is deprecated*", @@ -299,7 +299,7 @@ def test_nose_deprecated_with_setup(pytester: Pytester) -> None: ... """ ) - output = pytester.runpytest() + output = pytester.runpytest("-Wdefault::pytest.PytestRemovedIn8Warning") message = [ "*PytestRemovedIn8Warning: Support for nose tests is deprecated and will be removed in a future release.", "*test_nose_deprecated_with_setup.py::test_omits_warnings is using nose method: `setup_fn_no_op` (setup)", @@ -327,7 +327,7 @@ def test_nose_deprecated_setup_teardown(pytester: Pytester) -> None: ... """ ) - output = pytester.runpytest() + output = pytester.runpytest("-Wdefault::pytest.PytestRemovedIn8Warning") message = [ "*PytestRemovedIn8Warning: Support for nose tests is deprecated and will be removed in a future release.", "*test_nose_deprecated_setup_teardown.py::Test::test is using nose-specific method: `setup(self)`", diff --git a/testing/test_config.py b/testing/test_config.py index 3aec5d763..257d696fa 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1184,7 +1184,7 @@ def test_cmdline_processargs_simple(pytester: Pytester) -> None: args.append("-h") """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Wignore::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines(["*pytest*", "*-h*"]) diff --git a/testing/test_nose.py b/testing/test_nose.py index e838e79dd..cc79eb45b 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -23,7 +23,9 @@ def test_nose_setup(pytester: Pytester) -> None: test_hello.teardown = lambda: values.append(2) """ ) - result = pytester.runpytest(p, "-p", "nose") + result = pytester.runpytest( + p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" + ) result.assert_outcomes(passed=2) @@ -76,7 +78,9 @@ def test_nose_setup_func(pytester: Pytester) -> None: """ ) - result = pytester.runpytest(p, "-p", "nose") + result = pytester.runpytest( + p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" + ) result.assert_outcomes(passed=2) @@ -100,7 +104,9 @@ def test_nose_setup_func_failure(pytester: Pytester) -> None: """ ) - result = pytester.runpytest(p, "-p", "nose") + result = pytester.runpytest( + p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" + ) result.stdout.fnmatch_lines(["*TypeError: ()*"]) @@ -154,7 +160,9 @@ def test_nose_setup_partial(pytester: Pytester) -> None: test_hello.teardown = my_teardown_partial """ ) - result = pytester.runpytest(p, "-p", "nose") + result = pytester.runpytest( + p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" + ) result.stdout.fnmatch_lines(["*2 passed*"]) @@ -193,7 +201,9 @@ def test_module_level_setup(pytester: Pytester) -> None: assert items["setup2"] == ["up", "down", "up"] """ ) - result = pytester.runpytest("-p", "nose") + result = pytester.runpytest( + "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" + ) result.stdout.fnmatch_lines(["*4 passed*"]) @@ -278,7 +288,7 @@ def test_nose_setup_ordering(pytester: Pytester) -> None: assert self.visited_cls """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Wignore::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines(["*1 passed*"]) diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 03846cb30..96ecad6f6 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -518,7 +518,8 @@ class TestDeprecationWarningsByDefault: assert WARNINGS_SUMMARY_HEADER not in result.stdout.str() -@pytest.mark.skip("not relevant until pytest 8.0") +# In 8.1, uncomment below and change RemovedIn8 -> RemovedIn9. +# @pytest.mark.skip("not relevant until pytest 9.0") @pytest.mark.parametrize("change_default", [None, "ini", "cmdline"]) def test_removed_in_x_warning_as_error(pytester: Pytester, change_default) -> None: """This ensures that PytestRemovedInXWarnings raised by pytest are turned into errors.