Allow deprecated decorator to specify no plan for removal
Allow the @deprecated decorator to specify functionality as deprecated but not slate any release for removal of the deprecated functionality. Change-Id: Iff24553ec83c4a8b0faf4b6381b6fe1589a1c089
This commit is contained in:
committed by
Doug Hellmann
parent
14d1d9eea8
commit
7f263be4b1
@@ -53,6 +53,14 @@ class deprecated(object):
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, remove_in=+1)
|
||||
... def c(): pass
|
||||
|
||||
4. Specifying the deprecated functionality will not be removed:
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, remove_in=0)
|
||||
... def d(): pass
|
||||
|
||||
5. Specifying a replacement, deprecated functionality will not be removed:
|
||||
>>> @deprecated(as_of=deprecated.ICEHOUSE, in_favor_of='f()', remove_in=0)
|
||||
... def e(): pass
|
||||
|
||||
"""
|
||||
|
||||
# NOTE(morganfainberg): Bexar is used for unit test purposes, it is
|
||||
@@ -83,6 +91,12 @@ class deprecated(object):
|
||||
'%(what)s is deprecated as of %(as_of)s and may be '
|
||||
'removed in %(remove_in)s. It will not be superseded.')
|
||||
|
||||
_deprecated_msg_with_alternative_no_removal = _(
|
||||
'%(what)s is deprecated as of %(as_of)s in favor of %(in_favor_of)s.')
|
||||
|
||||
_deprecated_msg_with_no_alternative_no_removal = _(
|
||||
'%(what)s is deprecated as of %(as_of)s. It will not be superseded.')
|
||||
|
||||
def __init__(self, as_of, in_favor_of=None, remove_in=2, what=None):
|
||||
"""Initialize decorator
|
||||
|
||||
@@ -128,9 +142,19 @@ class deprecated(object):
|
||||
|
||||
if self.in_favor_of:
|
||||
details['in_favor_of'] = self.in_favor_of
|
||||
msg = self._deprecated_msg_with_alternative
|
||||
if self.remove_in > 0:
|
||||
msg = self._deprecated_msg_with_alternative
|
||||
else:
|
||||
# There are no plans to remove this function, but it is
|
||||
# now deprecated.
|
||||
msg = self._deprecated_msg_with_alternative_no_removal
|
||||
else:
|
||||
msg = self._deprecated_msg_no_alternative
|
||||
if self.remove_in > 0:
|
||||
msg = self._deprecated_msg_no_alternative
|
||||
else:
|
||||
# There are no plans to remove this function, but it is
|
||||
# now deprecated.
|
||||
msg = self._deprecated_msg_with_no_alternative_no_removal
|
||||
return msg, details
|
||||
|
||||
|
||||
|
||||
@@ -21,12 +21,23 @@ from openstack.common import versionutils
|
||||
|
||||
|
||||
class DeprecatedTestCase(test_base.BaseTestCase):
|
||||
def assert_deprecated(self, mock_log, **expected_details):
|
||||
def assert_deprecated(self, mock_log, no_removal=False,
|
||||
**expected_details):
|
||||
decorator = versionutils.deprecated
|
||||
if 'in_favor_of' in expected_details:
|
||||
expected_msg = decorator._deprecated_msg_with_alternative
|
||||
if no_removal is False:
|
||||
expected_msg = decorator._deprecated_msg_with_alternative
|
||||
else:
|
||||
expected_msg = getattr(
|
||||
decorator,
|
||||
'_deprecated_msg_with_alternative_no_removal')
|
||||
else:
|
||||
expected_msg = decorator._deprecated_msg_no_alternative
|
||||
if no_removal is False:
|
||||
expected_msg = decorator._deprecated_msg_no_alternative
|
||||
else:
|
||||
expected_msg = getattr(
|
||||
decorator,
|
||||
'_deprecated_msg_with_no_alternative_no_removal')
|
||||
mock_log.deprecated.assert_called_with(expected_msg, expected_details)
|
||||
|
||||
@mock.patch('openstack.common.versionutils.LOG', mock.Mock())
|
||||
@@ -146,6 +157,36 @@ class DeprecatedTestCase(test_base.BaseTestCase):
|
||||
as_of='Grizzly',
|
||||
remove_in='Juno')
|
||||
|
||||
@mock.patch('openstack.common.versionutils.LOG')
|
||||
def test_deprecated_with_removed_zero(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
remove_in=0)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
self.assert_deprecated(mock_log,
|
||||
no_removal=True,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
remove_in='Grizzly')
|
||||
|
||||
@mock.patch('openstack.common.versionutils.LOG')
|
||||
def test_deprecated_with_removed_zero_and_alternative(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
|
||||
in_favor_of='different_stuff()',
|
||||
remove_in=0)
|
||||
def do_outdated_stuff():
|
||||
return
|
||||
|
||||
do_outdated_stuff()
|
||||
self.assert_deprecated(mock_log,
|
||||
no_removal=True,
|
||||
what='do_outdated_stuff()',
|
||||
as_of='Grizzly',
|
||||
in_favor_of='different_stuff()',
|
||||
remove_in='Grizzly')
|
||||
|
||||
|
||||
class IsCompatibleTestCase(test_base.BaseTestCase):
|
||||
def test_same_version(self):
|
||||
|
||||
Reference in New Issue
Block a user