summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorgan Fainberg <morgan.fainberg@gmail.com>2014-07-12 17:06:27 -0700
committerMorgan Fainberg <morgan.fainberg@gmail.com>2014-07-12 23:23:33 -0700
commita2ad3a253b6200633028f5f2e188a2f102277ba5 (patch)
tree2dde15eb4793ed23f6053cc7cfb6d243d8b7acd0
parent05ae498b3a8d94a8746f14da395af58d3bbc1f77 (diff)
downloadoslo-incubator-a2ad3a253b6200633028f5f2e188a2f102277ba5.tar.gz
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
-rw-r--r--openstack/common/versionutils.py28
-rw-r--r--tests/unit/test_versionutils.py47
2 files changed, 70 insertions, 5 deletions
diff --git a/openstack/common/versionutils.py b/openstack/common/versionutils.py
index 095a5838..dee0828d 100644
--- a/openstack/common/versionutils.py
+++ b/openstack/common/versionutils.py
@@ -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
diff --git a/tests/unit/test_versionutils.py b/tests/unit/test_versionutils.py
index 036931dc..30e48d27 100644
--- a/tests/unit/test_versionutils.py
+++ b/tests/unit/test_versionutils.py
@@ -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):