[Zope3-checkins] CVS: Zope3/src/zope/interface -
declarations.py:1.17.10.6 interface.py:1.13.4.5 surrogate.py:1.1.2.4
Jim Fulton
jim at zope.com
Thu Oct 16 17:43:09 EDT 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv26682/src/zope/interface
Modified Files:
Tag: adaptergeddon-branch
declarations.py interface.py surrogate.py
Log Message:
Updated the global adapter service to use the new adapter machinery.
=== Zope3/src/zope/interface/declarations.py 1.17.10.5 => 1.17.10.6 ===
--- Zope3/src/zope/interface/declarations.py:1.17.10.5 Mon Oct 13 11:08:59 2003
+++ Zope3/src/zope/interface/declarations.py Thu Oct 16 17:42:38 2003
@@ -1093,9 +1093,7 @@
##############################################################################
-
-def _normalizeargs(sequence, output = None,
- noexpand=(InterfaceClass, Implements)):
+def _normalizeargs(sequence, output = None):
"""Normalize declaration arguments
Normalization arguments might contain Declarions, tuples, or single
@@ -1105,11 +1103,14 @@
"""
if output is None:
output = []
- for v in sequence:
- if isinstance(v, noexpand):
- output.append(v)
- else:
+
+ cls = sequence.__class__
+ if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
+ output.append(sequence)
+ else:
+ for v in sequence:
_normalizeargs(v, output)
+
return output
_empty = Declaration()
=== Zope3/src/zope/interface/interface.py 1.13.4.4 => 1.13.4.5 ===
--- Zope3/src/zope/interface/interface.py:1.13.4.4 Sun Oct 12 16:40:12 2003
+++ Zope3/src/zope/interface/interface.py Thu Oct 16 17:42:38 2003
@@ -17,6 +17,7 @@
$Id$
"""
+from __future__ import generators
import sys
import weakref
from types import FunctionType
@@ -116,15 +117,21 @@
self.dependents = weakref.WeakKeyDictionary()
self.__bases__ = tuple(bases)
+ def subscribe(self, dependent):
+ self.dependents[dependent] = 1
+
+ def unsubscribe(self, dependent):
+ del self.dependents[dependent]
+
def __setBases(self, bases):
# Register ourselves as a dependent of our old bases
for b in self.__bases__:
- del b.dependents[self]
+ b.unsubscribe(self)
# Register ourselves as a dependent of our bases
self.__dict__['__bases__'] = bases
for b in bases:
- b.dependents[self] = 1
+ b.subscribe(self)
self.changed()
=== Zope3/src/zope/interface/surrogate.py 1.1.2.3 => 1.1.2.4 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.3 Sun Oct 12 16:40:12 2003
+++ Zope3/src/zope/interface/surrogate.py Thu Oct 16 17:42:38 2003
@@ -54,10 +54,14 @@
# it's base (less local) surogate. In this case too, the dictionary
# can be saved.
-
+from __future__ import generators
import weakref
from zope.interface.ro import ro
from zope.interface.declarations import providedBy
+from zope.interface.interface import InterfaceClass
+from zope.proxy import removeAllProxies
+
+Default = InterfaceClass("Default", (), {})
class Surrogate(object):
@@ -65,15 +69,21 @@
self._adapters = {}
self._implied = {}
self._interface = weakref.ref(interface)
- interface.dependents[self] = 1
+ interface.subscribe(self)
self._registry = registry
self.dependents = weakref.WeakKeyDictionary()
self.__bases__ = [registry.get(base) for base in interface.__bases__]
for base in self.__bases__:
- base.dependents[self] = 1
+ base.subscribe(self)
self._computeImplied()
+ def subscribe(self, dependent):
+ self.dependents[dependent] = 1
+
+ def unsubscribe(self, dependent):
+ del self.dependents[dependent]
+
def extends(self, other, strict=True):
if other is self and strict:
return False
@@ -86,8 +96,8 @@
def isImplementedBy(self, ob):
return self._interface().isImplementedBy(ob)
- def _adaptTo(self, specification, factory, name=None, with=()):
- self._adapters[with, name, specification] = factory
+ def _adaptTo(self, specification, factories, name='', with=()):
+ self._adapters[with, name, specification] = factories
self.changed()
def changed(self):
@@ -115,19 +125,19 @@
# Add adapters and interfaces directly implied by same:
items = ancestor._adapters.iteritems()
- for (with, name, target), factory in items:
+ for (with, name, target), factories in items:
if with:
self.__add_multi_adapter(with, name, target, target,
implied, registered,
- (factory, ))
- elif name is not None:
+ factories)
+ elif name:
self.__add_named_adapter(target, target, name,
implied, registered,
- (factory, ))
+ factories)
else:
self.__add_adapter(target, target,
implied, registered,
- (factory, ))
+ factories)
def __add_adapter(self, target, provided, implied, registered, factories):
@@ -168,28 +178,33 @@
self.__add_multi_adapter(interfaces, name, b, provided,
implied, registered, factories)
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, self._interface())
+
class SurrogateRegistry(object):
def __init__(self):
self._surrogates = weakref.WeakKeyDictionary()
-
+ self._default = Surrogate(Default, self)
def get(self, declaration):
+ if declaration is None:
+ return self._default
surrogate = self._surrogates.get(declaration)
if surrogate is None:
surrogate = Surrogate(declaration, self)
self._surrogates[declaration] = surrogate
return surrogate
- def provideAdapter(self, required, provided, factory,
- name=None, with=()):
+ def provideAdapter(self, required, provided, factories,
+ name='', with=()):
required = self.get(required)
provided = self.get(provided)
if with:
with = tuple(map(self.get, with))
else:
with = ()
- required._adaptTo(provided, factory, name, with)
+ required._adaptTo(provided, factories, name or '', with)
def queryAdapter(self, ob, interface, default=None):
"""Query a simple adapter
@@ -228,7 +243,7 @@
>>> def f1(ob):
... return 1
- >>> registry.provideAdapter(F0, B1, f1)
+ >>> registry.provideAdapter(F0, B1, [f1])
>>> registry.queryAdapter(c, B0)
1
@@ -237,14 +252,14 @@
>>> def f2(ob):
... return 2
- >>> registry.provideAdapter(F1, B1, f2)
+ >>> registry.provideAdapter(F1, B1, [f2])
>>> registry.queryAdapter(c, B0)
2
>>> def f3(ob):
... return 3
- >>> registry.provideAdapter(F1, B0, f3)
+ >>> registry.provideAdapter(F1, B0, [f3])
>>> registry.queryAdapter(c, B0)
3
@@ -265,10 +280,12 @@
interface = surrogate
- declaration = providedBy(ob)
+ declaration = removeAllProxies(providedBy(ob))
s = self.get(declaration)
factories = s._implied.get(interface)
+ if factories is None:
+ factories = self._default._implied.get(interface)
if factories is not None:
for factory in factories:
ob = factory(ob)
@@ -305,7 +322,7 @@
>>> def f1(ob):
... return 1
- >>> registry.provideAdapter(F0, B1, f1, name='bob')
+ >>> registry.provideAdapter(F0, B1, [f1], name='bob')
>>> registry.queryNamedAdapter(c, B0, 'bob')
1
>>> registry.queryNamedAdapter(c, B0, 'bruce')
@@ -314,14 +331,14 @@
>>> def f2(ob):
... return 2
- >>> registry.provideAdapter(F1, B1, f2, name='bob')
+ >>> registry.provideAdapter(F1, B1, [f2], name='bob')
>>> registry.queryNamedAdapter(c, B0, 'bob')
2
>>> def f3(ob):
... return 3
- >>> registry.provideAdapter(F1, B0, f3, name='bob')
+ >>> registry.provideAdapter(F1, B0, [f3], name='bob')
>>> registry.queryNamedAdapter(c, B0, 'bob')
3
@@ -338,6 +355,8 @@
declaration = providedBy(ob)
s = self.get(declaration)
factories = s._implied.get((interface, name))
+ if factories is None:
+ factories = s._implied.get((Default, name))
if factories is not None:
for factory in factories:
ob = factory(ob)
@@ -383,7 +402,7 @@
>>> def f1(ob):
... return 1
- >>> registry.provideAdapter(IF0, IB1, f1, name='bob', with=[IR0])
+ >>> registry.provideAdapter(IF0, IB1, [f1], name='bob', with=[IR0])
>>> registry.queryMultiAdapter((c, r), IB0, 'bob')
1
>>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
@@ -392,7 +411,7 @@
>>> def f2(ob):
... return 2
- >>> registry.provideAdapter(IF1, IB1, f2, name='bob', with=[IR1])
+ >>> registry.provideAdapter(IF1, IB1, [f2], name='bob', with=[IR1])
>>> registry.queryMultiAdapter((c, r), IB0, 'bob')
2
@@ -416,6 +435,8 @@
s = self.get(declaration)
adapters = s._implied.get((interface, name, order))
+ if adapters is None:
+ adapters = s._implied.get((Default, name, order))
if adapters:
matched = None
matched_factories = None
@@ -444,5 +465,166 @@
return ob
return None
-
-
+
+ def getRegisteredMatching(self,
+ required_interfaces=None,
+ provided_interfaces=None,
+ name = None,
+ ):
+
+ """Search for registered adapters
+
+ Note, this is usually slow!
+
+ >>> from zope.interface import Interface
+
+ >>> class R1(Interface):
+ ... pass
+ >>> class R12(Interface):
+ ... pass
+ >>> class R2(R1):
+ ... pass
+ >>> class R3(R2):
+ ... pass
+ >>> class R4(R3):
+ ... pass
+
+ >>> class P1(Interface):
+ ... pass
+ >>> class P2(P1):
+ ... pass
+ >>> class P3(P2):
+ ... pass
+ >>> class P4(P3):
+ ... pass
+
+
+ >>> registry = SurrogateRegistry()
+ >>> registry.provideAdapter(None, P3, 'default P3')
+ >>> registry.provideAdapter(Interface, P3, 'any P3')
+ >>> registry.provideAdapter(R2, P3, 'R2 P3')
+ >>> registry.provideAdapter(R2, P3, "bobs R2 P3", name='bob')
+
+ >>> from pprint import PrettyPrinter
+ >>> pprint = PrettyPrinter(width=60).pprint
+ >>> def sorted(x):
+ ... x = [(getattr(r, '__name__', None), p.__name__, w, n, f)
+ ... for (r, p, w, n, f) in x]
+ ... x.sort()
+ ... pprint(x)
+
+ >>> sorted(registry.getRegisteredMatching())
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(name=''))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3')]
+
+ >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=P1))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=P3))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R4, R12),
+ ... provided_interfaces = (P1, )))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R4, R12),
+ ... provided_interfaces = (P3, )))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R2, ),
+ ... provided_interfaces = (P3, )))
+ [(None, 'P3', (), '', 'default P3'),
+ ('Interface', 'P3', (), '', 'any P3'),
+ ('R2', 'P3', (), '', 'R2 P3'),
+ ('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R2, ),
+ ... provided_interfaces = (P3, ),
+ ... name='bob'))
+ [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R3, ),
+ ... provided_interfaces = (P1, ),
+ ... name='bob'))
+ [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+
+ """
+
+
+ if isinstance(required_interfaces, InterfaceClass):
+ required_interfaces = (required_interfaces, )
+ elif required_interfaces is None:
+ required_interfaces = self._surrogates.keys()
+
+ required_interfaces = tuple(required_interfaces)+(None,)
+
+ if isinstance(provided_interfaces, InterfaceClass):
+ provided_interfaces = (provided_interfaces, )
+
+
+ seen = {}
+
+ for required in required_interfaces:
+ s = self.get(required)
+ for ancestor in ro(s):
+ if ancestor in seen:
+ continue
+ seen[ancestor] = 1
+ items = ancestor._adapters.iteritems()
+ ancestor = ancestor._interface()
+ if ancestor is Default:
+ ancestor = None
+ for (with, aname, target), factories in items:
+ if with:
+ continue # don't do multi-adapters yet
+ if name is not None and aname != name:
+ continue
+
+ target = target._interface()
+ if provided_interfaces:
+ for p in provided_interfaces:
+ if target.extends(p, False):
+ break
+ else:
+ # None matching
+ continue
+
+ yield (ancestor, target, with, aname, factories)
More information about the Zope3-Checkins
mailing list