[Zope3-dev] Backward-incompatible bug fix to zope.proxy
Roger Ineichen
dev at projekt01.ch
Sun Apr 2 19:17:21 EDT 2006
Jim Fulton schrieb:
> A while ago, Gary and I found what appeared to be a bug in
> zope.proxy.ProxyBase's handling of non-data descriptors (descriptors
> that define __get__, but not __set__ and __delete__) defined in
> proxy classes. Normally, when a class has non-data descriptors,
> instance data overrides the descriptor. ProxyBase let non-data
> descriptors override instance data. For a proxy, instance data almost
> always comes from the proxied object. This behavior of ProxyBase
> caused subtle bugs.
>
> I've decided to fix this bug because it was causing my pain on my
> jim-adapter branch. I decided to fix this bug on the branch. The fix
> has a somewhat unexpected side effect. It turns out that some proxy
> applications depended on the old behavior.
>
> Consider location proxies:
>
> class LocationProxy(ProxyBase):
> ...
>
> def __reduce__(self, proto=None):
> raise TypeError("Not picklable")
>
> ...
>
> Here the proxy is trying to prevent pickling by providing a __reduce__
> that raises an exception. Now methods are non-data descriptors. With
> the fix, the __reduce__ of the proxied object is used. We need to
> convert __reduce__ to a data descriptor. I've added a function to
> the branch that can be used as a decorator to do this:
>
>
> class LocationProxy(ProxyBase):
> ...
>
> @zope.proxy.non_overridable
> def __reduce__(self, proto=None):
> raise TypeError("Not picklable")
>
> ...
>
>
> I also had to change the the descriptors defined in zope.app.decorator
> to be data descriptors.
>
> The fix is obviously not backward compatible. I don't know if this
> would effect anything outside of Zope. If this affects anyone, please
> let me know. If necessary, I can probably provide a ProxyBase2 with
> the fix and leave ProxyBase alone, but I'd rather not.
>
> Is anyone using zope.proxy to define custom proxy types?
>
> Jim
>
Hi Jim,
We just use a IContainer location proxy adapter.
But since this adapter isn't persistent I don't think this
is a problem.
def proxify(container, item):
if IContainer.providedBy(item):
proxy = ContainerLocationProxy(item)
else:
proxy = LocationProxy(item)
proxy.__name__ = item.__name__
proxy.__parent__ = container
return proxy
class ContainerLocationProxy(LocationProxy):
"""Proxy the location of a container an its items."""
# zope.app.conatiner.interfaces.IReadContainer
def __getitem__(self, key):
return proxify(self, getProxiedObject(self).__getitem__(key))
...
Regards
Roger Ineichen
_____________________________
Projekt01 GmbH
www.projekt01.ch
Boesch 65
6331 Hünenberg
phone +41 (0)41 781 01 78
mobile +41 (0)79 340 52 32
fax +41 (0)41 781 00 78
email roger.ineichen at projekt01.ch
_____________________________
END OF MESSAGE
More information about the Zope3-dev
mailing list