[Checkins] SVN: martian/trunk/ Merge the philikon-moduleinfo-kwarg branch.

Philipp von Weitershausen philikon at philikon.de
Tue Oct 30 15:09:50 EDT 2007


Log message for revision 81222:
  Merge the philikon-moduleinfo-kwarg branch.
  

Changed:
  U   martian/trunk/CHANGES.txt
  U   martian/trunk/src/martian/README.txt
  U   martian/trunk/src/martian/core.py
  U   martian/trunk/src/martian/tests/test_all.py

-=-
Modified: martian/trunk/CHANGES.txt
===================================================================
--- martian/trunk/CHANGES.txt	2007-10-30 19:04:08 UTC (rev 81221)
+++ martian/trunk/CHANGES.txt	2007-10-30 19:09:50 UTC (rev 81222)
@@ -1,6 +1,17 @@
 CHANGES
 *******
 
+0.9.1 (unreleased)
+==================
+
+Feature changes
+---------------
+
+* Grokkers now receive a ``module_info`` keyword argument.  This
+  change is completely backwards-compatible since grokkers which don't
+  take ``module_info`` explicitly will absorb the extra argument in
+  ``**kw``.
+
 0.9 (2007-10-02)
 =================
 

Modified: martian/trunk/src/martian/README.txt
===================================================================
--- martian/trunk/src/martian/README.txt	2007-10-30 19:04:08 UTC (rev 81221)
+++ martian/trunk/src/martian/README.txt	2007-10-30 19:09:50 UTC (rev 81222)
@@ -291,7 +291,7 @@
 
   >>> class ColorGrokker(InstanceGrokker):
   ...   component_class = color.Color
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     color.all_colors[name] = obj
   ...     return True
 
@@ -359,7 +359,7 @@
 
   >>> class SoundGrokker(InstanceGrokker):
   ...   component_class = sound.Sound
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     sound.all_sounds[name] = obj
   ...     return True
   >>> sound_grokker = SoundGrokker()
@@ -677,7 +677,7 @@
   >>> read_amount = {}
   >>> from martian import GlobalGrokker
   >>> class AmountGrokker(GlobalGrokker):
-  ...   def grok(self, name, module):
+  ...   def grok(self, name, module, **kw):
   ...     read_amount[None] = module.amount
   ...     return True
 
@@ -711,7 +711,7 @@
 
   >>> class MachineGrokker(ClassGrokker):
   ...   component_class = oldstyle.Machine
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     oldstyle.all_machines[name] = obj
   ...     return True
 
@@ -719,7 +719,7 @@
 
   >>> class MachineInstanceGrokker(InstanceGrokker):
   ...   component_class = oldstyle.Machine
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     oldstyle.all_machine_instances[name] = obj
   ...     return True
 
@@ -787,7 +787,7 @@
   >>> all_numbers = {}
   >>> class NumberGrokker(InstanceGrokker):
   ...  component_class = Number
-  ...  def grok(self, name, obj, multiplier):
+  ...  def grok(self, name, obj, multiplier, **kw):
   ...    all_numbers[obj.nr] = obj.nr * multiplier
   ...    return True
   >>> def prepare(name, module, kw):
@@ -834,7 +834,7 @@
 
   >>> class BrokenGrokker(InstanceGrokker):
   ...  component_class = Number
-  ...  def grok(self, name, obj):
+  ...  def grok(self, name, obj, **kw):
   ...    pass
 
   >>> module_grokker = ModuleGrokker()
@@ -848,7 +848,7 @@
 Let's also try this with a GlobalGrokker::
 
   >>> class MyGrokker(GlobalGrokker):
-  ...   def grok(self, name, module):
+  ...   def grok(self, name, module, **kw):
   ...     return "Foo"
   >>> module_grokker = ModuleGrokker()
   >>> module_grokker.register(MyGrokker())
@@ -949,7 +949,7 @@
   >>> class somemodule(FakeModule):
   ...   class TestGrokker(ClassGrokker):
   ...     component_class = TestOnce
-  ...     def grok(self, name, obj):
+  ...     def grok(self, name, obj, **kw):
   ...        executed.append(name)
   ...        return True
   >>> somemodule = fake_import(somemodule)
@@ -985,7 +985,7 @@
   >>> class somemodule(FakeModule):
   ...   class TestGrokker(InstanceGrokker):
   ...     component_class = TestInstanceOnce
-  ...     def grok(self, name, obj):
+  ...     def grok(self, name, obj, **kw):
   ...        executed.append(name)
   ...        return True
   >>> somemodule = fake_import(somemodule)
@@ -1007,7 +1007,7 @@
   >>> executed = []
   >>> class somemodule(FakeModule):
   ...   class TestGrokker(GlobalGrokker):
-  ...     def grok(self, name, obj):
+  ...     def grok(self, name, obj, **kw):
   ...       executed.append(name)
   ...       return True
   >>> somemodule = fake_import(somemodule)
@@ -1051,7 +1051,7 @@
 
   >>> order = []
   >>> class OrderGrokker(ClassGrokker):
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     order.append(name)
   ...     return True
 
@@ -1098,7 +1098,7 @@
 
   >>> class MyGlobalGrokker(GlobalGrokker):
   ...   priority = 5
-  ...   def grok(self, name, obj):
+  ...   def grok(self, name, obj, **kw):
   ...     order.append(name)
   ...     return True
   >>> multi_grokker.grok('MyGlobalGrokker', MyGlobalGrokker)
@@ -1114,3 +1114,48 @@
 
   >>> order
   ['BSub', 'mymodule', 'ASub']
+
+
+Module info
+-----------
+
+In addition to the ``name`` and ``object`` positional arguments,
+grokkers will get also get a ``module_info`` keyword argument.  It is
+an ``IModuleInfo`` object which can be used, for example, to query
+module annotations.  Consider the following grokker:
+
+  >>> from martian.error import GrokError
+  >>> class AnnotationsGrokker(GlobalGrokker):
+  ...   def grok(self, name, module, module_info, **kw):
+  ...       ann = module_info.getAnnotation('some.annotation', None)
+  ...       if ann is None:
+  ...           raise GrokError('Did not find annotation!', module)
+  ...       if ann != 'ME GROK SAY HI':
+  ...           raise GrokError('Wrong annotation!', module)
+  ...       return True
+
+Now let's provide a fake module:
+
+  >>> import new, sys
+  >>> annotations = new.module('annotations')
+  >>> annotations.__file__ = '/fake/module/annotations.py'
+  >>> sys.modules['annotations'] = annotations
+
+Clearly, it can't find the module-level variable yet:
+
+  >>> module_grokker = ModuleGrokker()
+  >>> module_grokker.register(AnnotationsGrokker())
+  >>> import martian
+  >>> martian.grok_dotted_name('annotations', module_grokker)
+  Traceback (most recent call last):
+  ...
+  GrokError: Did not find annotation!
+
+Let's provide the annotation so that the grokker works as expected:
+
+  >>> annotations.__some_annotation__ = 'ME GROK SAY HI'
+  >>> martian.grok_dotted_name('annotations', module_grokker)
+
+Finally clean up:
+
+  >>> del sys.modules['annotations']

Modified: martian/trunk/src/martian/core.py
===================================================================
--- martian/trunk/src/martian/core.py	2007-10-30 19:04:08 UTC (rev 81221)
+++ martian/trunk/src/martian/core.py	2007-10-30 19:09:50 UTC (rev 81222)
@@ -198,7 +198,8 @@
         grok_package(sub_module_info, grokker, **kw)
 
 def grok_module(module_info, grokker, **kw):
-    grokker.grok(module_info.dotted_name, module_info.getModule(), **kw)
+    grokker.grok(module_info.dotted_name, module_info.getModule(),
+                 module_info=module_info, **kw)
 
 # deep meta mode here - we define grokkers that can pick up the
 # three kinds of grokker: ClassGrokker, InstanceGrokker and ModuleGrokker

Modified: martian/trunk/src/martian/tests/test_all.py
===================================================================
--- martian/trunk/src/martian/tests/test_all.py	2007-10-30 19:04:08 UTC (rev 81221)
+++ martian/trunk/src/martian/tests/test_all.py	2007-10-30 19:09:50 UTC (rev 81222)
@@ -61,12 +61,15 @@
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTests([
-        doctest.DocFileSuite('../README.txt',
+        doctest.DocFileSuite('README.txt',
+                             package='martian',
                              globs=globs,
                              optionflags=optionflags),
-        doctest.DocFileSuite('../scan.txt',
+        doctest.DocFileSuite('scan.txt',
+                             package='martian',
                              optionflags=optionflags),
-        doctest.DocFileSuite('../directive.txt',
+        doctest.DocFileSuite('directive.txt',
+                             package='martian',
                              optionflags=optionflags),
         ])
     return suite



More information about the Checkins mailing list