test_ok2/_pytest/warnings.py

86 lines
2.5 KiB
Python
Raw Normal View History

2016-06-22 18:21:51 +08:00
import os
from contextlib import contextmanager
2016-06-22 18:21:51 +08:00
import pytest
import warnings
def _setoption(wmod, arg):
"""
Copy of the warning._setoption function but does not escape arguments.
"""
parts = arg.split(':')
if len(parts) > 5:
raise wmod._OptionError("too many fields (max 5): %r" % (arg,))
while len(parts) < 5:
parts.append('')
action, message, category, module, lineno = [s.strip()
for s in parts]
action = wmod._getaction(action)
category = wmod._getcategory(category)
if lineno:
try:
lineno = int(lineno)
if lineno < 0:
raise ValueError
except (ValueError, OverflowError):
raise wmod._OptionError("invalid lineno %r" % (lineno,))
else:
lineno = 0
wmod.filterwarnings(action, message, category, module, lineno)
2016-06-22 18:21:51 +08:00
def pytest_addoption(parser):
group = parser.getgroup("pytest-warnings")
group.addoption(
'-W', '--pythonwarnings', action='append',
help="set which warnings to report, see -W option of python itself.")
parser.addini("filterwarnings", type="linelist",
help="Each line specifies warning filter pattern which would be passed"
"to warnings.filterwarnings. Process after -W and --pythonwarnings.")
2016-06-22 18:21:51 +08:00
@contextmanager
def catch_warnings_for_item(item):
"""
catches the warnings generated during setup/call/teardown execution
of the given item and after it is done posts them as warnings to this
item.
"""
2016-06-22 18:21:51 +08:00
args = item.config.getoption('pythonwarnings') or []
inifilters = item.config.getini("filterwarnings")
with warnings.catch_warnings(record=True) as log:
warnings.simplefilter('once')
2016-06-22 18:21:51 +08:00
for arg in args:
warnings._setoption(arg)
for arg in inifilters:
_setoption(warnings, arg)
2016-06-22 18:21:51 +08:00
yield
for warning in log:
2016-06-22 18:21:51 +08:00
msg = warnings.formatwarning(
warning.message, warning.category,
2017-02-25 23:02:48 +08:00
warning.filename, warning.lineno, warning.line)
item.warn("unused", msg)
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item):
with catch_warnings_for_item(item):
yield
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_setup(item):
with catch_warnings_for_item(item):
yield
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_teardown(item):
with catch_warnings_for_item(item):
yield