Merge pull request #4019 from nicoddemus/deprecation-warnings-4013

Show deprecation warnings even if filters are customized
This commit is contained in:
Bruno Oliveira 2018-09-22 18:17:07 -03:00 committed by GitHub
commit 42afce27b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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):