[Zope3-checkins] CVS: Zope3/src/zope/app/container - zopecontainer.py:1.26
Albertas Agejevas
alga@codeworks.lt
Thu, 17 Jul 2003 10:45:22 -0400
Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv1693/zope/app/container
Modified Files:
zopecontainer.py
Log Message:
A temporary workaround for making context aware descriptors work with
ZopeContainerDecorator. A more generic fix for this problem should be
made in wrapper.c.
=== Zope3/src/zope/app/container/zopecontainer.py 1.25 => 1.26 ===
--- Zope3/src/zope/app/container/zopecontainer.py:1.25 Mon Jul 7 13:14:47 2003
+++ Zope3/src/zope/app/container/zopecontainer.py Thu Jul 17 10:45:17 2003
@@ -25,6 +25,7 @@
from zope.app.interfaces.container import IContainerNamesContainer
from zope.component import queryAdapter, getAdapter
from zope.app.context import ContextWrapper, Wrapper
+from zope.context import ContextDescriptor
from zope.app.event import publish
from zope.app.interfaces.container import IAddNotifiable
from zope.app.interfaces.container import IDeleteNotifiable
@@ -35,8 +36,62 @@
from zope.app.event.objectevent import ObjectRemovedEvent
from zope.app.event.objectevent import ObjectModifiedEvent, ObjectAddedEvent
from zope.interface import implements
-
+from zope.context.wrapper import getdescriptor
_marker = object()
+
+__metaclass__ = type
+
+class ContainerDecoratorSuper:
+ """Like a super() but for wrappers.
+
+ The descriptors get their self rebound to a wrapper if they are
+ context descriptors.
+
+ XXX: this is just a plug to get context awareness work on Zope
+ container instances. This has to be implemented in wrapper.c
+ """
+
+ __slots__ = 'wrapper',
+
+ def __init__(self, wrapper):
+ self.wrapper = wrapper
+
+ def _getDescriptor(self, attr):
+ '''Returns a bound method with self rebound if the descriptor
+ is a ContextDescriptor, and a normal method otherwise.
+ '''
+ wrapper = self.wrapper
+ obj = getProxiedObject(wrapper)
+ cls = getattr(obj, '__class__', type(obj))
+ descriptor = getdescriptor(obj, attr)
+ if isinstance(descriptor, ContextDescriptor):
+ return descriptor.__get__(wrapper, cls)
+ else:
+ return getattr(obj, attr)
+
+ def __getitem__(self, key):
+ return self._getDescriptor('__getitem__')(key)
+
+ def __contains__(self, key):
+ return self._getDescriptor('__contains__')(key)
+
+ def get(self, key, default):
+ return self._getDescriptor('get')(key, default)
+
+ def items(self):
+ return self._getDescriptor('items')()
+
+ def values(self):
+ return self._getDescriptor('values')()
+
+ def __delitem__(self, key):
+ return self._getDescriptor('__delitem__')(key)
+
+ def setObject(self, key, value):
+ return self._getDescriptor('setObject')(key, value)
+
+
+
class ZopeItemContainerDecorator(Wrapper):
"""Decorates an IItemContainer object for context-awareness.
@@ -46,7 +101,8 @@
def __getitem__(self, key):
"See IZopeItemContainer"
- return ContextWrapper(getProxiedObject(self)[key], self, name=key)
+ return ContextWrapper(ContainerDecoratorSuper(self)[key],
+ self, name=key)
def get(self, key, default=None):
"See IZopeSimpleReadContainer"
@@ -59,7 +115,7 @@
def __contains__(self, key):
"See IReadMapping"
# '__contains__' in terms of __getitem__ on the proxied object
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
try:
container[key]
return True
@@ -72,7 +128,7 @@
def get(self, key, default=None):
"See IZopeSimpleReadContainer"
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
value = container.get(key, _marker)
if value is not _marker:
return ContextWrapper(value, self, name=key)
@@ -85,7 +141,7 @@
def values(self):
"See IZopeReadContainer"
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
result = []
for key, value in container.items():
result.append(ContextWrapper(value, self, name=key))
@@ -93,7 +149,7 @@
def items(self):
"See IZopeReadContainer"
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
result = []
for key, value in container.items():
result.append((key, ContextWrapper(value, self, name=key)))
@@ -112,11 +168,12 @@
def setObject(self, key, object):
"See IZopeWriteContainer"
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
+ unwrapped = removeAllProxies(self)
if not key:
- if not (IOptionalNamesContainer.isImplementedBy(container)
- or IContainerNamesContainer.isImplementedBy(container)):
+ if not (IOptionalNamesContainer.isImplementedBy(unwrapped)
+ or IContainerNamesContainer.isImplementedBy(unwrapped)):
raise ValueError("Empty names are not allowed")
key = ''
else:
@@ -149,7 +206,7 @@
def __delitem__(self, key):
"See IZopeWriteContainer"
- container = getProxiedObject(self)
+ container = ContainerDecoratorSuper(self)
# Dependency Note: This is a dependency on IItemContainer
object = ContextWrapper(container[key], self, name=key)