[Checkins] SVN: martian/trunk/src/martian/ndir. Implement facility for calculated defaults.

Martijn Faassen faassen at infrae.com
Thu Jan 31 14:01:29 EST 2008


Log message for revision 83342:
  Implement facility for calculated defaults.
  

Changed:
  U   martian/trunk/src/martian/ndir.py
  U   martian/trunk/src/martian/ndir.txt

-=-
Modified: martian/trunk/src/martian/ndir.py
===================================================================
--- martian/trunk/src/martian/ndir.py	2008-01-31 18:52:25 UTC (rev 83341)
+++ martian/trunk/src/martian/ndir.py	2008-01-31 19:01:28 UTC (rev 83342)
@@ -5,8 +5,6 @@
 from martian import util
 from martian.error import GrokImportError
 
-NOT_FOUND = object()
-
 # ONCE or MULTIPLE
 ONCE = object()
 MULTIPLE = object()
@@ -17,6 +15,7 @@
 OPTIONAL_ARG = object()
 
 _SENTINEL = object()
+_USE_DEFAULT = object()
 
 class ClassScope(object):
     description = 'class'
@@ -46,7 +45,7 @@
         self.default = default
         self.validate = validate
         self.arg = arg
-        
+
     def __call__(self, value=_SENTINEL):            
         name = self.namespaced_name()
 
@@ -60,7 +59,7 @@
                 raise GrokImportError("%s requires a single argument." % name)
         elif self.arg is OPTIONAL_ARG:
             if value is _SENTINEL:
-                value = self.default
+                value = _USE_DEFAULT
 
         if self.validate is not None:
             self.validate(name, value)
@@ -80,17 +79,20 @@
             frame.f_locals[name] = values
         else:
             assert False, "Unknown value for times: %" % self.times
-            
+
     def get(self, component, module=None):
         name = self.namespaced_name()
-        value = getattr(component, name, NOT_FOUND)
-        if value is not NOT_FOUND:
-            return value
-        if module is not None:
-            return getattr(module, name, self.default)
+        value = getattr(component, name, _USE_DEFAULT)
+        if value is _USE_DEFAULT and module is not None:
+            value = getattr(module, name, _USE_DEFAULT)
+        if value is _USE_DEFAULT:
+            return self.get_default(component)
+        return value
+
+    def get_default(self, component):
+        if callable(self.default):
+            return self.default(component)
         return self.default
-    
-        return getattr(component, self.namespaced_name(), self.default)
 
     def namespaced_name(self):
         return self.namespace + '.' + self.name

Modified: martian/trunk/src/martian/ndir.txt
===================================================================
--- martian/trunk/src/martian/ndir.txt	2008-01-31 18:52:25 UTC (rev 83341)
+++ martian/trunk/src/martian/ndir.txt	2008-01-31 19:01:28 UTC (rev 83342)
@@ -165,6 +165,30 @@
   >>> multi.get(Foo)
   [u'Once', u'Twice']
 
+Calculated defaults
+-------------------
+
+Often instead of just supplying the system with a default, we want to
+calculate the default in some way. We define the ``name`` directive,
+which if not present, will calculate its value from the name of class,
+lower-cased. Instead of passing a default value, we pass a function as the
+default argument::
+
+  >>> def default(component):
+  ...     return component.__name__.lower()
+  >>> name = Directive('martian', 'name', 
+  ...   CLASS, ONCE, default)
+
+  >>> class Foo(object):
+  ...   name('bar')
+  >>> name.get(Foo)
+  'bar'
+
+  >>> class Foo(object):
+  ...   pass
+  >>> name.get(Foo)
+  'foo'
+
 A marker directive
 ------------------
 
@@ -198,6 +222,16 @@
     ...
   GrokImportError: martian.mark accepts no arguments.
 
+The marker directive also works with calculated defaults::
+
+  >>> def func(component):
+  ...    return component.__name__
+  >>> mark = Directive('martian', 'mark', CLASS, ONCE, func, arg=NO_ARG)
+  >>> class Foo(object):
+  ...    pass
+  >>> mark.get(Foo)
+  'Foo'
+
 Optional arguments
 ------------------
 
@@ -228,6 +262,19 @@
   >>> optional.get(Foo)
   'default'
 
+The optional value directive also works with calculated defaults::
+
+  >>> optional = Directive('martian', 'optional', CLASS, ONCE, func,
+  ...                       arg=OPTIONAL_ARG)
+  >>> class Foo(object):
+  ...   optional()
+  >>> optional.get(Foo)
+  'Foo'
+  >>> class Foo(object):
+  ...   pass
+  >>> optional.get(Foo)
+  'Foo'
+
 Validation
 ----------
 
@@ -367,3 +414,4 @@
   Traceback (most recent call last):
     ...
   GrokImportError: martian.iface can only be called with an interface.
+



More information about the Checkins mailing list