fix #4243 - support positional argument stacklevel on python2

This commit is contained in:
Ronny Pfannschmidt 2018-10-26 09:01:25 +02:00
parent 041044eef0
commit ce0b0518c7
3 changed files with 19 additions and 6 deletions

View File

@ -0,0 +1 @@
Fix regression when ``stacklevel`` for warnings was passed as positional argument on python2.

View File

@ -156,21 +156,27 @@ class WarningsRecorder(warnings.catch_warnings):
# trivial patching of `warnings.warn` seems to be enough somehow?
if six.PY2:
def warn(*args, **kwargs):
kwargs.setdefault("stacklevel", 1)
kwargs["stacklevel"] += 1
def warn(message, category=None, stacklevel=1):
# duplicate the stdlib logic due to
# bad handing in the c version of warnings
if isinstance(message, Warning):
category = message.__class__
# Check category argument
if category is None:
category = UserWarning
assert issubclass(category, Warning)
# emulate resetting the warn registry
f_globals = sys._getframe(kwargs["stacklevel"] - 1).f_globals
f_globals = sys._getframe(stacklevel).f_globals
if "__warningregistry__" in f_globals:
orig = f_globals["__warningregistry__"]
f_globals["__warningregistry__"] = None
try:
return self._saved_warn(*args, **kwargs)
return self._saved_warn(message, category, stacklevel + 1)
finally:
f_globals["__warningregistry__"] = orig
else:
return self._saved_warn(*args, **kwargs)
return self._saved_warn(message, category, stacklevel + 1)
warnings.warn, self._saved_warn = warn, warnings.warn
return self

View File

@ -46,6 +46,12 @@ class TestWarningsRecorderChecker(object):
assert values is rec.list
pytest.raises(AssertionError, "rec.pop()")
@pytest.mark.issue(4243)
def test_warn_stacklevel(self):
rec = WarningsRecorder()
with rec:
warnings.warn("test", DeprecationWarning, 2)
def test_typechecking(self):
from _pytest.recwarn import WarningsChecker