diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 428a37f..731bbc9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,11 +23,17 @@ v1.2.9 (unreleased) Bug fix release +Fix +--- + +- Fix #20: Set the :func:`warnings.warn` stacklevel to 2 if the Python implementation is `PyPy `_. + Other ----- - Change the Tox configuration to run tests on PyPy v2.7 and 3.6. + v1.2.8 (2020-04-05) =================== @@ -55,7 +61,6 @@ Documentation - Add a detailed documentation about :ref:`sphinx_deco`. - Other ----- diff --git a/deprecated/classic.py b/deprecated/classic.py index bbdce5a..f3f67d6 100644 --- a/deprecated/classic.py +++ b/deprecated/classic.py @@ -10,18 +10,24 @@ import functools import inspect import warnings +import platform import wrapt try: - # If the c extension for wrapt was compiled and wrapt/_wrappers.pyd exists, then the + # If the C extension for wrapt was compiled and wrapt/_wrappers.pyd exists, then the # stack level that should be passed to warnings.warn should be 2. However, if using # a pure python wrapt, a extra stacklevel is required. import wrapt._wrappers - _stacklevel = 2 + _routine_stacklevel = 2 + _class_stacklevel = 2 except ImportError: - _stacklevel = 3 + _routine_stacklevel = 3 + if platform.python_implementation() == "PyPy": + _class_stacklevel = 2 + else: + _class_stacklevel = 3 string_types = (type(b''), type(u'')) @@ -158,13 +164,13 @@ def wrapped_cls(cls, *args, **kwargs): with warnings.catch_warnings(): if self.action: warnings.simplefilter(self.action, self.category) - warnings.warn(msg, category=self.category, stacklevel=_stacklevel) + warnings.warn(msg, category=self.category, stacklevel=_class_stacklevel) if old_new1 is object.__new__: return old_new1(cls) # actually, we don't know the real signature of *old_new1* - return old_new1(*args, **kwargs) + return old_new1(cls, *args, **kwargs) - wrapped.__new__ = classmethod(wrapped_cls) + wrapped.__new__ = staticmethod(wrapped_cls) return wrapped @@ -271,7 +277,7 @@ def wrapper_function(wrapped_, instance_, args_, kwargs_): with warnings.catch_warnings(): if action: warnings.simplefilter(action, category) - warnings.warn(msg, category=category, stacklevel=_stacklevel) + warnings.warn(msg, category=category, stacklevel=_routine_stacklevel) return wrapped_(*args_, **kwargs_) return wrapper_function(wrapped)