[Zodb-checkins] CVS: Zope3/src/zope/interface - surrogate.py:1.1.2.9
Jim Fulton
cvs-admin at zope.org
Tue Nov 11 10:52:34 EST 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv13421/src/zope/interface
Modified Files:
Tag: adaptergeddon-branch
surrogate.py
Log Message:
Did some refactoring in preparation for local surrogate registries.
- Changed adapter registrations to not use weakrefs.
- Factored out code for computing implied info based on adapter
registrations.
- Changed the strategy for computing the "implied" data structure to
merge surrogate-local implied data structures, reducing the amound
of computation done.
=== Zope3/src/zope/interface/surrogate.py 1.1.2.8 => 1.1.2.9 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.8 Mon Nov 10 15:45:20 2003
+++ Zope3/src/zope/interface/surrogate.py Tue Nov 11 10:52:33 2003
@@ -97,8 +97,6 @@
for base in self.__bases__:
base.subscribe(self)
- self._computeImplied()
-
def subscribe(self, dependent):
self.dependents[dependent] = 1
@@ -112,8 +110,17 @@
return self._interface().isImplementedBy(ob)
def _adaptTo(self, specification, factories, name='', with=()):
- self._adapters[with, name, specification] = factories
- self._computeSelfImplied()
+ if factories is None:
+ try:
+ del self._adapters[with, name, specification]
+ except KeyError:
+ pass
+ else:
+ self._adapters[with, name, specification] = factories
+
+ adapterImplied(self._adapters,
+ self._selfimplied,
+ self._multimplied)
self.changed()
def changed(self):
@@ -121,28 +128,6 @@
for dependent in self.dependents.keys():
dependent.changed()
- def _computeSelfImplied(self):
- implied = self._selfimplied
- implied.clear()
- multi = self._multimplied
- multi.clear()
- registered = {}
-
- # Add adapters and interfaces directly implied by same:
- for (with, name, target), factories in self._adapters.iteritems():
- if with:
- self.__add_multi_adapter(with, name, target, target,
- multi, factories)
- elif name:
- self.__add_named_adapter(target, target, name,
- implied, registered,
- factories)
- else:
- self.__add_adapter(target, target,
- implied, registered,
- factories)
-
-
def _computeImplied(self):
implied = self._implied
implied.clear()
@@ -162,44 +147,6 @@
implied[k] = ancestor_adapters.copy()
- def __add_adapter(self, target, provided, implied, registered, factories):
- if (target not in implied
- or
- (target in registered and registered[target].extends(provided))
- ):
- registered[target] = provided
- implied[target] = factories
- for b in target.__bases__:
- self.__add_adapter(b, provided, implied, registered, factories)
-
- def __add_named_adapter(self, target, provided, name,
- implied, registered, factories):
- key = target, name
- if (key not in implied
- or
- (key in registered and registered[key].extends(provided))
- ):
- registered[key] = provided
- implied[key] = factories
- for b in target.__bases__:
- self.__add_named_adapter(b, provided, name,
- implied, registered, factories)
-
- def __add_multi_adapter(self, interfaces, name, target, provided,
- implied, factories):
-
- order = len(interfaces)+1
- adapters = implied.get((target, name, order))
- if adapters is None:
- adapters = {}
- implied[(target, name, order)] = adapters
-
- adapters.setdefault(interfaces, factories)
-
- for b in target.__bases__:
- self.__add_multi_adapter(interfaces, name, b, provided,
- implied, factories)
-
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self._interface())
@@ -212,30 +159,20 @@
# dict because we have to use spec.weakref() rather than
# weakref.ref(spec) to get weak refs to specs.
+ _surrogateClass = Surrogate
+
def __init__(self):
self._surrogates = surrogates = {}
- self._default = Surrogate(Default, self)
-
- def _remove(k, selfref=weakref.ref(self)):
- self = selfref()
- if self is not None:
- try:
- del self._surrogates[k]
- except KeyError:
- pass
-
+ self._default = self._surrogateClass(Default, self)
- def _remove(k, surrogates=surrogates):
+ def _remove(k):
try:
del surrogates[k]
except KeyError:
pass
-
-
self._remove = _remove
-
def get(self, declaration):
if declaration is None:
return self._default
@@ -243,7 +180,8 @@
ref = declaration.weakref(self._remove)
surrogate = self._surrogates.get(ref)
if surrogate is None:
- surrogate = Surrogate(declaration, self)
+ surrogate = self._surrogateClass(declaration, self)
+ surrogate._computeImplied()
self._surrogates[ref] = surrogate
return surrogate
@@ -258,9 +196,8 @@
have a named adapter with an empty name.
"""
required = self.get(required)
- provided = self.get(provided)
if with:
- with = tuple(map(self.get, with))
+ with = tuple(with)
else:
with = ()
@@ -272,73 +209,55 @@
def queryAdapter(self, ob, interface, default=None, raw=False):
"""Query a simple adapter
- >>> import zope.interface
- >>> class F0(zope.interface.Interface):
- ... pass
- >>> class F1(F0):
- ... pass
+ >>> import zope.interface
+ >>> class F0(zope.interface.Interface):
+ ... pass
+ >>> class F1(F0):
+ ... pass
- >>> class C:
- ... zope.interface.implements(F1)
- >>> c = C()
+ >>> class C:
+ ... zope.interface.implements(F1)
+ >>> c = C()
- >>> registry = SurrogateRegistry()
+ >>> registry = SurrogateRegistry()
- When we adapt an object to an interface it implements, we get
- the object back:
+ Adapting to some other interface for which there is no
+ adapter returns the default:
- >>> registry.queryAdapter(c, F0) is c
- 1
+ >>> class B0(zope.interface.Interface):
+ ... pass
+ >>> class B1(B0):
+ ... pass
- But adapting to some other interface returns the default:
-
- >>> class B0(zope.interface.Interface):
- ... pass
- >>> class B1(B0):
- ... pass
+ >>> registry.queryAdapter(c, B0)
+ >>> registry.queryAdapter(c, B0, 42)
+ 42
- >>> registry.queryAdapter(c, B0)
- >>> registry.queryAdapter(c, B0, 42)
- 42
+ Unless we define an adapter:
- Unless we define an adapter:
+ >>> def f1(ob):
+ ... return 1
- >>> def f1(ob):
- ... return 1
+ >>> registry.provideAdapter(F0, B1, [f1])
+ >>> registry.queryAdapter(c, B0)
+ 1
- >>> registry.provideAdapter(F0, B1, [f1])
- >>> registry.queryAdapter(c, B0)
- 1
-
- If we define a more specific adapter (for F1), we'll get that:
-
- >>> def f2(ob):
- ... return 2
+ If we define a more specific adapter (for F1), we'll get that:
- >>> registry.provideAdapter(F1, B1, [f2])
- >>> registry.queryAdapter(c, B0)
- 2
-
- >>> def f3(ob):
- ... return 3
+ >>> def f2(ob):
+ ... return 2
- >>> registry.provideAdapter(F1, B0, [f3])
- >>> registry.queryAdapter(c, B0)
- 3
+ >>> registry.provideAdapter(F1, B1, [f2])
+ >>> registry.queryAdapter(c, B0)
+ 2
+ >>> def f3(ob):
+ ... return 3
- """
- surrogate = self._surrogates.get(interface.weakref())
- if surrogate is None:
- # If there is no surrogate for the interface, then we can't
- # have an adapter for it.
-
- # But we may implement it
- if interface.isImplementedBy(ob):
- return ob
- return default
-
- interface = surrogate
+ >>> registry.provideAdapter(F1, B0, [f3])
+ >>> registry.queryAdapter(c, B0)
+ 3
+ """
declaration = providedBy(ob)
s = self.get(declaration)
@@ -407,12 +326,7 @@
3
"""
- interface = self._surrogates.get(interface.weakref())
- if interface is None:
- # If there is no surrogate for the interface, then we can't
- # have an adapter for it.
- return default
-
+
declaration = providedBy(ob)
s = self.get(declaration)
factories = s._implied.get((interface, name))
@@ -492,12 +406,6 @@
True
"""
- interface = self._surrogates.get(interface.weakref())
- if interface is None:
- # If there is no surrogate for the interface, then we can't
- # have an adapter for it.
- return None
-
ob = objects[0]
order = len(objects)
obs = objects[1:]
@@ -549,122 +457,121 @@
provided_interfaces=None,
name = None,
):
-
"""Search for registered adapters
- Note, this is usually slow!
+ Note, this is usually slow!
- >>> from zope.interface import Interface
+ >>> 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', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(name=''))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3')]
-
- >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3')]
-
- >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(provided_interfaces=P1))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(provided_interfaces=P3))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(
- ... required_interfaces = (R4, R12),
- ... provided_interfaces = (P1, )))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(
- ... required_interfaces = (R4, R12),
- ... provided_interfaces = (P3, )))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(
- ... required_interfaces = (R2, ),
- ... provided_interfaces = (P3, )))
- [(None, 'P3', (), u'', 'default P3'),
- ('Interface', 'P3', (), u'', 'any P3'),
- ('R2', 'P3', (), u'', 'R2 P3'),
- ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(
- ... required_interfaces = (R2, ),
- ... provided_interfaces = (P3, ),
- ... name='bob'))
- [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
-
- >>> sorted(registry.getRegisteredMatching(
- ... required_interfaces = (R3, ),
- ... provided_interfaces = (P1, ),
- ... name='bob'))
- [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+ >>> 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', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(name=''))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3')]
+
+ >>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=[P1]))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=P1))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(provided_interfaces=P3))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R4, R12),
+ ... provided_interfaces = (P1, )))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R4, R12),
+ ... provided_interfaces = (P3, )))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R2, ),
+ ... provided_interfaces = (P3, )))
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3'),
+ ('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R2, ),
+ ... provided_interfaces = (P3, ),
+ ... name='bob'))
+ [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
+
+ >>> sorted(registry.getRegisteredMatching(
+ ... required_interfaces = (R3, ),
+ ... provided_interfaces = (P1, ),
+ ... name='bob'))
+ [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
- """
+ """
if name is not None:
name = unicode(name)
@@ -689,25 +596,76 @@
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
+ adapters = ancestor._adapters
+ if adapters:
+ items = 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
- yield (ancestor, target, with, aname, factories)
+ if provided_interfaces:
+ for p in provided_interfaces:
+ if target.extends(p, False):
+ break
+ else:
+ # None matching
+ continue
+
+ yield (ancestor, target, with, aname, factories)
+
+
+
+def adapterImplied(adapters, implied, multi):
+ implied.clear()
+ multi.clear()
+ registered = {}
+
+ # Add adapters and interfaces directly implied by same:
+ for (with, name, target), factories in adapters.iteritems():
+ if with:
+ _add_multi_adapter(with, name, target, target, multi, factories)
+ elif name:
+ _add_named_adapter(target, target, name, implied, registered,
+ factories)
+ else:
+ _add_adapter(target, target, implied, registered, factories)
+
+def _add_adapter(target, provided, implied, registered, factories):
+ if (target not in implied
+ or
+ (target in registered and registered[target].extends(provided))
+ ):
+ registered[target] = provided
+ implied[target] = factories
+ for b in target.__bases__:
+ _add_adapter(b, provided, implied, registered, factories)
+
+def _add_named_adapter(target, provided, name,
+ implied, registered, factories):
+ key = target, name
+ if (key not in implied
+ or
+ (key in registered and registered[key].extends(provided))
+ ):
+ registered[key] = provided
+ implied[key] = factories
+ for b in target.__bases__:
+ _add_named_adapter(b, provided, name,
+ implied, registered, factories)
+
+def _add_multi_adapter(interfaces, name, target, provided, implied, factories):
+ order = len(interfaces)+1
+ adapters = implied.get((target, name, order))
+ if adapters is None:
+ adapters = {}
+ implied[(target, name, order)] = adapters
+ adapters.setdefault(interfaces, factories)
+ for b in target.__bases__:
+ _add_multi_adapter(interfaces, name, b, provided, implied, factories)
More information about the Zodb-checkins
mailing list