diff options
| author | Jenkins <jenkins@review.openstack.org> | 2014-12-18 23:42:35 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2014-12-18 23:42:35 +0000 |
| commit | ba62a9c7be999f49d89af6c5e0636f6f89bbdd13 (patch) | |
| tree | 41d1f83e32607a40c20a7a7ddb30b10a2ce64141 /taskflow/utils/misc.py | |
| parent | 0cf641b0c294b5d653f4377248d6b3df358f104b (diff) | |
| parent | 4e514f41e57983e728db9025126df6f791a2594a (diff) | |
| download | taskflow-0.6.0.tar.gz | |
Merge "Move over to using oslo.utils [reflection, uuidutils]"0.6.0
Diffstat (limited to 'taskflow/utils/misc.py')
| -rw-r--r-- | taskflow/utils/misc.py | 48 |
1 files changed, 47 insertions, 1 deletions
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... |
