Implement new pytest_warning_captured hook
This commit is contained in:
parent
10f21b423a
commit
ffd47ceefc
|
@ -535,6 +535,25 @@ def pytest_logwarning(message, code, nodeid, fslocation):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@hookspec(historic=True)
|
||||||
|
def pytest_warning_captured(warning, when, item):
|
||||||
|
"""
|
||||||
|
Process a warning captured by the internal pytest plugin.
|
||||||
|
|
||||||
|
:param warnings.WarningMessage warning:
|
||||||
|
The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains
|
||||||
|
the same attributes as :py:func:`warnings.showwarning`.
|
||||||
|
|
||||||
|
:param str when:
|
||||||
|
Indicates when the warning was captured. Possible values:
|
||||||
|
* ``"collect"``: during test collection.
|
||||||
|
* ``"runtest"``: during test execution.
|
||||||
|
|
||||||
|
:param pytest.Item|None item:
|
||||||
|
The item being executed if ``when == "runtest"``, else ``None``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# doctest hooks
|
# doctest hooks
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
|
@ -58,7 +58,7 @@ def pytest_configure(config):
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def catch_warnings_for_item(item):
|
def deprecated_catch_warnings_for_item(item):
|
||||||
"""
|
"""
|
||||||
catches the warnings generated during setup/call/teardown execution
|
catches the warnings generated during setup/call/teardown execution
|
||||||
of the given item and after it is done posts them as warnings to this
|
of the given item and after it is done posts them as warnings to this
|
||||||
|
@ -80,40 +80,40 @@ def catch_warnings_for_item(item):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
for warning in log:
|
for warning in log:
|
||||||
warn_msg = warning.message
|
item.ihook.pytest_warning_captured.call_historic(
|
||||||
unicode_warning = False
|
kwargs=dict(warning=warning, when="runtest", item=item)
|
||||||
|
|
||||||
if compat._PY2 and any(
|
|
||||||
isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args
|
|
||||||
):
|
|
||||||
new_args = []
|
|
||||||
for m in warn_msg.args:
|
|
||||||
new_args.append(
|
|
||||||
compat.ascii_escaped(m)
|
|
||||||
if isinstance(m, compat.UNICODE_TYPES)
|
|
||||||
else m
|
|
||||||
)
|
|
||||||
unicode_warning = list(warn_msg.args) != new_args
|
|
||||||
warn_msg.args = new_args
|
|
||||||
|
|
||||||
msg = warnings.formatwarning(
|
|
||||||
warn_msg,
|
|
||||||
warning.category,
|
|
||||||
warning.filename,
|
|
||||||
warning.lineno,
|
|
||||||
warning.line,
|
|
||||||
)
|
)
|
||||||
item.warn("unused", msg)
|
deprecated_emit_warning(item, warning)
|
||||||
|
|
||||||
if unicode_warning:
|
|
||||||
warnings.warn(
|
def deprecated_emit_warning(item, warning):
|
||||||
"Warning is using unicode non convertible to ascii, "
|
"""
|
||||||
"converting to a safe representation:\n %s" % msg,
|
Emits the deprecated ``pytest_logwarning`` for the given warning and item.
|
||||||
UnicodeWarning,
|
"""
|
||||||
)
|
warn_msg = warning.message
|
||||||
|
unicode_warning = False
|
||||||
|
if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
|
||||||
|
new_args = []
|
||||||
|
for m in warn_msg.args:
|
||||||
|
new_args.append(
|
||||||
|
compat.ascii_escaped(m) if isinstance(m, compat.UNICODE_TYPES) else m
|
||||||
|
)
|
||||||
|
unicode_warning = list(warn_msg.args) != new_args
|
||||||
|
warn_msg.args = new_args
|
||||||
|
|
||||||
|
msg = warnings.formatwarning(
|
||||||
|
warn_msg, warning.category, warning.filename, warning.lineno, warning.line
|
||||||
|
)
|
||||||
|
item.warn("unused", msg)
|
||||||
|
if unicode_warning:
|
||||||
|
warnings.warn(
|
||||||
|
"Warning is using unicode non convertible to ascii, "
|
||||||
|
"converting to a safe representation:\n %s" % msg,
|
||||||
|
UnicodeWarning,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.hookimpl(hookwrapper=True)
|
@pytest.hookimpl(hookwrapper=True)
|
||||||
def pytest_runtest_protocol(item):
|
def pytest_runtest_protocol(item):
|
||||||
with catch_warnings_for_item(item):
|
with deprecated_catch_warnings_for_item(item):
|
||||||
yield
|
yield
|
||||||
|
|
|
@ -302,3 +302,22 @@ def test_filterwarnings_mark_registration(testdir):
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("--strict")
|
result = testdir.runpytest("--strict")
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.filterwarnings("always")
|
||||||
|
def test_warning_captured_hook(testdir, pyfile_with_warnings):
|
||||||
|
|
||||||
|
collected = []
|
||||||
|
|
||||||
|
class WarningCollector:
|
||||||
|
def pytest_warning_captured(self, warning, when, item):
|
||||||
|
collected.append((warning.category, when, item.name))
|
||||||
|
|
||||||
|
result = testdir.runpytest(plugins=[WarningCollector()])
|
||||||
|
result.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
(UserWarning, "runtest", "test_func"),
|
||||||
|
(RuntimeWarning, "runtest", "test_func"),
|
||||||
|
]
|
||||||
|
assert collected == expected
|
||||||
|
|
Loading…
Reference in New Issue