Use warnings.catch_warnings instead of WarningsRecorder
This has the benefical side-effect of not calling the original warnings.showwarnings function, which in its original form only writes the formatted warning to sys.stdout. Calling the original warnings.showwarnings has the effect that nested WarningsRecorder all catch the warnings: with WarningsRecorder() as rec1: with WarningsRecorder() as rec2: warnings.warn(UserWarning, 'some warning') (both rec1 and rec2 sees the warning) When running tests with `testdir`, the main pytest session would then see the warnings created by the internal code being tested (if any), and the main pytest session would end up with warnings as well.
This commit is contained in:
parent
a7643a5fbe
commit
82785fcd40
|
@ -1,5 +1,3 @@
|
|||
from _pytest.recwarn import RecordedWarning, WarningsRecorder
|
||||
import inspect
|
||||
import os
|
||||
import pytest
|
||||
import warnings
|
||||
|
@ -42,35 +40,19 @@ def pytest_addoption(parser):
|
|||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_call(item):
|
||||
wrec = WarningsRecorder()
|
||||
|
||||
def showwarning(message, category, filename, lineno, file=None, line=None):
|
||||
frame = inspect.currentframe()
|
||||
if '/_pytest/recwarn' in frame.f_back.f_code.co_filename:
|
||||
# we are in test recorder, so this warning is already handled
|
||||
return
|
||||
wrec._list.append(RecordedWarning(
|
||||
message, category, filename, lineno, file, line))
|
||||
# still perform old showwarning functionality
|
||||
wrec._showwarning(
|
||||
message, category, filename, lineno, file=file, line=line)
|
||||
|
||||
args = item.config.getoption('pythonwarnings') or []
|
||||
inifilters = item.config.getini("filterwarnings")
|
||||
with wrec:
|
||||
_showwarning = wrec._showwarning
|
||||
warnings.showwarning = showwarning
|
||||
wrec._module.simplefilter('once')
|
||||
with warnings.catch_warnings(record=True) as log:
|
||||
warnings.simplefilter('once')
|
||||
for arg in args:
|
||||
wrec._module._setoption(arg)
|
||||
warnings._setoption(arg)
|
||||
|
||||
for arg in inifilters:
|
||||
_setoption(wrec._module, arg)
|
||||
_setoption(warnings, arg)
|
||||
|
||||
yield
|
||||
wrec._showwarning = _showwarning
|
||||
|
||||
for warning in wrec.list:
|
||||
for warning in log:
|
||||
msg = warnings.formatwarning(
|
||||
warning.message, warning.category,
|
||||
os.path.relpath(warning.filename), warning.lineno, warning.line)
|
||||
|
|
|
@ -12,7 +12,7 @@ def pyfile_with_warnings(testdir):
|
|||
|
||||
|
||||
def test_normal_flow(testdir, pyfile_with_warnings):
|
||||
result = testdir.runpytest_subprocess()
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines([
|
||||
'*== pytest-warning summary ==*',
|
||||
|
||||
|
@ -35,7 +35,7 @@ def test_as_errors(testdir, pyfile_with_warnings, method):
|
|||
[pytest]
|
||||
filterwarnings= error
|
||||
''')
|
||||
result = testdir.runpytest_subprocess(*args)
|
||||
result = testdir.runpytest(*args)
|
||||
result.stdout.fnmatch_lines([
|
||||
'E PendingDeprecationWarning: functionality is pending deprecation',
|
||||
'test_as_errors.py:3: PendingDeprecationWarning',
|
||||
|
@ -52,7 +52,7 @@ def test_ignore(testdir, pyfile_with_warnings, method):
|
|||
filterwarnings= ignore
|
||||
''')
|
||||
|
||||
result = testdir.runpytest_subprocess(*args)
|
||||
result = testdir.runpytest(*args)
|
||||
result.stdout.fnmatch_lines([
|
||||
'* 1 passed in *',
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue