[Checkins] SVN: martian/branches/philikon-methodgrokker/src/martian/ Move the MethodGrokker to martian.

Philipp von Weitershausen philikon at philikon.de
Mon May 26 07:36:49 EDT 2008


Log message for revision 86968:
  Move the MethodGrokker to martian.
  

Changed:
  U   martian/branches/philikon-methodgrokker/src/martian/__init__.py
  U   martian/branches/philikon-methodgrokker/src/martian/components.py
  A   martian/branches/philikon-methodgrokker/src/martian/tests/public_methods_from_class.txt
  U   martian/branches/philikon-methodgrokker/src/martian/tests/test_all.py
  U   martian/branches/philikon-methodgrokker/src/martian/util.py

-=-
Modified: martian/branches/philikon-methodgrokker/src/martian/__init__.py
===================================================================
--- martian/branches/philikon-methodgrokker/src/martian/__init__.py	2008-05-26 11:30:46 UTC (rev 86967)
+++ martian/branches/philikon-methodgrokker/src/martian/__init__.py	2008-05-26 11:36:49 UTC (rev 86968)
@@ -2,6 +2,7 @@
     ModuleGrokker, MultiGrokker, MetaMultiGrokker, grok_dotted_name,
     grok_package, grok_module)
 from martian.components import GlobalGrokker, ClassGrokker, InstanceGrokker
+from martian.components import MethodGrokker
 from martian.util import scan_for_classes
 from martian.directive import Directive, MarkerDirective, MultipleTimesDirective
 from martian.directive import ONCE, MULTIPLE, DICT

Modified: martian/branches/philikon-methodgrokker/src/martian/components.py
===================================================================
--- martian/branches/philikon-methodgrokker/src/martian/components.py	2008-05-26 11:30:46 UTC (rev 86967)
+++ martian/branches/philikon-methodgrokker/src/martian/components.py	2008-05-26 11:36:49 UTC (rev 86968)
@@ -14,8 +14,10 @@
 
 from zope.interface import implements
 
+from martian import util
+from martian import directive
+from martian.error import GrokError
 from martian.interfaces import IGrokker, IComponentGrokker
-from martian import util
 
 NOT_DEFINED = object()
 
@@ -64,6 +66,46 @@
     def execute(self, class_, **data):
         raise NotImplementedError
 
+
+class MethodGrokker(ClassGrokker):
+    directive.baseclass()
+
+    def grok(self, name, class_, module_info=None, **kw):
+        module = None
+        if module_info is not None:
+            module = module_info.getModule()
+
+        # Populate the data dict with information from class or module
+        for directive in self.directives:
+            kw[directive.name] = directive.get(class_, module, **kw)
+
+        # Ignore methods that are present on the component baseclass.
+        basemethods = set(util.public_methods_from_class(self.component_class))
+        methods = set(util.public_methods_from_class(class_)) - basemethods
+        if not methods:
+            raise GrokError("%r does not define any public methods. "
+                            "Please add methods to this class to enable "
+                            "its registration." % class_, class_)
+
+        results = []
+        for method in methods:
+            # Directives may also be applied to methods, so let's
+            # check each directive and potentially override the
+            # class-level value with a value from the method *locally*.
+            data = kw.copy()
+            for bound_dir in self.directives:
+                directive = bound_dir.directive
+                class_value = data[bound_dir.name]
+                data[bound_dir.name] = directive.store.get(directive, method,
+                                                           default=class_value)
+            results.append(self.execute(class_, method, **data))
+
+        return max(results)
+
+    def execute(self, class_, method, **data):
+        raise NotImplementedError
+
+
 class InstanceGrokker(ComponentGrokkerBase):
     """Grokker that groks instances in a module.
     """

Added: martian/branches/philikon-methodgrokker/src/martian/tests/public_methods_from_class.txt
===================================================================
--- martian/branches/philikon-methodgrokker/src/martian/tests/public_methods_from_class.txt	                        (rev 0)
+++ martian/branches/philikon-methodgrokker/src/martian/tests/public_methods_from_class.txt	2008-05-26 11:36:49 UTC (rev 86968)
@@ -0,0 +1,32 @@
+Consider the following class
+
+  >>> class A(object):
+  ...     an_attribute = 42
+  ...
+  ...     def __init__(self):
+  ...         pass # this method is ignored
+  ...
+  ...     def __call__(self):
+  ...         pass # this method is ignored
+  ...
+  ...     def __double_underscored(self):
+  ...         pass # this method is ignored
+  ...
+  ...     def _single_underscored(self):
+  ...         pass # this method is ignored
+  ...
+  ...     def should_be_public(self):
+  ...         pass # this method is found
+  ...
+  ...     def should_also_be_public(self):
+  ...         pass # this method is found
+  ...
+
+With martian's ``public_methods_from_class`` helper we can extract all
+public methods from this class, in other words, all methods that do
+not begin with an underscore:
+
+  >>> from martian import util
+  >>> methods = util.public_methods_from_class(A)
+  >>> sorted([m.__name__ for m in methods])
+  ['should_also_be_public', 'should_be_public']


Property changes on: martian/branches/philikon-methodgrokker/src/martian/tests/public_methods_from_class.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: martian/branches/philikon-methodgrokker/src/martian/tests/test_all.py
===================================================================
--- martian/branches/philikon-methodgrokker/src/martian/tests/test_all.py	2008-05-26 11:30:46 UTC (rev 86967)
+++ martian/branches/philikon-methodgrokker/src/martian/tests/test_all.py	2008-05-26 11:36:49 UTC (rev 86968)
@@ -72,5 +72,8 @@
         doctest.DocFileSuite('scan_for_classes.txt',
                              package='martian.tests',
                              optionflags=optionflags),
+        doctest.DocFileSuite('public_methods_from_class.txt',
+                             package='martian.tests',
+                             optionflags=optionflags),
         ])
     return suite

Modified: martian/branches/philikon-methodgrokker/src/martian/util.py
===================================================================
--- martian/branches/philikon-methodgrokker/src/martian/util.py	2008-05-26 11:30:46 UTC (rev 86967)
+++ martian/branches/philikon-methodgrokker/src/martian/util.py	2008-05-26 11:36:49 UTC (rev 86968)
@@ -107,6 +107,10 @@
     methods = [c for c in candidates if inspect.ismethod(c)]
     return methods
 
+def public_methods_from_class(class_):
+    return [m for m in methods_from_class(class_) if \
+            not m.__name__.startswith('_')]
+
 def frame_is_module(frame):
     return frame.f_locals is frame.f_globals
 



More information about the Checkins mailing list