From 2f7e58235bf55aa3072b6b736b2dacc7ff3a7e1b Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Thu, 20 Nov 2014 15:26:00 -0800 Subject: [PATCH] Revert wrapt usage until further notice Currently its usage is failing on stable/icehouse which is being fixed, but that branch is also currently broken due to a tempest failure; so until this situation is resolved take out the usage of wrapt. Part of fixes for bug 1394647 Change-Id: Ibfe21944b6e6882f19f7cf4359e8356a64200278 --- requirements-py2.txt | 3 - requirements-py3.txt | 3 - taskflow/engines/action_engine/engine.py | 2 +- taskflow/engines/action_engine/runtime.py | 8 +- taskflow/engines/base.py | 26 +---- taskflow/tests/unit/test_failure.py | 12 -- taskflow/tests/unit/test_notifier.py | 9 -- taskflow/utils/deprecation.py | 127 ++++++++++++---------- 8 files changed, 77 insertions(+), 113 deletions(-) diff --git a/requirements-py2.txt b/requirements-py2.txt index d4469f8c..0827e7ed 100644 --- a/requirements-py2.txt +++ b/requirements-py2.txt @@ -13,9 +13,6 @@ ordereddict # Python 2->3 compatibility library. six>=1.7.0 -# For proxying objects and making correct decorators -wrapt>=1.7.0 # BSD License - # Very nice graph library networkx>=1.8 diff --git a/requirements-py3.txt b/requirements-py3.txt index 174eb59c..5f265dcc 100644 --- a/requirements-py3.txt +++ b/requirements-py3.txt @@ -10,9 +10,6 @@ pbr>=0.6,!=0.7,<1.0 # Python 2->3 compatibility library. six>=1.7.0 -# For proxying objects and making correct decorators -wrapt>=1.7.0 # BSD License - # Very nice graph library networkx>=1.8 diff --git a/taskflow/engines/action_engine/engine.py b/taskflow/engines/action_engine/engine.py index 5a0fc9fb..730d2895 100644 --- a/taskflow/engines/action_engine/engine.py +++ b/taskflow/engines/action_engine/engine.py @@ -217,7 +217,7 @@ class ActionEngine(base.EngineBase): self._compilation = self._compiler.compile() self._runtime = runtime.Runtime(self._compilation, self.storage, - self.atom_notifier, + self.task_notifier, self._task_executor) self._compiled = True diff --git a/taskflow/engines/action_engine/runtime.py b/taskflow/engines/action_engine/runtime.py index 9e053a47..06959f29 100644 --- a/taskflow/engines/action_engine/runtime.py +++ b/taskflow/engines/action_engine/runtime.py @@ -36,8 +36,8 @@ class Runtime(object): action engine to run to completion. """ - def __init__(self, compilation, storage, atom_notifier, task_executor): - self._atom_notifier = atom_notifier + def __init__(self, compilation, storage, task_notifier, task_executor): + self._task_notifier = task_notifier self._task_executor = task_executor self._storage = storage self._compilation = compilation @@ -68,7 +68,7 @@ class Runtime(object): @misc.cachedproperty def retry_action(self): - return ra.RetryAction(self._storage, self._atom_notifier, + return ra.RetryAction(self._storage, self._task_notifier, lambda atom: sc.ScopeWalker(self.compilation, atom, names_only=True)) @@ -76,7 +76,7 @@ class Runtime(object): @misc.cachedproperty def task_action(self): return ta.TaskAction(self._storage, self._task_executor, - self._atom_notifier, + self._task_notifier, lambda atom: sc.ScopeWalker(self.compilation, atom, names_only=True)) diff --git a/taskflow/engines/base.py b/taskflow/engines/base.py index 2c409726..2fab9d0f 100644 --- a/taskflow/engines/base.py +++ b/taskflow/engines/base.py @@ -20,7 +20,6 @@ import abc import six from taskflow.types import notifier -from taskflow.utils import deprecation from taskflow.utils import misc @@ -32,10 +31,6 @@ class EngineBase(object): occur related to the flow the engine contains. :ivar task_notifier: A notification object that will dispatch events that occur related to the tasks the engine contains. - occur related to the tasks the engine - contains (deprecated). - :ivar atom_notifier: A notification object that will dispatch events that - occur related to the atoms the engine contains. """ def __init__(self, flow, flow_detail, backend, options): @@ -46,25 +41,8 @@ class EngineBase(object): self._options = {} else: self._options = dict(options) - self._notifier = notifier.Notifier() - self._atom_notifier = notifier.Notifier() - - @property - def notifier(self): - """The flow notifier.""" - return self._notifier - - @property - @deprecation.moved_property('atom_notifier', version="0.6", - removal_version="?") - def task_notifier(self): - """The task notifier.""" - return self._atom_notifier - - @property - def atom_notifier(self): - """The atom notifier.""" - return self._atom_notifier + self.notifier = notifier.Notifier() + self.task_notifier = notifier.Notifier() @property def options(self): diff --git a/taskflow/tests/unit/test_failure.py b/taskflow/tests/unit/test_failure.py index b70add4f..793274e1 100644 --- a/taskflow/tests/unit/test_failure.py +++ b/taskflow/tests/unit/test_failure.py @@ -22,7 +22,6 @@ from taskflow import exceptions from taskflow import test from taskflow.tests import utils as test_utils from taskflow.types import failure -from taskflow.utils import misc def _captured_failure(msg): @@ -39,17 +38,6 @@ def _make_exc_info(msg): return sys.exc_info() -class DeprecatedTestCase(test.TestCase): - def test_deprecated(self): - f = None - try: - raise RuntimeError("Woot!") - except RuntimeError: - f = misc.Failure() - self.assertIsInstance(f, failure.Failure) - self.assertIsInstance(f, misc.Failure) - - class GeneralFailureObjTestsMixin(object): def test_captures_message(self): diff --git a/taskflow/tests/unit/test_notifier.py b/taskflow/tests/unit/test_notifier.py index 61dc7746..0761cb6e 100644 --- a/taskflow/tests/unit/test_notifier.py +++ b/taskflow/tests/unit/test_notifier.py @@ -20,15 +20,6 @@ import functools from taskflow import states from taskflow import test from taskflow.types import notifier as nt -from taskflow.utils import misc - - -class DeprecatedTestCase(test.TestCase): - def test_deprecated(self): - notifier = misc.Notifier() - self.assertIsInstance(notifier, misc.Notifier) - self.assertIsInstance(notifier, nt.Notifier) - self.assertTrue(hasattr(misc.Notifier, 'ANY')) class NotifierTest(test.TestCase): diff --git a/taskflow/utils/deprecation.py b/taskflow/utils/deprecation.py index b83cce58..899e035d 100644 --- a/taskflow/utils/deprecation.py +++ b/taskflow/utils/deprecation.py @@ -14,11 +14,8 @@ # License for the specific language governing permissions and limitations # under the License. -import functools import warnings -import wrapt - from taskflow.utils import reflection @@ -27,67 +24,72 @@ def deprecation(message, stacklevel=2): warnings.warn(message, category=DeprecationWarning, stacklevel=stacklevel) -class MovedClassProxy(wrapt.ObjectProxy): - """Acts as a proxy to a class that was moved to another location.""" +# Helper accessors for the moved proxy (since it will not have easy access +# to its own getattr and setattr functions). +_setattr = object.__setattr__ +_getattr = object.__getattribute__ + + +class MovedClassProxy(object): + """Acts as a proxy to a class that was moved to another location. + + Partially based on: + + http://code.activestate.com/recipes/496741-object-proxying/ and other + various examination of how to make a good enough proxy for our usage to + move the various types we want to move during the deprecation process. + + And partially based on the wrapt object proxy (which we should just use + when it becomes available @ http://review.openstack.org/#/c/94754/). + """ + + __slots__ = [ + '__wrapped__', '__message__', '__stacklevel__', + # Ensure weakrefs can be made, + # https://docs.python.org/2/reference/datamodel.html#slots + '__weakref__', + ] def __init__(self, wrapped, message, stacklevel): - super(MovedClassProxy, self).__init__(wrapped) - self._self_message = message - self._self_stacklevel = stacklevel - - def __call__(self, *args, **kwargs): - deprecation(self._self_message, stacklevel=self._self_stacklevel) - return self.__wrapped__(*args, **kwargs) + # We can't assign to these directly, since we are overriding getattr + # and setattr and delattr so we have to do this hoop jump to ensure + # that we don't invoke those methods (and cause infinite recursion). + _setattr(self, '__wrapped__', wrapped) + _setattr(self, '__message__', message) + _setattr(self, '__stacklevel__', stacklevel) + try: + _setattr(self, '__qualname__', wrapped.__qualname__) + except AttributeError: + pass def __instancecheck__(self, instance): - deprecation(self._self_message, stacklevel=self._self_stacklevel) - return isinstance(instance, self.__wrapped__) + deprecation( + _getattr(self, '__message__'), _getattr(self, '__stacklevel__')) + return isinstance(instance, _getattr(self, '__wrapped__')) def __subclasscheck__(self, instance): - deprecation(self._self_message, stacklevel=self._self_stacklevel) - return issubclass(instance, self.__wrapped__) + deprecation( + _getattr(self, '__message__'), _getattr(self, '__stacklevel__')) + return issubclass(instance, _getattr(self, '__wrapped__')) + def __call__(self, *args, **kwargs): + deprecation( + _getattr(self, '__message__'), _getattr(self, '__stacklevel__')) + return _getattr(self, '__wrapped__')(*args, **kwargs) -def _generate_moved_message(kind, old_name, new_name, - message=None, version=None, removal_version=None): - message_components = [ - "%s '%s' has moved to '%s'" % (kind, old_name, new_name), - ] - if version: - message_components.append(" in version '%s'" % version) - if removal_version: - if removal_version == "?": - message_components.append(" and will be removed in a future" - " version") - else: - message_components.append(" and will be removed in version" - " '%s'" % removal_version) - if message: - message_components.append(": %s" % message) - return ''.join(message_components) + def __getattribute__(self, name): + return getattr(_getattr(self, '__wrapped__'), name) + def __setattr__(self, name, value): + setattr(_getattr(self, '__wrapped__'), name, value) -def _moved_decorator(kind, new_name, message=None, - version=None, removal_version=None): - """Decorates a method/function/other that was moved to another location.""" + def __delattr__(self, name): + delattr(_getattr(self, '__wrapped__'), name) - @wrapt.decorator - def decorator(wrapped, instance, args, kwargs): - try: - old_name = wrapped.__qualname__ - except AttributeError: - old_name = wrapped.__name__ - out_message = _generate_moved_message(kind, old_name, new_name, - message=message, version=version, - removal_version=removal_version) - deprecation(out_message, 3) - return wrapped(*args, **kwargs) - - return decorator - - -"""Decorates a property that was moved to another location.""" -moved_property = functools.partial(_moved_decorator, 'Property') + def __repr__(self): + wrapped = _getattr(self, '__wrapped__') + return "<%s at 0x%x for %r at 0x%x>" % ( + type(self).__name__, id(self), wrapped, id(wrapped)) def moved_class(new_class, old_class_name, old_module_name, message=None, @@ -99,7 +101,18 @@ 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) - out_message = _generate_moved_message('Class', old_name, new_name, - message=message, version=version, - removal_version=removal_version) - return MovedClassProxy(new_class, out_message, 3) + message_components = [ + "Class '%s' has moved to '%s'" % (old_name, new_name), + ] + if version: + message_components.append(" in version '%s'" % version) + if removal_version: + if removal_version == "?": + message_components.append(" and will be removed in a future" + " version") + else: + message_components.append(" and will be removed in version '%s'" + % removal_version) + if message: + message_components.append(": %s" % message) + return MovedClassProxy(new_class, "".join(message_components), 3)