[Zodb-checkins] CVS: Zope3/src/zope/interface -
surrogate.py:1.1.2.10
Jim Fulton
cvs-admin at zope.org
Wed Nov 12 15:08:19 EST 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv25410/src/zope/interface
Modified Files:
Tag: adaptergeddon-branch
surrogate.py
Log Message:
Changed the strategy for tracking changes. Now, when we register new
adapters, we mark affected surrogates as dirty. They will recompute
their implied information only when it is needed.
=== Zope3/src/zope/interface/surrogate.py 1.1.2.9 => 1.1.2.10 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.9 Tue Nov 11 10:52:33 2003
+++ Zope3/src/zope/interface/surrogate.py Wed Nov 12 15:08:15 2003
@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Surrogate-interface registry implementation
+"""Surrogate-specification registry implementation
$Id$
"""
@@ -40,13 +40,13 @@
# where:
-# with is a tuple of surrogates that is non-empty only in the case
+# with is a tuple of specs that is non-empty only in the case
# of multi-adapters.
# name is a unicode adapter name. Unnamed adapters have an empty
# name.
-# specification is the surrogate of the interface being adapted to.
+# specification is the interface being adapted to.
# factories is normally a tuple of factories, but can be anything.
# (See the "raw" option to the query-adapter calls.)
@@ -75,6 +75,16 @@
Default = InterfaceClass("Default", (), {})
+class ReadProperty(object):
+
+ def __init__(self, func):
+ self.func = func
+
+ def __get__(self, inst, class_):
+ if inst is None:
+ return self
+ return self.func(inst)
+
class Surrogate(object):
"""Specification surrogate
@@ -82,55 +92,29 @@
behalf of a specification.
"""
- def __init__(self, interface, registry):
- self._adapters = {}
- self._implied = {}
- self._selfimplied = {}
- self._multimplied = {}
-
- self._interface = interface.weakref()
- interface.subscribe(self)
-
- self._registry = registry
+ def __init__(self, spec, registry):
+ self.spec = spec.weakref()
+ spec.subscribe(self)
+ self.adapters = {}
self.dependents = weakref.WeakKeyDictionary()
- self.__bases__ = [registry.get(base) for base in interface.__bases__]
+
+ self.__bases__ = [registry.get(base) for base in spec.__bases__]
for base in self.__bases__:
base.subscribe(self)
- def subscribe(self, dependent):
- self.dependents[dependent] = 1
-
- def unsubscribe(self, dependent):
- del self.dependents[dependent]
-
- def extends(self, other, strict=True):
- return self._interface().extends(other._interface(), strict)
-
- def isImplementedBy(self, ob):
- return self._interface().isImplementedBy(ob)
-
- def _adaptTo(self, specification, factories, name='', with=()):
- 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):
- self._computeImplied()
+ def dirty(self):
+ if 'get' in self.__dict__:
+ # Not already dirty
+ del self.selfImplied
+ del self.multImplied
+ del self.get
for dependent in self.dependents.keys():
- dependent.changed()
+ dependent.dirty()
+
+ def clean(self):
+ self.selfImplied, self.multImplied = adapterImplied(self.adapters)
- def _computeImplied(self):
- implied = self._implied
- implied.clear()
+ implied = {}
ancestors = ro(self)
@@ -138,17 +122,60 @@
# override less-specific data.
ancestors.reverse()
for ancestor in ancestors:
- implied.update(ancestor._selfimplied)
- for k, ancestor_adapters in ancestor._multimplied.iteritems():
+ implied.update(ancestor.selfImplied)
+ for k, ancestor_adapters in ancestor.multImplied.iteritems():
implied_adapters = implied.get(k)
if implied_adapters:
implied_adapters.update(ancestor_adapters)
else:
implied[k] = ancestor_adapters.copy()
-
+
+ self.get = implied.get
+
+ def get(self, key):
+ """Get an implied value
+
+ This is only called when the surrogate is dirty
+ """
+ self.clean()
+ return self.__dict__['get'](key)
+
+ def selfImplied(self):
+ """Return selfImplied when dirty
+ """
+ self.clean()
+ return self.__dict__['selfImplied']
+ selfImplied = ReadProperty(selfImplied)
+
+ def multiImplied(self):
+ """Return _multiImplied when dirty
+ """
+ self.clean()
+ return self.__dict__['multiImplied']
+ multiImplied = ReadProperty(multiImplied)
+
+ def subscribe(self, dependent):
+ self.dependents[dependent] = 1
+
+ def unsubscribe(self, dependent):
+ del self.dependents[dependent]
+
+ def _adaptTo(self, specification, factories, name='', with=()):
+ if factories is None:
+ try:
+ del self.adapters[with, name, specification]
+ except KeyError:
+ pass
+ else:
+ self.adapters[with, name, specification] = factories
+
+ self.dirty()
+
+ def changed(self, which=None):
+ self.dirty()
def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, self._interface())
+ return '<%s(%s)>' % (self.__class__.__name__, self.spec())
class SurrogateRegistry(object):
"""Surrogate registry
@@ -181,14 +208,12 @@
surrogate = self._surrogates.get(ref)
if surrogate is None:
surrogate = self._surrogateClass(declaration, self)
- surrogate._computeImplied()
self._surrogates[ref] = surrogate
return surrogate
- def provideAdapter(self, required, provided, factories,
- name=u'', with=()):
+ def provideAdapter(self, required, provided, factories, name=u'', with=()):
"""Register an adapter
Note that the given name must be convertable to unicode.
@@ -262,9 +287,9 @@
declaration = providedBy(ob)
s = self.get(declaration)
- factories = s._implied.get(interface)
+ factories = s.get(interface)
if factories is None:
- factories = self._default._implied.get(interface)
+ factories = self._default.get(interface)
if factories is not None:
if raw:
@@ -329,9 +354,9 @@
declaration = providedBy(ob)
s = self.get(declaration)
- factories = s._implied.get((interface, name))
+ factories = s.get((interface, name))
if factories is None:
- factories = self._default._implied.get((interface, name))
+ factories = self._default.get((interface, name))
if factories is not None:
if raw:
return factories
@@ -413,9 +438,9 @@
declaration = providedBy(ob)
s = self.get(declaration)
- adapters = s._implied.get((interface, name, order))
+ adapters = s.get((interface, name, order))
if adapters is None:
- adapters = self._default._implied.get((interface, name, order))
+ adapters = self._default.get((interface, name, order))
if adapters:
matched = None
@@ -596,10 +621,10 @@
if ancestor in seen:
continue
seen[ancestor] = 1
- adapters = ancestor._adapters
+ adapters = ancestor.adapters
if adapters:
items = adapters.iteritems()
- ancestor = ancestor._interface()
+ ancestor = ancestor.spec()
if ancestor is Default:
ancestor = None
for (with, aname, target), factories in items:
@@ -620,9 +645,9 @@
-def adapterImplied(adapters, implied, multi):
- implied.clear()
- multi.clear()
+def adapterImplied(adapters):
+ implied = {}
+ multi = {}
registered = {}
# Add adapters and interfaces directly implied by same:
@@ -634,6 +659,8 @@
factories)
else:
_add_adapter(target, target, implied, registered, factories)
+
+ return implied, multi
def _add_adapter(target, provided, implied, registered, factories):
if (target not in implied
More information about the Zodb-checkins
mailing list