[Zope-dev] __getattr__ and Acquisition
Andreas Kostyrka
andreas@kostyrka.priv.at
23 Sep 2002 17:00:36 +0200
Am Mon, 2002-09-23 um 10.35 schrieb Lennart Regebro:
> From: "Andreas Kostyrka" <andreas@kostyrka.priv.at>
> > Nope it is not. In a normal method you can access something acquired
> > like this:
> > self.acquired_value.
>
> I often do just that. :-) I'm not 100% sure what you need to include for
> that to work, but I would expect that it is Aqcuisition.Implicit.
Well, Acquisition does not work in __getattr__. This seems trivially
because the "self" is unwrapped in the case of __getattr__, while it's
wrapped when called on a normal method.
>
> > The problem is, that __getattr__ does not have access to the acquisition
> > chain.
>
> Well, it does, but it typically causes infinite recursion if you aren't
Well, it would perhaps make sense for Acquisition to use the
equivalent of getattr(self.aq_explicit,name) instead of
getattr(aq_base(self),name)
This way you have no infinite recursion, but still can acquire things
explicitly with aq_acquire :)
> careful. Something like this might work (this is untested code, adapted from
> something that is a bit more complex that we are doing):
>
> def __getattr__(self, name, marker=None):
> if not name.startswith('_') and not name.startswith('aq_'):
> if not name in self._v_ignore_attrib:
> subob = getattr(self,name,_marker)
Well, where do you intenden your getattr to get the attribute from?
> self._v_ignore_attrib=[]
> # Return it in context of self, forgetting
> # its location and acting as if it were located
> # in self.
> return aq_base(subob)
> else:
> self._v_ignore_attrib.append(name)
>
> raise AttributeError, name
>
>
> > Basically I want "Transparent Folders" which get their "transparent
> > values from the Acquisition path.
>
> Aha. Well, I wouldn't call it trivial, but it is definitely doable.
Difficult. Because __getattr__ does not have access to the acquisition
chain. (Just looking at Acquisition.c makes my head go all jelly ;) )
1.) Change Acquisition to call getattr not on self but on an explicit
wrapper of self. see above.
Problem: Compability with Zope? Should probably work. But perhaps there
are things that rely on self being the object and not an explicit
Wrapper.
Problem: The idea of patching Acquisition.c makes my head spin.
Problem: Not possible to fix it up as an Product -> needs a patch to
Zope.
2.) Fetch my a wrapped copy of self from the Python call stack.
Problem: It's an example of code that would be labelled "Do not copy
this style!"
Problem: Can break at the most curious moments.
3.) Store the wrapped self in some attribute during traversal.
Problem: This is plain wrong. It's not safe in a number of ways, ...
(threads, multiple acquisition paths, etc.)
I've implemented solution 2) because
- it's packable as a product
- I'm not sure a core change to Acquisition.c is something that has ANY
chance of getting into Zope.
- I'm not 100% sure that changing Acquisition.c will not break Zope in
some subtle ways.
- I'm already past the delivery deadline for my small application of
this. Hacking the Python stack seems something that I can predict much
better than any try to hack Acquisition.c :(
Andreas