[PEAK] Default value lost in binding.Obtain()

Alexey Smishlayev alexey at xtech2.lv
Sat Oct 31 03:09:23 EDT 2015


It does except for a little typo, at line 60 of the patch it should read 
"ob = acquireComponent(component, attr, default)", then it works good. 
Thank you!


Best regards,
Alexey

On 30/10/15 20:59, PJ Eby wrote:
> Does this patch work for you?
>
> On Wed, Oct 28, 2015 at 8:45 AM, Alexey Smishlayev <alexey at xtech2.lv> wrote:
>> Hi!
>> How can I get an svn checkout to incorporate described changes and propose
>> another patch? This is essential for our software and I'd like to see it
>> merged in upstream as soon as possible.
>>
>> Best regards,
>> Alexey
>>
>>
>> On 30/09/15 01:53, PJ Eby wrote:
>>> Thanks for reporting the problem.  Unfortunately your patch will mask
>>> any other sort of name error, including one that happens indirectly as
>>> a side effect of the lookup.  I think the correct fix is going to be
>>> to change the nameNotFound() method of config.IConfigurationRoot to
>>> include a default (defaulting to NOT_GIVEN), and have
>>> acquireComponent() take a default and pass it along to nameNotFound().
>>> This would handle the case of a direct lookup failing by returning the
>>> default, but still raise an error for any other part of the process
>>> getting a naming error.
>>>
>>> On Tue, Sep 29, 2015 at 9:03 AM, Alexey Smishlayev <alexey at xtech2.lv>
>>> wrote:
>>>> Hello!
>>>>
>>>> Today, fiddling with the binding.Obtain() I noticed that the default
>>>> value
>>>> gets lost.
>>>>
>>>> In my application, I have a component tree and I want an attribute to be
>>>> defined in any component in that tree, so I created binding:
>>>>
>>>>>       callback = binding.Obtain("callbackFunction", default=lambda arg:
>>>>> None)
>>>>>
>>>> So, in case that no component defines a callbackFunction, the lambda
>>>> function would be used as a fallback.
>>>> Unfortunately, "default" option is ignored unless target name contains
>>>> slashes (e.g. "/callbackFunction", "./callBackFunction",
>>>> "../callbackFunction")
>>>>
>>>> I went to the peak/binding/components.py trying to fix it and propose the
>>>> attached patch.
>>>> The problem is that default value was not propagated to the
>>>> acquireComponent() call, so an exception occurred.
>>>>
>>>>
>>>> Best regards,
>>>> Alexey Smishlayev
>>>>
>>>> _______________________________________________
>>>> PEAK mailing list
>>>> PEAK at eby-sarna.com
>>>> http://www.eby-sarna.com/mailman/listinfo/peak
>>
>> _______________________________________________
>> PEAK mailing list
>> PEAK at eby-sarna.com
>> http://www.eby-sarna.com/mailman/listinfo/peak

-------------- next part --------------
Index: src/peak/config/config_components.py
===================================================================
--- src/peak/config/config_components.py	(revision 2778)
+++ src/peak/config/config_components.py	(working copy)
@@ -764,8 +764,8 @@
     def noMoreValues(self,root,configKey,forObj):
         pass
 
-    def nameNotFound(self,root,name,forObj):
-        return naming.lookup(forObj, name, creationParent=forObj)
+    def nameNotFound(self,root,name,forObj,default=NOT_GIVEN):
+        return naming.lookup(forObj, name, creationParent=forObj, default=default)
 
 
 
Index: src/peak/config/interfaces.py
===================================================================
--- src/peak/config/interfaces.py	(revision 2778)
+++ src/peak/config/interfaces.py	(working copy)
@@ -134,7 +134,7 @@
     def noMoreValues(root,configKey,forObj):
         """A value search has completed"""
 
-    def nameNotFound(root,name,forObj,bindName):
+    def nameNotFound(root,name,forObj,bindName,default=NOT_GIVEN):
         """A (non-URL) component name was not found"""
 
 
Index: src/peak/binding/components.py
===================================================================
--- src/peak/binding/components.py	(revision 2778)
+++ src/peak/binding/components.py	(working copy)
@@ -285,7 +285,7 @@
 
 
 
-def acquireComponent(component, name):
+def acquireComponent(component, name, default=NOT_GIVEN):
 
     """Acquire 'name' relative to 'component', w/fallback to naming.lookup()
 
@@ -312,7 +312,7 @@
         return adapt(
             prev, IConfigurationRoot, NullConfigRoot
         ).nameNotFound(
-            prev, name, component
+            prev, name, component, default=default
         )
 
 
@@ -376,38 +376,38 @@
         attr = parts.next()                 # first part
         pc = _getFirstPathComponent(attr)
 
+        if pc:
+            ob = pc(component)
+        elif default is NOT_GIVEN:   
+            ob = acquireComponent(component, attr) # let the error happen
+        else:
+            ob = acquireComponent(component, attr, default)
 
-        if pc:  ob = pc(component)
-        else:   ob = acquireComponent(component, attr)
-
         resolved = []
         append = resolved.append
 
         try:
             for attr in parts:
+                if ob is NOT_FOUND: break
                 pc = _getNextPathComponent(attr)
                 if pc:  ob = pc(ob)
                 else:   ob = getattr(ob,attr)
                 append(attr)
+            else:
+                return ob
 
         except AttributeError:
+            pass
 
-            if default is not NOT_GIVEN:
-                return default
+        if default is not NOT_GIVEN:
+            return default
 
-            raise exceptions.NameNotFound(
-                resolvedName = ComponentName(resolved),
-                remainingName = ComponentName([attr] + [a for a in parts]),
-                resolvedObj = ob
-            )
+        raise exceptions.NameNotFound(
+            resolvedName = ComponentName(resolved),
+            remainingName = ComponentName([attr] + [a for a in parts]),
+            resolvedObj = ob
+        )
 
-        return ob
-
-
-
-
-
-
 _getFirstPathComponent = dict( (
     ('',   getRootComponent),
     ('.',  lambda x:x),


More information about the PEAK mailing list