[Zope-CMF] Re: How to disable acquisition?

Christian Heimes heimes at faho.rwth-aachen.de
Wed Sep 1 09:18:43 EDT 2004


Jens Hauser wrote:
> ###CUT
>         <!-- JH: if a document called intro exists, we insert it here -->
>         <div class="stx"
>              tal:condition="exists:here/intro"
>              tal:define="doc nocall:here/intro| nothing"
>              tal:attributes="class
> python:test(doc.text_format=='structured-text', 'stx', 'plain')">
>             <div tal:replace="structure python:doc.CookedBody(stx_level=2)"
> />
>         </div>
> ###CUT
> 
> This works so far but my problem is, that it looks for a file "intro" within
> a folder AND it's parents. This is not what I want to have. I want the
> script only to look into the current folder represented by "here" and not
> into any parents of the actual folder.
> 
> Can anybody tell me how to achieve this?

In TTW Code you have to use explicit acquisition:

tal:condition="exists:here/aq_inner/aq_explicit/intro"

Or in python code:
getattr(context.aq_inner.aq_explicit, 'intro', None)

With aq_inner all except the inner wrapper are removed and aq_explicit 
is switching to explicit acquisition which means that no attributes are 
acquired implicitly (without special code).

In trusted code you can use this construct (copied from my Archetypes code):

_marker = []

def shasattr(obj, attr, acquire=False):
     """Safe has attribute method

     * It's acquisition safe by default because it's removing the 
acquisition
       wrapper before trying to test for the attribute.

     * It's not using hasattr which might swallow a ZODB ConflictError 
(actually
       the implementation of hasattr is swallowing all exceptions). 
Instead of
       using hasattr it's comparing the output of getattr with a special 
marker
       object.

     XXX the getattr() trick can be removed when Python's hasattr() is 
fixed to
     catch only AttributeErrors.

     Quoting Shane Hathaway:

     That said, I was surprised to discover that Python 2.3 implements 
hasattr
     this way (from bltinmodule.c):

             v = PyObject_GetAttr(v, name);
             if (v == NULL) {
                     PyErr_Clear();
                     Py_INCREF(Py_False);
                     return Py_False;
             }
     	Py_DECREF(v);
     	Py_INCREF(Py_True);
     	return Py_True;

     It should not swallow all errors, especially now that descriptors make
     computed attributes quite common.  getattr() only recently started 
catching
     only AttributeErrors, but apparently hasattr is lagging behind.  I 
suggest
     the consistency between getattr and hasattr should be fixed in 
Python, not
     Zope.

     Shane
     """
     if not acquire:
         obj = aq_base(obj)
     return getattr(obj, attr, _marker) is not _marker

Christian



More information about the Zope-CMF mailing list