Add in a new hook pytest_warning_recorded for warning capture
communication
This commit is contained in:
parent
c594bbbd19
commit
9ee6550181
|
@ -711,6 +711,7 @@ Session related reporting hooks:
|
|||
.. autofunction:: pytest_fixture_setup
|
||||
.. autofunction:: pytest_fixture_post_finalizer
|
||||
.. autofunction:: pytest_warning_captured
|
||||
.. autofunction:: pytest_warning_record
|
||||
|
||||
Central hook for reporting about test execution:
|
||||
|
||||
|
|
|
@ -622,6 +622,33 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config):
|
|||
|
||||
@hookspec(historic=True)
|
||||
def pytest_warning_captured(warning_message, when, item, location):
|
||||
"""(**Deprecated**) Process a warning captured by the internal pytest warnings plugin.
|
||||
|
||||
This hook is considered deprecated and will be removed in a future pytest version.
|
||||
Use :func:`pytest_warning_record` instead.
|
||||
|
||||
:param warnings.WarningMessage warning_message:
|
||||
The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains
|
||||
the same attributes as the parameters of :py:func:`warnings.showwarning`.
|
||||
|
||||
:param str when:
|
||||
Indicates when the warning was captured. Possible values:
|
||||
|
||||
* ``"config"``: during pytest configuration/initialization stage.
|
||||
* ``"collect"``: during test collection.
|
||||
* ``"runtest"``: during test execution.
|
||||
|
||||
:param pytest.Item|None item:
|
||||
The item being executed if ``when`` is ``"runtest"``, otherwise ``None``.
|
||||
|
||||
:param tuple location:
|
||||
Holds information about the execution context of the captured warning (filename, linenumber, function).
|
||||
``function`` evaluates to <module> when the execution context is at the module level.
|
||||
"""
|
||||
|
||||
|
||||
@hookspec(historic=True)
|
||||
def pytest_warning_record(warning_message, when, nodeid, location):
|
||||
"""
|
||||
Process a warning captured by the internal pytest warnings plugin.
|
||||
|
||||
|
@ -636,11 +663,7 @@ def pytest_warning_captured(warning_message, when, item, location):
|
|||
* ``"collect"``: during test collection.
|
||||
* ``"runtest"``: during test execution.
|
||||
|
||||
:param pytest.Item|None item:
|
||||
**DEPRECATED**: This parameter is incompatible with ``pytest-xdist``, and will always receive ``None``
|
||||
in a future release.
|
||||
|
||||
The item being executed if ``when`` is ``"runtest"``, otherwise ``None``.
|
||||
:param str nodeid: full id of the item
|
||||
|
||||
:param tuple location:
|
||||
Holds information about the execution context of the captured warning (filename, linenumber, function).
|
||||
|
|
|
@ -227,7 +227,7 @@ def pytest_report_teststatus(report: TestReport) -> Tuple[str, str, str]:
|
|||
@attr.s
|
||||
class WarningReport:
|
||||
"""
|
||||
Simple structure to hold warnings information captured by ``pytest_warning_captured``.
|
||||
Simple structure to hold warnings information captured by ``pytest_warning_record``.
|
||||
|
||||
:ivar str message: user friendly message about the warning
|
||||
:ivar str|None nodeid: node id that generated the warning (see ``get_location``).
|
||||
|
@ -412,13 +412,14 @@ class TerminalReporter:
|
|||
return 1
|
||||
|
||||
def pytest_warning_captured(self, warning_message, item):
|
||||
# from _pytest.nodes import get_fslocation_from_item
|
||||
pass
|
||||
|
||||
def pytest_warning_record(self, warning_message, nodeid):
|
||||
from _pytest.warnings import warning_record_to_str
|
||||
|
||||
fslocation = warning_message.filename, warning_message.lineno
|
||||
message = warning_record_to_str(warning_message)
|
||||
|
||||
nodeid = item.nodeid if item is not None else ""
|
||||
warning_report = WarningReport(
|
||||
fslocation=fslocation, message=message, nodeid=nodeid
|
||||
)
|
||||
|
|
|
@ -81,7 +81,7 @@ def catch_warnings_for_item(config, ihook, when, item):
|
|||
|
||||
``item`` can be None if we are not in the context of an item execution.
|
||||
|
||||
Each warning captured triggers the ``pytest_warning_captured`` hook.
|
||||
Each warning captured triggers the ``pytest_warning_record`` hook.
|
||||
"""
|
||||
cmdline_filters = config.getoption("pythonwarnings") or []
|
||||
inifilters = config.getini("filterwarnings")
|
||||
|
@ -102,6 +102,7 @@ def catch_warnings_for_item(config, ihook, when, item):
|
|||
for arg in cmdline_filters:
|
||||
warnings.filterwarnings(*_parse_filter(arg, escape=True))
|
||||
|
||||
nodeid = "" if item is None else item.nodeid
|
||||
if item is not None:
|
||||
for mark in item.iter_markers(name="filterwarnings"):
|
||||
for arg in mark.args:
|
||||
|
@ -110,8 +111,9 @@ def catch_warnings_for_item(config, ihook, when, item):
|
|||
yield
|
||||
|
||||
for warning_message in log:
|
||||
ihook.pytest_warning_captured.call_historic(
|
||||
kwargs=dict(warning_message=warning_message, when=when, item=item)
|
||||
# raise ValueError(ihook.pytest_warning_record)
|
||||
ihook.pytest_warning_record.call_historic(
|
||||
kwargs=dict(warning_message=warning_message, nodeid=nodeid, when=when)
|
||||
)
|
||||
|
||||
|
||||
|
@ -166,8 +168,9 @@ def pytest_sessionfinish(session):
|
|||
def _issue_warning_captured(warning, hook, stacklevel):
|
||||
"""
|
||||
This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage:
|
||||
at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured
|
||||
hook so we can display these warnings in the terminal. This is a hack until we can sort out #2891.
|
||||
at this point the actual options might not have been set, so we manually trigger the pytest_warning_record hooks
|
||||
so we can display these warnings in the terminal.
|
||||
This is a hack until we can sort out #2891.
|
||||
|
||||
:param warning: the warning instance.
|
||||
:param hook: the hook caller
|
||||
|
@ -180,8 +183,8 @@ def _issue_warning_captured(warning, hook, stacklevel):
|
|||
assert records is not None
|
||||
frame = sys._getframe(stacklevel - 1)
|
||||
location = frame.f_code.co_filename, frame.f_lineno, frame.f_code.co_name
|
||||
hook.pytest_warning_captured.call_historic(
|
||||
hook.pytest_warning_record.call_historic(
|
||||
kwargs=dict(
|
||||
warning_message=records[0], when="config", item=None, location=location
|
||||
warning_message=records[0], when="config", nodeid="", location=location
|
||||
)
|
||||
)
|
||||
|
|
|
@ -268,9 +268,8 @@ def test_warning_captured_hook(testdir):
|
|||
collected = []
|
||||
|
||||
class WarningCollector:
|
||||
def pytest_warning_captured(self, warning_message, when, item):
|
||||
imge_name = item.name if item is not None else ""
|
||||
collected.append((str(warning_message.message), when, imge_name))
|
||||
def pytest_warning_record(self, warning_message, when, nodeid):
|
||||
collected.append((str(warning_message.message), when, nodeid))
|
||||
|
||||
result = testdir.runpytest(plugins=[WarningCollector()])
|
||||
result.stdout.fnmatch_lines(["*1 passed*"])
|
||||
|
@ -278,11 +277,11 @@ def test_warning_captured_hook(testdir):
|
|||
expected = [
|
||||
("config warning", "config", ""),
|
||||
("collect warning", "collect", ""),
|
||||
("setup warning", "runtest", "test_func"),
|
||||
("call warning", "runtest", "test_func"),
|
||||
("teardown warning", "runtest", "test_func"),
|
||||
("setup warning", "runtest", "test_warning_captured_hook.py::test_func"),
|
||||
("call warning", "runtest", "test_warning_captured_hook.py::test_func"),
|
||||
("teardown warning", "runtest", "test_warning_captured_hook.py::test_func"),
|
||||
]
|
||||
assert collected == expected
|
||||
assert collected == expected, str(collected)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("always")
|
||||
|
@ -649,7 +648,7 @@ class TestStackLevel:
|
|||
captured = []
|
||||
|
||||
@classmethod
|
||||
def pytest_warning_captured(cls, warning_message, when, item, location):
|
||||
def pytest_warning_record(cls, warning_message, when, nodeid, location):
|
||||
cls.captured.append((warning_message, location))
|
||||
|
||||
testdir.plugins = [CapturedWarnings()]
|
||||
|
|
Loading…
Reference in New Issue