hooke.ui.gui was getting complicated, so I stripped it down for a moment.
[hooke.git] / hooke / util / pluggable.py
index 0a491cb67b9491f4719292c86697422a6fd749a6..14eaeb0209ed0f9bd4f6326dd19d85e355df3fe9 100644 (file)
@@ -19,7 +19,8 @@
 """`pluggable`
 """
 
-from ..util.graph import Node, Graph
+from ..compat.odict import odict
+from .graph import Node, Graph
 
 
 class IsSubclass (object):
@@ -58,6 +59,34 @@ class IsSubclass (object):
             return False
         return subclass
 
+
+def construct_odict(this_modname, submodnames, class_selector,
+                    instantiate=True):
+    """Search the submodules `submodnames` of a module `this_modname`
+    for class objects for which `class_selector(class)` returns
+    `True`.  If `instantiate == True` these classes are instantiated
+    and stored in the returned :class:`hooke.compat.odict.odict` in
+    the order in which they were discovered.  Otherwise, the class
+    itself is stored.
+    """
+    objs = odict()
+    for submodname in submodnames:
+        count = len([s for s in submodnames if s == submodname])
+        assert count > 0, 'No %s entries: %s' % (submodname, submodnames)
+        assert count == 1, 'Multiple (%d) %s entries: %s' \
+            % (count, submodname, submodnames)
+        this_mod = __import__(this_modname, fromlist=[submodname])
+        submod = getattr(this_mod, submodname)
+        for objname in dir(submod):
+            obj = getattr(submod, objname)
+            if class_selector(obj):
+                if instantiate == True:
+                    obj = obj()
+                name = getattr(obj, 'name', submodname)
+                objs[name] = obj
+    return objs
+
+
 def construct_graph(this_modname, submodnames, class_selector,
                     assert_name_match=True):
     """Search the submodules `submodnames` of a module `this_modname`