Merge "Add 'moved_read_only_property' descriptor"

This commit is contained in:
Jenkins 2015-12-04 12:59:00 +00:00 committed by Gerrit Code Review
commit 0132731a38
2 changed files with 68 additions and 0 deletions

View File

@ -86,6 +86,55 @@ def moved_function(new_func, old_func_name, old_module_name,
return old_new_func
class moved_read_only_property(object):
"""Descriptor for read-only properties moved to another location.
This works like the ``@property`` descriptor but can be used instead to
provide the same functionality and also interact with the :mod:`warnings`
module to warn when a property is accessed, so that users of those
properties can know that a previously read-only property at a prior
location/name has moved to another location/name.
:param old_name: old attribute location/name
:param new_name: new attribute location/name
:param version: version string (represents the version this deprecation
was created in)
:param removal_version: version string (represents the version this
deprecation will be removed in); a string
of '?' will denote this will be removed in
some future unknown version
:param stacklevel: stacklevel used in the :func:`warnings.warn` function
to locate where the users code is when reporting the
deprecation call (the default being 3)
:param category: the :mod:`warnings` category to use, defaults to
:py:class:`DeprecationWarning` if not provided
"""
def __init__(self, old_name, new_name,
version=None, removal_version=None,
stacklevel=3, category=None):
self._old_name = old_name
self._new_name = new_name
self._message = _utils.generate_message(
"Read-only property '%s' has moved"
" to '%s'" % (self._old_name, self._new_name),
version=version, removal_version=removal_version)
self._stacklevel = stacklevel
self._category = category
def __get__(self, instance, owner):
_utils.deprecation(self._message,
stacklevel=self._stacklevel,
category=self._category)
# This handles the descriptor being applied on a
# instance or a class and makes both work correctly...
if instance is not None:
real_owner = instance
else:
real_owner = owner
return getattr(real_owner, self._new_name)
def moved_method(new_method_name, message=None,
version=None, removal_version=None, stacklevel=3,
category=None):

View File

@ -67,6 +67,17 @@ class KittyKat(object):
return 'supermeow'
class Giraffe(object):
color = 'orange'
colour = moves.moved_read_only_property('colour', 'color')
@property
def height(self):
return 2
heightt = moves.moved_read_only_property('heightt', 'height')
class NewHotness(object):
def hot(self):
return 'cold'
@ -216,6 +227,14 @@ class MovedPropertyTest(test_base.TestCase):
self.assertEqual('woof', dog.burk)
self.assertEqual('woof', dog.bark)
def test_readonly_move(self):
with warnings.catch_warnings(record=True) as capture:
warnings.simplefilter("always")
self.assertEqual('orange', Giraffe.colour)
g = Giraffe()
self.assertEqual(2, g.heightt)
self.assertEqual(2, len(capture))
def test_warnings_emitted(self):
dog = WoofWoof()
with warnings.catch_warnings(record=True) as capture: