[Zope3-checkins] CVS: Zope3/src/zope/app/component - decoratorservice.py:1.1.2.4 directiveswithperms.py:1.1.2.2 hooks.py:1.5.8.8
Steve Alexander
steve@cat-box.net
Thu, 15 May 2003 10:49:57 -0400
Update of /cvs-repository/Zope3/src/zope/app/component
In directory cvs.zope.org:/tmp/cvs-serv12712/src/zope/app/component
Modified Files:
Tag: stevea-decorators-branch
decoratorservice.py directiveswithperms.py hooks.py
Log Message:
More work on Decorators.
Converted existing tests to use decorators instead of ZopeContainerAdapter.
=== Zope3/src/zope/app/component/decoratorservice.py 1.1.2.3 => 1.1.2.4 ===
--- Zope3/src/zope/app/component/decoratorservice.py:1.1.2.3 Wed May 14 13:44:09 2003
+++ Zope3/src/zope/app/component/decoratorservice.py Thu May 15 10:49:26 2003
@@ -15,37 +15,61 @@
$Id$
"""
-
+_marker = object()
class DecoratorRegistry:
def __init__(self):
# XXX This class needs an interface. Also, rather than using a dict,
# this should be using a type registry.
+
+ # These two are used only for registering things.
self._id_to_spec = {}
self._class_to_id = {}
+
+ # This registry is used in practice.
self._class_to_spec = {}
def queryContextDecoratorSpec(self, class_):
return self._class_to_spec.get(class_)
+# queryreg = self._class_to_spec.get
+# for base in getattr(class_, '__mro__', ()):
+# spec = queryreg(base, _marker)
+# if spec is not _marker:
+# return spec
+# return None
def registerDecoratorForClass(self, class_, decorator_id, type):
if type != 'context':
raise ValueError(
'Only decorators of type "context" are implemented.')
+# if getattr(class_, '__mro__', None) is None:
+# raise TypeError('Decorators cannot be registered for classic'
+# ' classes. %r has no __mro__.' % (class_,))
if class_ in self._class_to_id:
raise ValueError('More than one decorator registered for decorator'
' type "%s", class "%s"' % (type, class_))
- spec = self._id_to_spec.get(decorator_id)
- if spec is None:
- raise ValueError('Decorator id %s not defined' % decorator_id)
+ if decorator_id is not None:
+ spec = self._id_to_spec.get(decorator_id)
+ if spec is None:
+ raise ValueError('Decorator id %s not defined' % decorator_id)
+ else:
+ # No decoration for this class.
+ spec = None
# NB: only context decorators supported for now!
self._class_to_id[class_] = decorator_id
self._class_to_spec[class_] = spec
def queryDecoratorForClass(self, class_, type):
+ # Use getattr because hasattr swallows exceptions.
if type != 'context':
return None
return self._class_to_id.get(class_)
+# queryreg = self._class_to_id.get
+# for base in getattr(class_, '__mro__', ()):
+# spec = queryreg(base, _marker)
+# if spec is not _marker:
+# return spec
+# return None
def registerDecorator(self, decorator_id, spec):
if decorator_id in self._id_to_spec:
@@ -62,7 +86,6 @@
queryDecoratorForClass = decoratorRegistry.queryDecoratorForClass
registerDecoratorForClass = decoratorRegistry.registerDecoratorForClass
-queryDecoratorForClass = decoratorRegistry.queryDecoratorForClass
registerDecorator = decoratorRegistry.registerDecorator
queryContextDecoratorSpec = decoratorRegistry.queryContextDecoratorSpec
=== Zope3/src/zope/app/component/directiveswithperms.py 1.1.2.1 => 1.1.2.2 ===
--- Zope3/src/zope/app/component/directiveswithperms.py:1.1.2.1 Wed May 14 13:44:09 2003
+++ Zope3/src/zope/app/component/directiveswithperms.py Thu May 15 10:49:26 2003
@@ -254,11 +254,6 @@
getService(None, Factories).provideFactory(id, factory)
-class MixinBase:
- def __init__(self, inner, outer):
- self.inner = inner
- self.outer = outer
-
class DecoratorDirective(DirectiveWithPermissions):
classProvides(INonEmptyDirective)
implements(ISubdirectiveHandler)
@@ -286,18 +281,19 @@
def __call__(self):
class_ = self._class
+ names = self._names or []
- bases = (class_, MixinBase)
- cname = "GeneratedDecoratorMixinClass"
- cdict = {}
- newclass = type(cname, bases, cdict)
-
- names = self._names
- if names is None:
- names = ([name for name in self._get_permission_map] +
- [name for name in self._set_permission_map])
+ # Make a set of names from those appearing in the permission maps,
+ # and those in names.
+ # We don't really *need* to do this, but it makes the names attribute
+ # of the DecoratorSpec ugly.
+
+ nameset = dict(zip(names, names)) # don't care about values
+ nameset.update(self._get_permission_map)
+ nameset.update(self._set_permission_map)
+ names = nameset.keys()
- spec = DecoratorSpec(newclass, implementedBy(class_), names,
+ spec = DecoratorSpec(class_, implementedBy(class_), names,
self._get_permission_map,
self._set_permission_map,
self._trusted_mixin)
@@ -323,6 +319,9 @@
('decorator_protectSetAttribute', self._id, name),
_decorateAddPermission,
(self._set_permission_map, name, permission_id, self._id, 'set')))
+
+ def _mimic(self, _context, class_):
+ raise ConfigurationError('like_class not implemented for decorators.')
def _decorateAddPermission(map, name, permission_id, decorator_id, operation):
if name in map:
=== Zope3/src/zope/app/component/hooks.py 1.5.8.7 => 1.5.8.8 ===
--- Zope3/src/zope/app/component/hooks.py:1.5.8.7 Wed May 14 13:44:09 2003
+++ Zope3/src/zope/app/component/hooks.py Thu May 15 10:49:26 2003
@@ -78,7 +78,7 @@
if cls is not None:
decorator_spec = queryContextDecoratorSpec(cls)
if decorator_spec is not None:
- return decorate(spec, _ob, _parent, kw)
+ return decorate(decorator_spec, _ob, _parent, kw)
if t is Proxy:
# insert into proxies
checker = getChecker(_ob)
@@ -110,7 +110,6 @@
if spec.mixinInterfaceSpec is not None:
attrdict['__providedBy__'] = (
spec.mixinInterfaceSpec + providedBy(unproxied_ob))
-
d = Decorator(unproxied_ob, parent, spec.mixinFactory, spec.names,
attrdict, inner, **kw)
if checker is not None: