diff --git a/debtcollector/moves.py b/debtcollector/moves.py index cf77dd2..fb134ca 100644 --- a/debtcollector/moves.py +++ b/debtcollector/moves.py @@ -23,10 +23,12 @@ from debtcollector import _utils _KIND_MOVED_PREFIX_TPL = "%s '%s' has moved to '%s'" _CLASS_MOVED_PREFIX_TPL = "Class '%s' has moved to '%s'" +_MOVED_METHOD_POSTFIX = "()" def _moved_decorator(kind, new_attribute_name, message=None, - version=None, removal_version=None, stacklevel=3): + version=None, removal_version=None, stacklevel=3, + attr_postfix=None): """Decorates a method/property that was moved to another location.""" def decorator(f): @@ -38,6 +40,9 @@ def _moved_decorator(kind, new_attribute_name, message=None, old_attribute_name = f.__name__ fully_qualified = False + if attr_postfix: + old_attribute_name += attr_postfix + @six.wraps(f) def wrapper(self, *args, **kwargs): base_name = reflection.get_class_name(self, fully_qualified=False) @@ -58,10 +63,20 @@ def _moved_decorator(kind, new_attribute_name, message=None, return decorator +def moved_method(new_method_name, message=None, + version=None, removal_version=None, stacklevel=3): + """Decorates a *instance* method that was moved to another location.""" + if not new_method_name.endswith(_MOVED_METHOD_POSTFIX): + new_method_name += _MOVED_METHOD_POSTFIX + return _moved_decorator('Method', new_method_name, message=message, + version=version, removal_version=removal_version, + stacklevel=stacklevel, + attr_postfix=_MOVED_METHOD_POSTFIX) + + def moved_property(new_attribute_name, message=None, version=None, removal_version=None, stacklevel=3): """Decorates a *instance* property that was moved to another location.""" - return _moved_decorator('Property', new_attribute_name, message=message, version=version, removal_version=removal_version, stacklevel=stacklevel) diff --git a/debtcollector/tests/test_deprecation.py b/debtcollector/tests/test_deprecation.py index 73d32d0..363c540 100644 --- a/debtcollector/tests/test_deprecation.py +++ b/debtcollector/tests/test_deprecation.py @@ -35,6 +35,16 @@ class WoofWoof(object): return self.bark +class KittyKat(object): + + @moves.moved_method('supermeow') + def meow(self): + return self.supermeow() + + def supermeow(self): + return 'supermeow' + + class NewHotness(object): def hot(self): return 'cold' @@ -94,6 +104,29 @@ class MovedPropertyTest(test_base.TestCase): self.assertEqual(0, len(capture)) +class MovedMethodTest(test_base.TestCase): + def test_basics(self): + c = KittyKat() + self.assertEqual('supermeow', c.meow()) + self.assertEqual('supermeow', c.supermeow()) + + def test_warnings_emitted(self): + c = KittyKat() + with warnings.catch_warnings(record=True) as capture: + warnings.simplefilter("always") + self.assertEqual('supermeow', c.meow()) + self.assertEqual(1, len(capture)) + w = capture[0] + self.assertEqual(DeprecationWarning, w.category) + + def test_warnings_not_emitted(self): + c = KittyKat() + with warnings.catch_warnings(record=True) as capture: + warnings.simplefilter("always") + self.assertEqual('supermeow', c.supermeow()) + self.assertEqual(0, len(capture)) + + class RenamedKwargTest(test_base.TestCase): def test_basics(self): self.assertEqual((1, 1), blip_blop())