[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