summaryrefslogtreecommitdiff
path: root/taskflow/utils
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-12-18 23:42:35 +0000
committerGerrit Code Review <review@openstack.org>2014-12-18 23:42:35 +0000
commitba62a9c7be999f49d89af6c5e0636f6f89bbdd13 (patch)
tree41d1f83e32607a40c20a7a7ddb30b10a2ce64141 /taskflow/utils
parent0cf641b0c294b5d653f4377248d6b3df358f104b (diff)
parent4e514f41e57983e728db9025126df6f791a2594a (diff)
downloadtaskflow-0.6.0.tar.gz
Merge "Move over to using oslo.utils [reflection, uuidutils]"0.6.0
Diffstat (limited to 'taskflow/utils')
-rw-r--r--taskflow/utils/deprecation.py3
-rw-r--r--taskflow/utils/kazoo_utils.py2
-rw-r--r--taskflow/utils/misc.py48
-rw-r--r--taskflow/utils/persistence_utils.py2
-rw-r--r--taskflow/utils/reflection.py251
5 files changed, 50 insertions, 256 deletions
diff --git a/taskflow/utils/deprecation.py b/taskflow/utils/deprecation.py
index f70d767..5c46666 100644
--- a/taskflow/utils/deprecation.py
+++ b/taskflow/utils/deprecation.py
@@ -17,10 +17,9 @@
import functools
import warnings
+from oslo.utils import reflection
import six
-from taskflow.utils import reflection
-
_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"
diff --git a/taskflow/utils/kazoo_utils.py b/taskflow/utils/kazoo_utils.py
index 0a9922b..ab44963 100644
--- a/taskflow/utils/kazoo_utils.py
+++ b/taskflow/utils/kazoo_utils.py
@@ -16,11 +16,11 @@
from kazoo import client
from kazoo import exceptions as k_exc
+from oslo.utils import reflection
import six
from six.moves import zip as compat_zip
from taskflow import exceptions as exc
-from taskflow.utils import reflection
def _parse_hosts(hosts):
diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py
index 3491006..a6b04fa 100644
--- a/taskflow/utils/misc.py
+++ b/taskflow/utils/misc.py
@@ -23,9 +23,12 @@ import os
import re
import sys
import threading
+import types
from oslo.serialization import jsonutils
+from oslo.utils import importutils
from oslo.utils import netutils
+from oslo.utils import reflection
import six
from six.moves import map as compat_map
from six.moves import range as compat_range
@@ -34,7 +37,6 @@ from six.moves.urllib import parse as urlparse
from taskflow.types import failure
from taskflow.types import notifier
from taskflow.utils import deprecation
-from taskflow.utils import reflection
NUMERIC_TYPES = six.integer_types + (float,)
@@ -83,6 +85,50 @@ def merge_uri(uri, conf):
return conf
+def find_subclasses(locations, base_cls, exclude_hidden=True):
+ """Finds subclass types in the given locations.
+
+ This will examines the given locations for types which are subclasses of
+ the base class type provided and returns the found subclasses (or fails
+ with exceptions if this introspection can not be accomplished).
+
+ If a string is provided as one of the locations it will be imported and
+ examined if it is a subclass of the base class. If a module is given,
+ all of its members will be examined for attributes which are subclasses of
+ the base class. If a type itself is given it will be examined for being a
+ subclass of the base class.
+ """
+ derived = set()
+ for item in locations:
+ module = None
+ if isinstance(item, six.string_types):
+ try:
+ pkg, cls = item.split(':')
+ except ValueError:
+ module = importutils.import_module(item)
+ else:
+ obj = importutils.import_class('%s.%s' % (pkg, cls))
+ if not reflection.is_subclass(obj, base_cls):
+ raise TypeError("Item %s is not a %s subclass" %
+ (item, base_cls))
+ derived.add(obj)
+ elif isinstance(item, types.ModuleType):
+ module = item
+ elif reflection.is_subclass(item, base_cls):
+ derived.add(item)
+ else:
+ raise TypeError("Item %s unexpected type: %s" %
+ (item, type(item)))
+ # If it's a module derive objects from it if we can.
+ if module is not None:
+ for (name, obj) in inspect.getmembers(module):
+ if name.startswith("_") and exclude_hidden:
+ continue
+ if reflection.is_subclass(obj, base_cls):
+ derived.add(obj)
+ return derived
+
+
def parse_uri(uri):
"""Parses a uri into its components."""
# Do some basic validation before continuing...
diff --git a/taskflow/utils/persistence_utils.py b/taskflow/utils/persistence_utils.py
index 340f558..b8a1535 100644
--- a/taskflow/utils/persistence_utils.py
+++ b/taskflow/utils/persistence_utils.py
@@ -17,9 +17,9 @@
import contextlib
from oslo.utils import timeutils
+from oslo.utils import uuidutils
from taskflow import logging
-from taskflow.openstack.common import uuidutils
from taskflow.persistence import logbook
from taskflow.utils import misc
diff --git a/taskflow/utils/reflection.py b/taskflow/utils/reflection.py
deleted file mode 100644
index 08eaf6c..0000000
--- a/taskflow/utils/reflection.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2012-2013 Yahoo! Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import inspect
-import types
-
-from oslo.utils import importutils
-import six
-
-try:
- _TYPE_TYPE = types.TypeType
-except AttributeError:
- _TYPE_TYPE = type
-
-# See: https://docs.python.org/2/library/__builtin__.html#module-__builtin__
-# and see https://docs.python.org/2/reference/executionmodel.html (and likely
-# others)...
-_BUILTIN_MODULES = ('builtins', '__builtin__', 'exceptions')
-
-
-def _get_members(obj, exclude_hidden):
- """Yields the members of an object, filtering by hidden/not hidden."""
- for (name, value) in inspect.getmembers(obj):
- if name.startswith("_") and exclude_hidden:
- continue
- yield (name, value)
-
-
-def find_subclasses(locations, base_cls, exclude_hidden=True):
- """Finds subclass types in the given locations.
-
- This will examines the given locations for types which are subclasses of
- the base class type provided and returns the found subclasses (or fails
- with exceptions if this introspection can not be accomplished).
-
- If a string is provided as one of the locations it will be imported and
- examined if it is a subclass of the base class. If a module is given,
- all of its members will be examined for attributes which are subclasses of
- the base class. If a type itself is given it will be examined for being a
- subclass of the base class.
- """
- derived = set()
- for item in locations:
- module = None
- if isinstance(item, six.string_types):
- try:
- pkg, cls = item.split(':')
- except ValueError:
- module = importutils.import_module(item)
- else:
- obj = importutils.import_class('%s.%s' % (pkg, cls))
- if not is_subclass(obj, base_cls):
- raise TypeError("Item %s is not a %s subclass" %
- (item, base_cls))
- derived.add(obj)
- elif isinstance(item, types.ModuleType):
- module = item
- elif is_subclass(item, base_cls):
- derived.add(item)
- else:
- raise TypeError("Item %s unexpected type: %s" %
- (item, type(item)))
- # If it's a module derive objects from it if we can.
- if module is not None:
- for (_name, obj) in _get_members(module, exclude_hidden):
- if is_subclass(obj, base_cls):
- derived.add(obj)
- return derived
-
-
-def get_member_names(obj, exclude_hidden=True):
- """Get all the member names for a object."""
- return [name for (name, _obj) in _get_members(obj, exclude_hidden)]
-
-
-def get_class_name(obj, fully_qualified=True):
- """Get class name for object.
-
- If object is a type, fully qualified name of the type is returned.
- Else, fully qualified name of the type of the object is returned.
- For builtin types, just name is returned.
- """
- if not isinstance(obj, six.class_types):
- obj = type(obj)
- try:
- built_in = obj.__module__ in _BUILTIN_MODULES
- except AttributeError:
- pass
- else:
- if built_in:
- try:
- return obj.__qualname__
- except AttributeError:
- return obj.__name__
- pieces = []
- try:
- pieces.append(obj.__qualname__)
- except AttributeError:
- pieces.append(obj.__name__)
- if fully_qualified:
- try:
- pieces.insert(0, obj.__module__)
- except AttributeError:
- pass
- return '.'.join(pieces)
-
-
-def get_all_class_names(obj, up_to=object):
- """Get class names of object parent classes.
-
- Iterate over all class names object is instance or subclass of,
- in order of method resolution (mro). If up_to parameter is provided,
- only name of classes that are sublcasses to that class are returned.
- """
- if not isinstance(obj, six.class_types):
- obj = type(obj)
- for cls in obj.mro():
- if issubclass(cls, up_to):
- yield get_class_name(cls)
-
-
-def get_callable_name(function):
- """Generate a name from callable.
-
- Tries to do the best to guess fully qualified callable name.
- """
- method_self = get_method_self(function)
- if method_self is not None:
- # This is a bound method.
- if isinstance(method_self, six.class_types):
- # This is a bound class method.
- im_class = method_self
- else:
- im_class = type(method_self)
- try:
- parts = (im_class.__module__, function.__qualname__)
- except AttributeError:
- parts = (im_class.__module__, im_class.__name__, function.__name__)
- elif inspect.ismethod(function) or inspect.isfunction(function):
- # This could be a function, a static method, a unbound method...
- try:
- parts = (function.__module__, function.__qualname__)
- except AttributeError:
- if hasattr(function, 'im_class'):
- # This is a unbound method, which exists only in python 2.x
- im_class = function.im_class
- parts = (im_class.__module__,
- im_class.__name__, function.__name__)
- else:
- parts = (function.__module__, function.__name__)
- else:
- im_class = type(function)
- if im_class is _TYPE_TYPE:
- im_class = function
- try:
- parts = (im_class.__module__, im_class.__qualname__)
- except AttributeError:
- parts = (im_class.__module__, im_class.__name__)
- return '.'.join(parts)
-
-
-def get_method_self(method):
- if not inspect.ismethod(method):
- return None
- try:
- return six.get_method_self(method)
- except AttributeError:
- return None
-
-
-def is_same_callback(callback1, callback2, strict=True):
- """Returns if the two callbacks are the same."""
- if callback1 is callback2:
- # This happens when plain methods are given (or static/non-bound
- # methods).
- return True
- if callback1 == callback2:
- if not strict:
- return True
- # Two bound methods are equal if functions themselves are equal and
- # objects they are applied to are equal. This means that a bound
- # method could be the same bound method on another object if the
- # objects have __eq__ methods that return true (when in fact it is a
- # different bound method). Python u so crazy!
- try:
- self1 = six.get_method_self(callback1)
- self2 = six.get_method_self(callback2)
- return self1 is self2
- except AttributeError:
- pass
- return False
-
-
-def is_bound_method(method):
- """Returns if the given method is bound to an object."""
- return bool(get_method_self(method))
-
-
-def is_subclass(obj, cls):
- """Returns if the object is class and it is subclass of a given class."""
- return inspect.isclass(obj) and issubclass(obj, cls)
-
-
-def _get_arg_spec(function):
- if isinstance(function, type):
- bound = True
- function = function.__init__
- elif isinstance(function, (types.FunctionType, types.MethodType)):
- bound = is_bound_method(function)
- function = getattr(function, '__wrapped__', function)
- else:
- function = function.__call__
- bound = is_bound_method(function)
- return inspect.getargspec(function), bound
-
-
-def get_callable_args(function, required_only=False):
- """Get names of callable arguments.
-
- Special arguments (like ``*args`` and ``**kwargs``) are not included into
- output.
-
- If required_only is True, optional arguments (with default values)
- are not included into output.
- """
- argspec, bound = _get_arg_spec(function)
- f_args = argspec.args
- if required_only and argspec.defaults:
- f_args = f_args[:-len(argspec.defaults)]
- if bound:
- f_args = f_args[1:]
- return f_args
-
-
-def accepts_kwargs(function):
- """Returns True if function accepts kwargs."""
- argspec, _bound = _get_arg_spec(function)
- return bool(argspec.keywords)