From 43e8576ca3403484f65a603bd748576e21d57f11 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 15 Jun 2019 11:40:08 -0300 Subject: [PATCH] Make pytest warnings show as from 'pytest' module instead of '_pytest.warning_types' When we configure warnings as errors, users see error messages like this: def test(): > warnings.warn(pytest.PytestWarning("some warning")) E _pytest.warning_types.PytestWarning: some warning This is a problem because suggests the user should use `_pytest.warning_types.PytestWarning` to configure their warning filters, which is not nice. This commit changes the message to: def test(): > warnings.warn(pytest.PytestWarning("some warning")) E pytest.PytestWarning: some warning --- changelog/5452.feature.rst | 1 + src/_pytest/warning_types.py | 20 +++++++++++++++++++ testing/test_warning_types.py | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 changelog/5452.feature.rst create mode 100644 testing/test_warning_types.py diff --git a/changelog/5452.feature.rst b/changelog/5452.feature.rst new file mode 100644 index 000000000..4e47e971e --- /dev/null +++ b/changelog/5452.feature.rst @@ -0,0 +1 @@ +When warnings are configured as errors, pytest warnings now appear as originating from ``pytest.`` instead of the internal ``_pytest.warning_types.`` module. diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py index d7d37b4bb..ac7e5ca48 100644 --- a/src/_pytest/warning_types.py +++ b/src/_pytest/warning_types.py @@ -8,6 +8,8 @@ class PytestWarning(UserWarning): Base class for all warnings emitted by pytest. """ + __module__ = "pytest" + class PytestAssertRewriteWarning(PytestWarning): """ @@ -16,6 +18,8 @@ class PytestAssertRewriteWarning(PytestWarning): Warning emitted by the pytest assert rewrite module. """ + __module__ = "pytest" + class PytestCacheWarning(PytestWarning): """ @@ -24,6 +28,8 @@ class PytestCacheWarning(PytestWarning): Warning emitted by the cache plugin in various situations. """ + __module__ = "pytest" + class PytestConfigWarning(PytestWarning): """ @@ -32,6 +38,8 @@ class PytestConfigWarning(PytestWarning): Warning emitted for configuration issues. """ + __module__ = "pytest" + class PytestCollectionWarning(PytestWarning): """ @@ -40,6 +48,8 @@ class PytestCollectionWarning(PytestWarning): Warning emitted when pytest is not able to collect a file or symbol in a module. """ + __module__ = "pytest" + class PytestDeprecationWarning(PytestWarning, DeprecationWarning): """ @@ -48,6 +58,8 @@ class PytestDeprecationWarning(PytestWarning, DeprecationWarning): Warning class for features that will be removed in a future version. """ + __module__ = "pytest" + class PytestExperimentalApiWarning(PytestWarning, FutureWarning): """ @@ -57,6 +69,8 @@ class PytestExperimentalApiWarning(PytestWarning, FutureWarning): removed completely in future version """ + __module__ = "pytest" + @classmethod def simple(cls, apiname): return cls( @@ -75,6 +89,8 @@ class PytestUnhandledCoroutineWarning(PytestWarning): are not natively supported. """ + __module__ = "pytest" + class PytestUnknownMarkWarning(PytestWarning): """ @@ -84,6 +100,8 @@ class PytestUnknownMarkWarning(PytestWarning): See https://docs.pytest.org/en/latest/mark.html for details. """ + __module__ = "pytest" + class RemovedInPytest4Warning(PytestDeprecationWarning): """ @@ -92,6 +110,8 @@ class RemovedInPytest4Warning(PytestDeprecationWarning): Warning class for features scheduled to be removed in pytest 4.0. """ + __module__ = "pytest" + @attr.s class UnformattedWarning: diff --git a/testing/test_warning_types.py b/testing/test_warning_types.py new file mode 100644 index 000000000..f16d7252a --- /dev/null +++ b/testing/test_warning_types.py @@ -0,0 +1,37 @@ +import inspect + +import _pytest.warning_types +import pytest + + +@pytest.mark.parametrize( + "warning_class", + [ + w + for n, w in vars(_pytest.warning_types).items() + if inspect.isclass(w) and issubclass(w, Warning) + ], +) +def test_warning_types(warning_class): + """Make sure all warnings declared in _pytest.warning_types are displayed as coming + from 'pytest' instead of the internal module (#5452). + """ + assert warning_class.__module__ == "pytest" + + +@pytest.mark.filterwarnings("error::pytest.PytestWarning") +def test_pytest_warnings_repr_integration_test(testdir): + """Small integration test to ensure our small hack of setting the __module__ attribute + of our warnings actually works (#5452). + """ + testdir.makepyfile( + """ + import pytest + import warnings + + def test(): + warnings.warn(pytest.PytestWarning("some warning")) + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["E pytest.PytestWarning: some warning"])