From 1b5149793659cd234fc91a9ac00c2be78b62e00d Mon Sep 17 00:00:00 2001 From: Ankit Goel Date: Thu, 18 Oct 2018 02:36:41 +0000 Subject: [PATCH 1/2] [WIP] Update warning stacklevel when wrapping warnings.warn --- src/_pytest/recwarn.py | 2 ++ testing/test_recwarn.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 62c9158fb..5adc42d26 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -156,6 +156,8 @@ class WarningsRecorder(warnings.catch_warnings): if six.PY2: def warn(*args, **kwargs): + kwargs.setdefault("stacklevel", 1) + kwargs["stacklevel"] += 1 return self._saved_warn(*args, **kwargs) warnings.warn, self._saved_warn = warn, warnings.warn diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 3ae543248..e1d44f174 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -6,6 +6,12 @@ import pytest from _pytest.recwarn import WarningsRecorder +def test_recwarn_stacklevel(recwarn): + warnings.warn("hello") + warn = recwarn.pop() + assert warn.filename == __file__ + + def test_recwarn_functional(testdir): testdir.makepyfile( """ From cdd0e18ca8c82a2cb6e61ee2f2893782fe29756b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 18 Oct 2018 10:40:47 -0700 Subject: [PATCH 2/2] Emulate resetting the warnings registry for python 2.x --- changelog/4192.bugfix.rst | 1 + src/_pytest/recwarn.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 changelog/4192.bugfix.rst diff --git a/changelog/4192.bugfix.rst b/changelog/4192.bugfix.rst new file mode 100644 index 000000000..86ed95360 --- /dev/null +++ b/changelog/4192.bugfix.rst @@ -0,0 +1 @@ +Fix filename reported by ``warnings.warn`` when using ``recwarn`` under python2. diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 5adc42d26..8738fe0b8 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -158,7 +158,18 @@ class WarningsRecorder(warnings.catch_warnings): def warn(*args, **kwargs): kwargs.setdefault("stacklevel", 1) kwargs["stacklevel"] += 1 - return self._saved_warn(*args, **kwargs) + + # emulate resetting the warn registry + f_globals = sys._getframe(kwargs["stacklevel"] - 1).f_globals + if "__warningregistry__" in f_globals: + orig = f_globals["__warningregistry__"] + f_globals["__warningregistry__"] = None + try: + return self._saved_warn(*args, **kwargs) + finally: + f_globals["__warningregistry__"] = orig + else: + return self._saved_warn(*args, **kwargs) warnings.warn, self._saved_warn = warn, warnings.warn return self