From c9c0505814a88ecea0c995aa4f0dd97883978559 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Fri, 6 Feb 2015 17:14:06 -0800 Subject: [PATCH] Use debtcollector library to replace internal utility The new debtcollector library was extracted from this code and has now been released (and made available in the requirements list) so we can go ahead and just use it for most of the cases (minus the proxy moved class) in our code-base to reduce the amount of custom code we have to maintain to perform deprecation activities. Change-Id: Ieeda6ffe282b67a1c1bb4f72e5858d22df0f30a0 --- requirements-py2.txt | 3 + requirements-py3.txt | 3 + taskflow/conductors/single_threaded.py | 4 +- taskflow/engines/base.py | 12 ++- taskflow/engines/helpers.py | 18 ++-- taskflow/listeners/base.py | 15 ++-- taskflow/utils/deprecation.py | 120 ++----------------------- taskflow/utils/misc.py | 10 ++- 8 files changed, 41 insertions(+), 144 deletions(-) diff --git a/requirements-py2.txt b/requirements-py2.txt index 083caec03..0a88a9f8d 100644 --- a/requirements-py2.txt +++ b/requirements-py2.txt @@ -28,3 +28,6 @@ jsonschema>=2.0.0,<3.0.0 # For common utilities oslo.utils>=1.2.0 # Apache-2.0 oslo.serialization>=1.2.0 # Apache-2.0 + +# For deprecation of things +debtcollector>=0.2 diff --git a/requirements-py3.txt b/requirements-py3.txt index b04fc0aff..033ca7106 100644 --- a/requirements-py3.txt +++ b/requirements-py3.txt @@ -22,3 +22,6 @@ jsonschema>=2.0.0,<3.0.0 # For common utilities oslo.utils>=1.2.0 # Apache-2.0 oslo.serialization>=1.2.0 # Apache-2.0 + +# For deprecation of things +debtcollector>=0.2 diff --git a/taskflow/conductors/single_threaded.py b/taskflow/conductors/single_threaded.py index aa90645f6..c8ab5a034 100644 --- a/taskflow/conductors/single_threaded.py +++ b/taskflow/conductors/single_threaded.py @@ -14,6 +14,8 @@ # License for the specific language governing permissions and limitations # under the License. +from debtcollector import moves + from taskflow.conductors.backends import impl_blocking from taskflow.utils import deprecation @@ -23,6 +25,6 @@ deprecation.removed_module(__name__, version="0.8", removal_version="?") # TODO(harlowja): remove this proxy/legacy class soon... -SingleThreadedConductor = deprecation.moved_inheritable_class( +SingleThreadedConductor = moves.moved_class( impl_blocking.BlockingConductor, 'SingleThreadedConductor', __name__, version="0.8", removal_version="?") diff --git a/taskflow/engines/base.py b/taskflow/engines/base.py index 7ea8e7089..5e2263ebd 100644 --- a/taskflow/engines/base.py +++ b/taskflow/engines/base.py @@ -17,11 +17,11 @@ import abc +from debtcollector import moves import six from taskflow import storage from taskflow.types import notifier -from taskflow.utils import deprecation from taskflow.utils import misc @@ -56,8 +56,8 @@ class Engine(object): return self._notifier @property - @deprecation.moved_property('atom_notifier', version="0.6", - removal_version="?") + @moves.moved_property('atom_notifier', version="0.6", + removal_version="?") def task_notifier(self): """The task notifier.""" return self._atom_notifier @@ -113,7 +113,5 @@ class Engine(object): # TODO(harlowja): remove in 0.7 or later... -EngineBase = deprecation.moved_inheritable_class(Engine, - 'EngineBase', __name__, - version="0.6", - removal_version="?") +EngineBase = moves.moved_class(Engine, 'EngineBase', __name__, + version="0.6", removal_version="?") diff --git a/taskflow/engines/helpers.py b/taskflow/engines/helpers.py index 3d8ccf55f..43ea8b6e5 100644 --- a/taskflow/engines/helpers.py +++ b/taskflow/engines/helpers.py @@ -18,6 +18,7 @@ import contextlib import itertools import traceback +from debtcollector import renames from oslo_utils import importutils from oslo_utils import reflection import six @@ -26,7 +27,6 @@ import stevedore.driver from taskflow import exceptions as exc from taskflow import logging from taskflow.persistence import backends as p_backends -from taskflow.utils import deprecation from taskflow.utils import misc from taskflow.utils import persistence_utils as p_utils @@ -90,14 +90,14 @@ def _extract_engine(**kwargs): lambda frame: frame[0] in _FILE_NAMES, reversed(traceback.extract_stack(limit=3))) stacklevel = sum(1 for _frame in finder) - decorator = deprecation.renamed_kwarg('engine_conf', 'engine', - version="0.6", - removal_version="?", - # Three is added on since the - # decorator adds three of its own - # stack levels that we need to - # hop out of... - stacklevel=stacklevel + 3) + decorator = renames.renamed_kwarg('engine_conf', 'engine', + version="0.6", + removal_version="?", + # Three is added on since the + # decorator adds three of its own + # stack levels that we need to + # hop out of... + stacklevel=stacklevel + 3) return decorator(_compat_extract)(**kwargs) else: return _compat_extract(**kwargs) diff --git a/taskflow/listeners/base.py b/taskflow/listeners/base.py index 4884d90ea..75b0db095 100644 --- a/taskflow/listeners/base.py +++ b/taskflow/listeners/base.py @@ -18,6 +18,7 @@ from __future__ import absolute_import import abc +from debtcollector import moves from oslo_utils import excutils import six @@ -25,7 +26,6 @@ from taskflow import logging from taskflow import states from taskflow.types import failure from taskflow.types import notifier -from taskflow.utils import deprecation LOG = logging.getLogger(__name__) @@ -165,10 +165,8 @@ class Listener(object): # TODO(harlowja): remove in 0.7 or later... -ListenerBase = deprecation.moved_inheritable_class(Listener, - 'ListenerBase', __name__, - version="0.6", - removal_version="?") +ListenerBase = moves.moved_class(Listener, 'ListenerBase', __name__, + version="0.6", removal_version="?") @six.add_metaclass(abc.ABCMeta) @@ -213,10 +211,9 @@ class DumpingListener(Listener): # TODO(harlowja): remove in 0.7 or later... -class LoggingBase(deprecation.moved_inheritable_class(DumpingListener, - 'LoggingBase', __name__, - version="0.6", - removal_version="?")): +class LoggingBase(moves.moved_class(DumpingListener, + 'LoggingBase', __name__, + version="0.6", removal_version="?")): def _dump(self, message, *args, **kwargs): self._log(message, *args, **kwargs) diff --git a/taskflow/utils/deprecation.py b/taskflow/utils/deprecation.py index 55ed982d8..8bb48b27c 100644 --- a/taskflow/utils/deprecation.py +++ b/taskflow/utils/deprecation.py @@ -14,17 +14,11 @@ # License for the specific language governing permissions and limitations # under the License. -import functools import warnings from oslo_utils import reflection import six -_CLASS_MOVED_PREFIX_TPL = "Class '%s' has moved to '%s'" -_KIND_MOVED_PREFIX_TPL = "%s '%s' has moved to '%s'" -_KWARG_MOVED_POSTFIX_TPL = ", please use the '%s' argument instead" -_KWARG_MOVED_PREFIX_TPL = "Using the '%s' argument is deprecated" - def deprecation(message, stacklevel=None): """Warns about some type of deprecation that has been (or will be) made. @@ -137,34 +131,11 @@ def _generate_message(prefix, postfix=None, message=None, return ''.join(message_components) -def renamed_kwarg(old_name, new_name, message=None, - version=None, removal_version=None, stacklevel=3): - """Decorates a kwarg accepting function to deprecate a renamed kwarg.""" - - prefix = _KWARG_MOVED_PREFIX_TPL % old_name - postfix = _KWARG_MOVED_POSTFIX_TPL % new_name - out_message = _generate_message(prefix, postfix=postfix, - message=message, version=version, - removal_version=removal_version) - - def decorator(f): - - @six.wraps(f) - def wrapper(*args, **kwargs): - if old_name in kwargs: - deprecation(out_message, stacklevel=stacklevel) - return f(*args, **kwargs) - - return wrapper - - return decorator - - def removed_kwarg(old_name, message=None, version=None, removal_version=None, stacklevel=3): """Decorates a kwarg accepting function to deprecate a removed kwarg.""" - prefix = _KWARG_MOVED_PREFIX_TPL % old_name + prefix = "Using the '%s' argument is deprecated" % old_name out_message = _generate_message(prefix, postfix=None, message=message, version=version, removal_version=removal_version) @@ -182,41 +153,9 @@ def removed_kwarg(old_name, message=None, return decorator -def _moved_decorator(kind, new_attribute_name, message=None, - version=None, removal_version=None, - stacklevel=3): - """Decorates a method/property that was moved to another location.""" - - def decorator(f): - try: - old_attribute_name = f.__qualname__ - fully_qualified = True - except AttributeError: - old_attribute_name = f.__name__ - fully_qualified = False - - @six.wraps(f) - def wrapper(self, *args, **kwargs): - base_name = reflection.get_class_name(self, fully_qualified=False) - if fully_qualified: - old_name = old_attribute_name - else: - old_name = ".".join((base_name, old_attribute_name)) - new_name = ".".join((base_name, new_attribute_name)) - prefix = _KIND_MOVED_PREFIX_TPL % (kind, old_name, new_name) - out_message = _generate_message( - prefix, message=message, - version=version, removal_version=removal_version) - deprecation(out_message, stacklevel=stacklevel) - return f(self, *args, **kwargs) - - return wrapper - - return decorator - - def removed_module(module_name, replacement_name=None, message=None, version=None, removal_version=None, stacklevel=4): + """Deprecates a module that will be removed/replaced in the future.""" prefix = "The '%s' module usage is deprecated" % module_name if replacement_name: postfix = ", please use %s instead" % replacement_name @@ -229,56 +168,9 @@ def removed_module(module_name, replacement_name=None, message=None, deprecation(out_message, stacklevel=stacklevel) -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) - - -def moved_inheritable_class(new_class, old_class_name, old_module_name, - message=None, version=None, removal_version=None): - """Deprecates a class that was moved to another location. - - NOTE(harlowja): this creates a new-old type that can be used for a - deprecation period that can be inherited from, the difference between this - and the ``moved_class`` deprecation function is that the proxy from that - function can not be inherited from (thus limiting its use for a more - particular usecase where inheritance is not needed). - - This will emit warnings when the old locations class is initialized, - telling where the new and improved location for the old class now is. - """ - old_name = ".".join((old_module_name, old_class_name)) - new_name = reflection.get_class_name(new_class) - prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name) - out_message = _generate_message(prefix, - message=message, version=version, - removal_version=removal_version) - - def decorator(f): - - # Use the older functools until the following is available: - # - # https://bitbucket.org/gutworth/six/issue/105 - - @functools.wraps(f, assigned=("__name__", "__doc__")) - def wrapper(self, *args, **kwargs): - deprecation(out_message, stacklevel=3) - return f(self, *args, **kwargs) - - return wrapper - - old_class = type(old_class_name, (new_class,), {}) - old_class.__module__ = old_module_name - old_class.__init__ = decorator(old_class.__init__) - return old_class - - -def moved_class(new_class, old_class_name, old_module_name, message=None, - version=None, removal_version=None, stacklevel=3): +def moved_proxy_class(new_class, old_class_name, old_module_name, + message=None, version=None, removal_version=None, + stacklevel=3): """Deprecates a class that was moved to another location. This will emit warnings when the old locations class is initialized, @@ -286,7 +178,7 @@ def moved_class(new_class, old_class_name, old_module_name, message=None, """ old_name = ".".join((old_module_name, old_class_name)) new_name = reflection.get_class_name(new_class) - prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name) + prefix = "Class '%s' has moved to '%s'" % (old_name, new_name) out_message = _generate_message(prefix, message=message, version=version, removal_version=removal_version) diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py index b2e967d44..db99fd50c 100644 --- a/taskflow/utils/misc.py +++ b/taskflow/utils/misc.py @@ -419,12 +419,14 @@ def ensure_tree(path): raise -Failure = deprecation.moved_class(failure.Failure, 'Failure', __name__, - version="0.6", removal_version="?") +Failure = deprecation.moved_proxy_class(failure.Failure, + 'Failure', __name__, + version="0.6", removal_version="?") -Notifier = deprecation.moved_class(notifier.Notifier, 'Notifier', __name__, - version="0.6", removal_version="?") +Notifier = deprecation.moved_proxy_class(notifier.Notifier, + 'Notifier', __name__, + version="0.6", removal_version="?") @contextlib.contextmanager