summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Peuch <cortex@worlddomination.be>2020-10-09 11:10:30 +0200
committerLaurent Peuch <cortex@worlddomination.be>2020-10-09 11:10:30 +0200
commitf7a5bd8003e406ce873653955be0aeec92e486f2 (patch)
tree23726180fed5a791ba14257e5c6d215db948025e
parent0aedd28cb0eca8ba51f54db4fd2e171971569c7d (diff)
downloadlogilab-common-f7a5bd8003e406ce873653955be0aeec92e486f2.tar.gz
feat: add tests to ensure that warnings target the correct line
-rw-r--r--logilab/common/deprecation.py2
-rw-r--r--test/test_deprecation.py213
2 files changed, 213 insertions, 2 deletions
diff --git a/logilab/common/deprecation.py b/logilab/common/deprecation.py
index 848f8e7..e5c755d 100644
--- a/logilab/common/deprecation.py
+++ b/logilab/common/deprecation.py
@@ -383,7 +383,7 @@ def _generate_class_deprecated():
module_name=getattr(
cls, "__deprecation_warning_module_name__", _get_module_name(1)
),
- stacklevel=getattr(cls, "__deprecation_warning_stacklevel__", 4),
+ stacklevel=getattr(cls, "__deprecation_warning_stacklevel__", 3),
version=getattr(cls, "__deprecation_warning_version__", None),
)
return type.__call__(cls, *args, **kwargs)
diff --git a/test/test_deprecation.py b/test/test_deprecation.py
index 93fc0eb..50a1c0c 100644
--- a/test/test_deprecation.py
+++ b/test/test_deprecation.py
@@ -17,13 +17,19 @@
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for logilab.common.deprecation"""
+import os
import warnings
+from inspect import currentframe, getframeinfo
+
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.modutils import LazyObject
from logilab.common import deprecation
+CURRENT_FILE = os.path.abspath(__file__)
+
+
class RawInputTC(TestCase):
# XXX with 2.6 we could test warnings
@@ -389,7 +395,7 @@ class StructuredDeprecatedWarningsTest(TestCase):
some_class = SomeClass()
- some_class.old == some_class.new
+ some_class.old == some_class.new # trigger warning
self.assertEqual(len(self.collected_warnings), 1)
warning = self.collected_warnings.pop()
@@ -479,5 +485,210 @@ class StructuredDeprecatedWarningsTest(TestCase):
self.assertEqual(warning.kind, deprecation.DeprecationWarningKind.CALLABLE)
+class DeprecatedWarningsTracebackLocationTest(TestCase):
+ def setUp(self):
+ self.catch_warnings = warnings.catch_warnings(record=True)
+ self.collected_warnings = self.catch_warnings.__enter__()
+
+ def tearDown(self):
+ self.catch_warnings.__exit__()
+
+ def mk_func(self):
+ def any_func():
+ pass
+
+ return any_func
+
+ def test_class_deprecated(self):
+ class AnyClass(metaclass=deprecation.class_deprecated):
+ pass
+
+ AnyClass()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_class_renamed(self):
+ class AnyClass:
+ pass
+
+ OldClass = deprecation.class_renamed("OldClass", AnyClass)
+
+ OldClass()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_class_moved(self):
+ class AnyClass:
+ pass
+
+ OldClass = deprecation.class_moved(new_class=AnyClass, old_name="OldName")
+ OldClass()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ AnyClass = deprecation.class_moved(new_class=AnyClass)
+
+ AnyClass()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_deprecated_func(self):
+ any_func = deprecation.callable_deprecated()(self.mk_func())
+ any_func()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ any_func = deprecation.callable_deprecated("message")(self.mk_func())
+ any_func()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_deprecated_decorator(self):
+ @deprecation.callable_deprecated()
+ def any_func():
+ pass
+
+ any_func()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ @deprecation.callable_deprecated("message")
+ def any_func():
+ pass
+
+ any_func()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_attribute_renamed(self):
+ @deprecation.attribute_renamed(old_name="old", new_name="new")
+ class SomeClass:
+ def __init__(self):
+ self.new = 42
+
+ some_class = SomeClass()
+
+ some_class.old == some_class.new # trigger warning
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ some_class.old = 43
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ del some_class.old
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_argument_renamed(self):
+ @deprecation.argument_renamed(old_name="old", new_name="new")
+ def some_function(new):
+ return new
+
+ some_function(old=42)
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_argument_removed(self):
+ @deprecation.argument_removed("old")
+ def some_function(new):
+ return new
+
+ some_function(new=10, old=20)
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_callable_renamed(self):
+ def any_func():
+ pass
+
+ old_func = deprecation.callable_renamed("old_func", any_func)
+ old_func()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+ def test_callable_moved(self):
+ module = "data.deprecation"
+ moving_target = deprecation.callable_moved(module, "moving_target")
+ moving_target()
+ warning_line = getframeinfo(currentframe()).lineno - 1
+
+ self.assertEqual(len(self.collected_warnings), 1)
+ warning = self.collected_warnings.pop()
+
+ location = f"{CURRENT_FILE}:{warning_line}"
+ self.assertEqual(f"{warning.filename}:{warning.lineno}", location)
+
+
if __name__ == "__main__":
unittest_main()