Show deprecation warnings even if filters are customized

Fix #4013
This commit is contained in:
Bruno Oliveira 2018-09-22 08:27:53 -03:00
parent 83802d1494
commit c30184709d
4 changed files with 42 additions and 18 deletions

View File

@ -0,0 +1,2 @@
Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version
any customization would override pytest's filters and deprecation warnings would fall back to being hidden by default.

View File

@ -101,22 +101,28 @@ DeprecationWarning and PendingDeprecationWarning
------------------------------------------------ ------------------------------------------------
.. versionadded:: 3.8 .. versionadded:: 3.8
.. versionchanged:: 3.9
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` if no other warning filters By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning``.
are configured.
To disable showing ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings, you might define any warnings Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
filter either in the command-line or in the ini file, or you can use: (such as third-party libraries), in which case you might use the standard warning filters options (ini or marks).
For example:
.. code-block:: ini .. code-block:: ini
[pytest] [pytest]
filterwarnings = filterwarnings =
ignore::DeprecationWarning ignore:.*U.*mode is deprecated:DeprecationWarning
ignore::PendingDeprecationWarning
.. note:: .. note::
This makes pytest more compliant with `PEP-0506 <https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners>`_ which suggests that those warnings should If warnings are configured at the interpreter level, using
the `PYTHONWARNINGS <https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS>`_ environment variable or the
``-W`` command-line option, pytest will not configure any filters by default.
.. note::
This feature makes pytest more compliant with `PEP-0506 <https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners>`_ which suggests that those warnings should
be shown by default by test runners, but pytest doesn't follow ``PEP-0506`` completely because resetting all be shown by default by test runners, but pytest doesn't follow ``PEP-0506`` completely because resetting all
warning filters like suggested in the PEP will break existing test suites that configure warning filters themselves warning filters like suggested in the PEP will break existing test suites that configure warning filters themselves
by calling ``warnings.simplefilter`` (see issue `#2430 <https://github.com/pytest-dev/pytest/issues/2430>`_ by calling ``warnings.simplefilter`` (see issue `#2430 <https://github.com/pytest-dev/pytest/issues/2430>`_

View File

@ -70,7 +70,11 @@ def catch_warnings_for_item(config, ihook, when, item):
cmdline_filters = config.getoption("pythonwarnings") or [] cmdline_filters = config.getoption("pythonwarnings") or []
inifilters = config.getini("filterwarnings") inifilters = config.getini("filterwarnings")
with warnings.catch_warnings(record=True) as log: with warnings.catch_warnings(record=True) as log:
filters_configured = bool(cmdline_filters or inifilters or sys.warnoptions)
if not sys.warnoptions:
# if user is not explicitly configuring warning filters, show deprecation warnings by default (#2908)
warnings.filterwarnings("always", category=DeprecationWarning)
warnings.filterwarnings("always", category=PendingDeprecationWarning)
# filters should have this precedence: mark, cmdline options, ini # filters should have this precedence: mark, cmdline options, ini
# filters should be applied in the inverse order of precedence # filters should be applied in the inverse order of precedence
@ -84,12 +88,6 @@ def catch_warnings_for_item(config, ihook, when, item):
for mark in item.iter_markers(name="filterwarnings"): for mark in item.iter_markers(name="filterwarnings"):
for arg in mark.args: for arg in mark.args:
_setoption(warnings, arg) _setoption(warnings, arg)
filters_configured = True
if not filters_configured:
# if user is not explicitly configuring warning filters, show deprecation warnings by default (#2908)
warnings.filterwarnings("always", category=DeprecationWarning)
warnings.filterwarnings("always", category=PendingDeprecationWarning)
yield yield

View File

@ -495,8 +495,18 @@ class TestDeprecationWarningsByDefault:
) )
) )
def test_shown_by_default(self, testdir): @pytest.mark.parametrize("customize_filters", [True, False])
def test_shown_by_default(self, testdir, customize_filters):
"""Show deprecation warnings by default, even if user has customized the warnings filters (#4013)."""
self.create_file(testdir) self.create_file(testdir)
if customize_filters:
testdir.makeini(
"""
[pytest]
filterwarnings =
once::UserWarning
"""
)
result = testdir.runpytest_subprocess() result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
[ [
@ -512,7 +522,9 @@ class TestDeprecationWarningsByDefault:
testdir.makeini( testdir.makeini(
""" """
[pytest] [pytest]
filterwarnings = once::UserWarning filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
""" """
) )
result = testdir.runpytest_subprocess() result = testdir.runpytest_subprocess()
@ -523,7 +535,8 @@ class TestDeprecationWarningsByDefault:
be displayed normally. be displayed normally.
""" """
self.create_file( self.create_file(
testdir, mark='@pytest.mark.filterwarnings("once::UserWarning")' testdir,
mark='@pytest.mark.filterwarnings("ignore::PendingDeprecationWarning")',
) )
result = testdir.runpytest_subprocess() result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
@ -536,7 +549,12 @@ class TestDeprecationWarningsByDefault:
def test_hidden_by_cmdline(self, testdir): def test_hidden_by_cmdline(self, testdir):
self.create_file(testdir) self.create_file(testdir)
result = testdir.runpytest_subprocess("-W", "once::UserWarning") result = testdir.runpytest_subprocess(
"-W",
"ignore::DeprecationWarning",
"-W",
"ignore::PendingDeprecationWarning",
)
assert WARNINGS_SUMMARY_HEADER not in result.stdout.str() assert WARNINGS_SUMMARY_HEADER not in result.stdout.str()
def test_hidden_by_system(self, testdir, monkeypatch): def test_hidden_by_system(self, testdir, monkeypatch):