Add a moved *instance* method deprecation pattern
When an instance method has moved to a better location (for whatever reason) it is nice to provide the old instance method under the previous name for a deprecation cycle. To enable this kind of pattern use/modify/extend the existing moved decorator to not just work for properties but also work for instance methods. Change-Id: Ie002d9255d9e5127011c5308c7f5ce16d0b44821
This commit is contained in:
parent
b833207aaa
commit
31733373e1
@ -23,10 +23,12 @@ from debtcollector import _utils
|
|||||||
|
|
||||||
_KIND_MOVED_PREFIX_TPL = "%s '%s' has moved to '%s'"
|
_KIND_MOVED_PREFIX_TPL = "%s '%s' has moved to '%s'"
|
||||||
_CLASS_MOVED_PREFIX_TPL = "Class '%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,
|
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."""
|
"""Decorates a method/property that was moved to another location."""
|
||||||
|
|
||||||
def decorator(f):
|
def decorator(f):
|
||||||
@ -38,6 +40,9 @@ def _moved_decorator(kind, new_attribute_name, message=None,
|
|||||||
old_attribute_name = f.__name__
|
old_attribute_name = f.__name__
|
||||||
fully_qualified = False
|
fully_qualified = False
|
||||||
|
|
||||||
|
if attr_postfix:
|
||||||
|
old_attribute_name += attr_postfix
|
||||||
|
|
||||||
@six.wraps(f)
|
@six.wraps(f)
|
||||||
def wrapper(self, *args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
base_name = reflection.get_class_name(self, fully_qualified=False)
|
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
|
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,
|
def moved_property(new_attribute_name, message=None,
|
||||||
version=None, removal_version=None, stacklevel=3):
|
version=None, removal_version=None, stacklevel=3):
|
||||||
"""Decorates a *instance* property that was moved to another location."""
|
"""Decorates a *instance* property that was moved to another location."""
|
||||||
|
|
||||||
return _moved_decorator('Property', new_attribute_name, message=message,
|
return _moved_decorator('Property', new_attribute_name, message=message,
|
||||||
version=version, removal_version=removal_version,
|
version=version, removal_version=removal_version,
|
||||||
stacklevel=stacklevel)
|
stacklevel=stacklevel)
|
||||||
|
@ -35,6 +35,16 @@ class WoofWoof(object):
|
|||||||
return self.bark
|
return self.bark
|
||||||
|
|
||||||
|
|
||||||
|
class KittyKat(object):
|
||||||
|
|
||||||
|
@moves.moved_method('supermeow')
|
||||||
|
def meow(self):
|
||||||
|
return self.supermeow()
|
||||||
|
|
||||||
|
def supermeow(self):
|
||||||
|
return 'supermeow'
|
||||||
|
|
||||||
|
|
||||||
class NewHotness(object):
|
class NewHotness(object):
|
||||||
def hot(self):
|
def hot(self):
|
||||||
return 'cold'
|
return 'cold'
|
||||||
@ -94,6 +104,29 @@ class MovedPropertyTest(test_base.TestCase):
|
|||||||
self.assertEqual(0, len(capture))
|
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):
|
class RenamedKwargTest(test_base.TestCase):
|
||||||
def test_basics(self):
|
def test_basics(self):
|
||||||
self.assertEqual((1, 1), blip_blop())
|
self.assertEqual((1, 1), blip_blop())
|
||||||
|
Loading…
Reference in New Issue
Block a user