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
.. versionchanged:: 3.9
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` if no other warning filters
are configured.
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning``.
To disable showing ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings, you might define any warnings
filter either in the command-line or in the ini file, or you can use:
Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
(such as third-party libraries), in which case you might use the standard warning filters options (ini or marks).
For example:
.. code-block:: ini
[pytest]
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
ignore:.*U.*mode is deprecated:DeprecationWarning
.. 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
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>`_

View File

@ -70,7 +70,11 @@ def catch_warnings_for_item(config, ihook, when, item):
cmdline_filters = config.getoption("pythonwarnings") or []
inifilters = config.getini("filterwarnings")
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 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 arg in mark.args:
_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

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)
if customize_filters:
testdir.makeini(
"""
[pytest]
filterwarnings =
once::UserWarning
"""
)
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(
[
@ -512,7 +522,9 @@ class TestDeprecationWarningsByDefault:
testdir.makeini(
"""
[pytest]
filterwarnings = once::UserWarning
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
"""
)
result = testdir.runpytest_subprocess()
@ -523,7 +535,8 @@ class TestDeprecationWarningsByDefault:
be displayed normally.
"""
self.create_file(
testdir, mark='@pytest.mark.filterwarnings("once::UserWarning")'
testdir,
mark='@pytest.mark.filterwarnings("ignore::PendingDeprecationWarning")',
)
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(
@ -536,7 +549,12 @@ class TestDeprecationWarningsByDefault:
def test_hidden_by_cmdline(self, 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()
def test_hidden_by_system(self, testdir, monkeypatch):