def changed_import_test_warn( recwarn: WarningsRecorder, module_qual_name: str, *, attribute_name: str = None, warn_nr=1 ): """Helper for testing changed imports, returning the imported item. Parameters ---------- module_qual_name : str Fully qualified name for a module e.g. ``glotaran.model.base_model`` attribute_name : str, optional Name of the attribute e.g. ``Model`` Returns ------- Any Module attribute or module """ warnings.simplefilter("always") recwarn.clear() if attribute_name is not None: result = module_attribute(module_qual_name, attribute_name) else: result = import_module(module_qual_name) check_recwarn(recwarn, warn_nr=warn_nr) return result
def check_recwarn(records: WarningsRecorder, warn_nr=1): for record in records: print(record) assert len(records) == warn_nr assert records[0].category == GlotaranApiDeprecationWarning records.clear()
def test_examples_sequential(recwarn: WarningsRecorder, attribute_name: str): """glotaran.examples.sequential exported attributes""" from glotaran.examples import sequential # noqa: F401 recwarn.clear() changed_import_test_warn( recwarn, "glotaran.examples.sequential", attribute_name=attribute_name )
def test_invalid_enter_exit(self): # wrap this test in WarningsRecorder to ensure warning state gets reset with WarningsRecorder(): with pytest.raises(RuntimeError): rec = WarningsRecorder() rec.__exit__(None, None, None) # can't exit before entering with pytest.raises(RuntimeError): rec = WarningsRecorder() with rec: with rec: pass # can't enter twice
def test_recording(self): rec = WarningsRecorder() with rec: assert not rec.list warnings.warn_explicit("hello", UserWarning, "xyz", 13) assert len(rec.list) == 1 warnings.warn(DeprecationWarning("hello")) assert len(rec.list) == 2 warn = rec.pop() assert str(warn.message) == "hello" values = rec.list rec.clear() assert len(rec.list) == 0 assert values is rec.list pytest.raises(AssertionError, "rec.pop()")
def test_recording(self): rec = WarningsRecorder() with rec: assert not rec.list warnings.warn_explicit("hello", UserWarning, "xyz", 13) assert len(rec.list) == 1 warnings.warn(DeprecationWarning("hello")) assert len(rec.list) == 2 warn = rec.pop() assert str(warn.message) == "hello" values = rec.list rec.clear() assert len(rec.list) == 0 assert values is rec.list pytest.raises(AssertionError, rec.pop)
def pytest_runtest_call(item): if _DISABLED: yield return from _pytest.recwarn import RecordedWarning, WarningsRecorder 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') for arg in args: wrec._module._setoption(arg) for arg in inifilters: _setoption(wrec._module, arg) yield wrec._showwarning = _showwarning for warning in wrec.list: msg = warnings.formatwarning(warning.message, warning.category, os.path.relpath(warning.filename), warning.lineno, warning.line) fslocation = getattr(item, "location", None) if fslocation is None: fslocation = getattr(item, "fspath", None) else: fslocation = "%s:%s" % fslocation[:2] fslocation = "in %s the following warning was recorded:\n" % fslocation item.config.warn("W0", msg, fslocation=fslocation)
def warncheck(warnfilters): with WarningsRecorder() as record: warnfilters() yield gc.collect() to_prints = [] def keyfunc(_): return _.category.__name__, _.filename, _.lineno _sorted = sorted(record, key=keyfunc) _grouped = itertools.groupby(_sorted, keyfunc) for k, g in _grouped: to_prints.append("\n" "category: {}\n" "filename: {}\n" " lineno: {}".format(*k)) messages = itertools.groupby(g, lambda _: str(_.message)) for k2, g2 in messages: count = sum(1 for _ in g2) count_str = ' ({} times)'.format(count) if count > 1 else '' to_prints.append(" msg: {}{}".format(k2, count_str)) if to_prints: to_prints.insert(0, 'Warnings found:') pytest.fail('\n'.join(to_prints))
def test_functional( test_file: FunctionalTestFile, recwarn: WarningsRecorder, pytestconfig: Config ) -> None: __tracebackhide__ = True # pylint: disable=unused-variable if UPDATE_FILE.exists(): lint_test: Union[ LintModuleOutputUpdate, testutils.LintModuleTest ] = LintModuleOutputUpdate(test_file, pytestconfig) else: lint_test = testutils.LintModuleTest(test_file, pytestconfig) lint_test.setUp() lint_test.runTest() warning = None try: # Catch <unknown>:x: DeprecationWarning: invalid escape sequence # so it's not shown during tests warning = recwarn.pop() except AssertionError: pass if warning is not None: if ( test_file.base in TEST_WITH_EXPECTED_DEPRECATION and sys.version_info.minor > 5 ): assert issubclass(warning.category, DeprecationWarning) assert "invalid escape sequence" in str(warning.message)
def test_recwarn_captures_deprecation_warning(recwarn: WarningsRecorder) -> None: """ Check that recwarn can capture DeprecationWarning by default without custom filterwarnings (see #8666). """ warnings.warn(DeprecationWarning("some deprecation")) assert len(recwarn) == 1 assert recwarn.pop(DeprecationWarning)
def test_recording(self, recwarn): showwarning = py.std.warnings.showwarning rec = WarningsRecorder() with rec: assert py.std.warnings.showwarning != showwarning assert not rec.list py.std.warnings.warn_explicit("hello", UserWarning, "xyz", 13) assert len(rec.list) == 1 py.std.warnings.warn(DeprecationWarning("hello")) assert len(rec.list) == 2 warn = rec.pop() assert str(warn.message) == "hello" l = rec.list rec.clear() assert len(rec.list) == 0 assert l is rec.list pytest.raises(AssertionError, "rec.pop()") assert showwarning == py.std.warnings.showwarning
def test_recwarn_stacklevel(recwarn: WarningsRecorder) -> None: warnings.warn("hello") warn = recwarn.pop() assert warn.filename == __file__
def test_warn_stacklevel(self) -> None: """#4243""" rec = WarningsRecorder(_ispytest=True) with rec: warnings.warn("test", DeprecationWarning, 2)
def test_warn_stacklevel(self): """#4243""" rec = WarningsRecorder() with rec: warnings.warn("test", DeprecationWarning, 2)
import os import sys import json import pytest import warnings import traceback from _pytest.recwarn import WarningsRecorder if sys.version_info >= (3, 8): from importlib import metadata as importlib_metadata else: import importlib_metadata counted_warnings = {} warnings_recorder = WarningsRecorder() default_formatwarning = warnings_recorder._module.formatwarning default_showwarning = warnings_recorder._module.showwarning def showwarning_with_traceback(message, category, filename, lineno, file=None, line=None): msg = warnings.WarningMessage(message, category, filename, lineno, file, line) msg.formatted_traceback = traceback.format_stack() msg.traceback = traceback.extract_stack()