[Zope3-checkins] CVS: Zope3/src/zope/interface -
interface.py:1.13.4.7 interfaces.py:1.15.8.3
surrogate.py:1.1.2.6 type.py:1.10.30.1
Jim Fulton
cvs-admin at zope.org
Sun Nov 9 11:09:04 EST 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv15349/src/zope/interface
Modified Files:
Tag: adaptergeddon-branch
interface.py interfaces.py surrogate.py type.py
Log Message:
Created a global presentation service that replaces the
global view, resource, and skin services.
Now look up presentation components by adapting from a request type,
rather than adapting to a presentation type.
=== Zope3/src/zope/interface/interface.py 1.13.4.6 => 1.13.4.7 ===
--- Zope3/src/zope/interface/interface.py:1.13.4.6 Thu Nov 6 07:35:10 2003
+++ Zope3/src/zope/interface/interface.py Sun Nov 9 11:08:33 2003
@@ -230,8 +230,8 @@
# We directly imply our ancestors:
implied[ancestor] = ()
- # Now, advize our dependents of change:
- for dependent in self.dependents:
+ # Now, advise our dependents of change:
+ for dependent in self.dependents.keys():
dependent.changed()
@@ -313,6 +313,13 @@
and
((not strict) or (self != interface))
)
+
+ def weakref(self, callback=None):
+ if callback is None:
+ return weakref.ref(self)
+ else:
+ return weakref.ref(self, callback)
+
class InterfaceClass(Element, Specification):
"""Prototype (scarecrow) Interfaces Implementation."""
=== Zope3/src/zope/interface/interfaces.py 1.15.8.2 => 1.15.8.3 ===
--- Zope3/src/zope/interface/interfaces.py:1.15.8.2 Thu Nov 6 07:35:10 2003
+++ Zope3/src/zope/interface/interfaces.py Sun Nov 9 11:08:33 2003
@@ -55,7 +55,44 @@
"""Return a signature string suitable for inclusion in documentation.
"""
-class IInterface(IElement):
+class ISpecification(Interface):
+ """Object Behavioral specifications
+ """
+
+ def extends(other, strict=True):
+ """Test whether a specification extends another
+
+ The specification extends other if it has other as a base
+ interface or if one of it's bases extends other.
+
+ If strict is false, then the specification extends itself.
+
+ """
+
+ def isOrExtends(other):
+ """Test whether the specification is or extends another
+ """
+
+ def weakref(callback=None):
+ """Return a weakref to the specification
+
+ This method is, regrettably, needed to allow weakrefs to be
+ computed to security-proxied specifications. While the
+ zope.interface package does not require zope.security or
+ zope.proxy, it has to be able to coexist with it.
+
+ """
+
+ __bases__ = Attribute("""Base specifications
+
+ A tuple if specifications from which this specification is
+ directly derived.
+
+ """)
+
+
+
+class IInterface(ISpecification, IElement):
"""Interface objects
Interface objects describe the behavior of an object by containing
@@ -147,26 +184,6 @@
"""
-
- def extends(other, strict=True):
- """Test whether the interface extends another interface
-
- A true value is returned in the interface extends the other
- interface, and false otherwise.
-
- Normally, an interface doesn't extend itself. If a false value
- is passed as the second argument, or via the 'strict' keyword
- argument, then a true value will be returned if the interface
- and the other interface are the same.
- """
-
- def isOrExtends(other):
- """Test whether the interface is or extends another interface
-
- A true value is returned in the interface is or extends the other
- interface, and false otherwise.
- """
-
def isImplementedBy(object):
"""Test whether the interface is implemented by the object
@@ -239,8 +256,6 @@
"""
__module__ = Attribute("""The name of the module defining the interface""")
-
- __bases__ = Attribute("""A tuple of base interfaces""")
@@ -437,7 +452,7 @@
"""
-class IDeclaration(Interface):
+class IDeclaration(ISpecification):
"""Interface declaration
Declarations are used to express the interfaces implemented by
@@ -466,21 +481,6 @@
base interfaces are listed after interfaces that extend them
and, otherwise, interfaces are included in the order that they
were defined in the specification.
- """
-
- def extends(interface):
- """Test whether an interface specification extends an interface
-
- An interface specification extends an interface if it contains
- an interface that extends an interface.
-
- """
-
- def isOrExtends(other):
- """Test whether the interface is or extends another interface
-
- A true value is returned in the interface is or extends the other
- interface, and false otherwise.
"""
def __sub__(interfaces):
=== Zope3/src/zope/interface/surrogate.py 1.1.2.5 => 1.1.2.6 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.5 Thu Oct 16 18:48:28 2003
+++ Zope3/src/zope/interface/surrogate.py Sun Nov 9 11:08:33 2003
@@ -16,59 +16,76 @@
$Id$
"""
-# Optimization notes
+# Implementation notes
-# For each surrogate, we store a dict {key -> factories}
+# We keep a collection of surregates.
+
+# A surrogate is a surrogate for a specifiocation (interface or
+# declaration). We use wek references in order to remove surrogates if
+# the corresponding specification goes away.
+
+# Each surrogate keeps track of:
+
+# - The adapters registered directly for that surrogate, and
+
+# - The "implied" adapters, which is the adapters that can be computed
+# from instances of that surrogate.
+
+# The later data structure takes into account adapters registered for
+# specifications that the registered surrogate extends.
+
+# The registrations are of the form:
+
+# {(with, name, specification) -> factories}
+
+# where:
+
+# with is a tuple of surrogates 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.
+
+# factories is normally a tuple of factories, but can be anything.
+# (See the "raw" option to the query-adapter calls.)
+
+# The implied adapters are held in a single dictionary. The items in the
+# dictionary are of 3 forms:
+
+# specification -> factories
+
+# for simple unnamed adapters
+
+# (specification, name) -> factories
+
+# for named adapters
+
+# (specification, name, order) -> {with -> factories}
+
+# for multi-adapters.
-# where key is one of
-# provides,
-# provided, name
-# provided, name, order
-
-# Currently, we stora all of the keys in a single dict:
-
-# consider named adapters. Each key is a two-tuple.
-# That's 5 extra words per key for the tuple.
-
-# suppose that the dict was of the form:
-# {name -> {provided -> factroies}
-
-# This saves n-1 * 5 words, where n is the number of entries for a
-# given name. There is the overhead of an extra dictionary per
-# word. Given that many interfaces only have a single entry, this
-# extra overhead could be significant, however, there are some extra
-# opportunities for savings. See below. There are two dict lookups,
-# but, possibly, each lookup is cheaper, because the cache and
-# comparisons are cheaper.
-
-# It will often be the case that an implied dict (for a required
-# interface and name (and order), will be equal to the implied dict
-# for one of the interfaces bases. This will happen, for example, when
-# there aren't adapters registered for an interface and the interface
-# has one base. In a case like this, the interface can share the
-# implied dict with the base.
-
-# Additional savings will be permitted for local surrogates. For
-# example, it will often be the case that the implied dictionary
-# for a local surrogate will be the same as the implied dictionary for
-# 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):
+ """Specification surrogate
+
+ A specification surrogate is used to hold adapter registrations on
+ behalf of a specification.
+ """
def __init__(self, interface, registry):
self._adapters = {}
self._implied = {}
- self._interface = weakref.ref(interface)
+ self._interface = interface.weakref()
interface.subscribe(self)
self._registry = registry
@@ -96,7 +113,7 @@
def changed(self):
self._computeImplied()
- for dependent in self.dependents:
+ for dependent in self.dependents.keys():
dependent.changed()
def _computeImplied(self):
@@ -173,31 +190,62 @@
return '%s(%s)' % (self.__class__.__name__, self._interface())
class SurrogateRegistry(object):
+ """Surrogate registry
+ """
+
+ # Implementation node:
+ # We are like a weakref dict ourselves. We can't use a weakref
+ # dict because we have to use spec.weakref() rather than
+ # weakref.ref(spec) to get weak refs to specs.
def __init__(self):
- self._surrogates = weakref.WeakKeyDictionary()
+ self._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._remove = _remove
+
+
def get(self, declaration):
if declaration is None:
return self._default
- surrogate = self._surrogates.get(declaration)
+
+ ref = declaration.weakref(self._remove)
+ surrogate = self._surrogates.get(ref)
if surrogate is None:
surrogate = Surrogate(declaration, self)
- self._surrogates[declaration] = surrogate
+ self._surrogates[ref] = surrogate
+
return surrogate
+
def provideAdapter(self, required, provided, factories,
- name='', with=()):
+ name=u'', with=()):
+ """Register an adapter
+
+ Note that the given name must be convertable to unicode.
+ Use an empty string for unnamed adapters. It is impossible to
+ have a named adapter with an empty name.
+ """
required = self.get(required)
provided = self.get(provided)
if with:
with = tuple(map(self.get, with))
else:
with = ()
- required._adaptTo(provided, factories, name or '', with)
- def queryAdapter(self, ob, interface, default=None):
+ if not isinstance(name, basestring):
+ raise TypeError("The name provided to provideAdapter "
+ "must be a string or unicode")
+ required._adaptTo(provided, factories, unicode(name), with)
+
+ def queryAdapter(self, ob, interface, default=None, raw=False):
"""Query a simple adapter
>>> import zope.interface
@@ -256,10 +304,7 @@
"""
-
- surrogates = self._surrogates
-
- surrogate = surrogates.get(interface)
+ 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.
@@ -271,20 +316,24 @@
interface = surrogate
- declaration = removeAllProxies(providedBy(ob))
+ declaration = 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:
+ if raw:
+ return factories
+
for factory in factories:
ob = factory(ob)
return ob
return default
- def queryNamedAdapter(self, ob, interface, name, default=None):
+ def queryNamedAdapter(self, ob, interface, name, default=None, raw=False):
"""Query a named simple adapter
>>> import zope.interface
@@ -333,11 +382,8 @@
>>> registry.queryNamedAdapter(c, B0, 'bob')
3
-
"""
- surrogates = self._surrogates
-
- interface = surrogates.get(interface)
+ 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.
@@ -347,15 +393,18 @@
s = self.get(declaration)
factories = s._implied.get((interface, name))
if factories is None:
- factories = s._implied.get((Default, name))
+ factories = self._default._implied.get((interface, name))
if factories is not None:
+ if raw:
+ return factories
for factory in factories:
ob = factory(ob)
return ob
return default
- def queryMultiAdapter(self, objects, interface, name):
+ def queryMultiAdapter(self, objects, interface, name=u'',
+ default=None, raw=False):
"""
>>> import zope.interface
@@ -379,7 +428,7 @@
>>> registry = SurrogateRegistry()
- If we ask for a named adapter, we won't get a result unless there
+ If we ask for a multi adapter, we won't get a result unless there
is a named adapter, even if the object implements the interface:
>>> registry.queryMultiAdapter((c, r), IF0, 'bob')
@@ -390,29 +439,36 @@
... pass
- >>> def f1(ob):
- ... return 1
+ >>> class f1:
+ ... def __init__(self, x, y):
+ ... self.x, self.y = x, y
+
>>> registry.provideAdapter(IF0, IB1, [f1], name='bob', with=[IR0])
- >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
- 1
- >>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
+ >>> a = registry.queryMultiAdapter((c, r), IB0, 'bob')
+ >>> a.__class__ is f1
+ True
+ >>> a.x is c
+ True
+ >>> a.y is r
+ True
+ >>> registry.queryMultiAdapter((c, r), IB0, 'bruce')
- >>> def f2(ob):
- ... return 2
+ >>> class f2(f1):
+ ... pass
>>> registry.provideAdapter(IF1, IB1, [f2], name='bob', with=[IR1])
- >>> registry.queryMultiAdapter((c, r), IB0, 'bob')
- 2
+ >>> a = registry.queryMultiAdapter((c, r), IB0, 'bob')
+ >>> a.__class__ is f2
+ True
+ >>> a.x is c
+ True
+ >>> a.y is r
+ True
- >>> def f3(ob):
- ... return 3
-
"""
- surrogates = self._surrogates
-
- interface = surrogates.get(interface)
+ 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.
@@ -420,19 +476,20 @@
ob = objects[0]
order = len(objects)
- objects = objects[1:]
+ obs = objects[1:]
declaration = providedBy(ob)
s = self.get(declaration)
adapters = s._implied.get((interface, name, order))
if adapters is None:
- adapters = s._implied.get((Default, name, order))
+ adapters = self._default._implied.get((interface, name, order))
+
if adapters:
matched = None
matched_factories = None
for interfaces, factories in adapters.iteritems():
- for iface, ob in zip(interfaces, objects):
+ for iface, ob in zip(interfaces, obs):
if not iface.isImplementedBy(ob):
break # This one is no good
else:
@@ -451,11 +508,17 @@
# old is better than new
break
- for factory in matched_factories:
- ob = factory(ob)
- return ob
+ if matched_factories is None:
+ return default
+
+ if raw:
+ return matched_factories
- return None
+ assert len(matched_factories) == 1
+
+ return matched_factories[0](*objects)
+
+ return default
def getRegisteredMatching(self,
required_interfaces=None,
@@ -505,85 +568,88 @@
... pprint(x)
>>> sorted(registry.getRegisteredMatching())
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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(name=''))
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3')]
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3'),
+ ('R2', 'P3', (), u'', 'R2 P3')]
>>> sorted(registry.getRegisteredMatching(required_interfaces=[R1]))
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3')]
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', 'any P3')]
>>> sorted(registry.getRegisteredMatching(required_interfaces=R1))
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3')]
+ [(None, 'P3', (), u'', 'default P3'),
+ ('Interface', 'P3', (), u'', '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')]
+ [(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', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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(provided_interfaces=P3))
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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 = (P3, )))
- [(None, 'P3', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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', (), '', 'default P3'),
- ('Interface', 'P3', (), '', 'any P3'),
- ('R2', 'P3', (), '', 'R2 P3'),
- ('R2', 'P3', (), 'bob', 'bobs R2 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', (), 'bob', 'bobs R2 P3')]
+ [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
>>> sorted(registry.getRegisteredMatching(
... required_interfaces = (R3, ),
... provided_interfaces = (P1, ),
... name='bob'))
- [('R2', 'P3', (), 'bob', 'bobs R2 P3')]
+ [('R2', 'P3', (), u'bob', 'bobs R2 P3')]
"""
+ if name is not None:
+ name = unicode(name)
if isinstance(required_interfaces, InterfaceClass):
required_interfaces = (required_interfaces, )
elif required_interfaces is None:
- required_interfaces = self._surrogates.keys()
+ required_interfaces = [ref() for ref in self._surrogates.keys()
+ if ref() is not None]
required_interfaces = tuple(required_interfaces)+(None,)
=== Zope3/src/zope/interface/type.py 1.10 => 1.10.30.1 ===
--- Zope3/src/zope/interface/type.py:1.10 Sat Jun 7 02:37:29 2003
+++ Zope3/src/zope/interface/type.py Sun Nov 9 11:08:33 2003
@@ -96,7 +96,7 @@
result = []
for k in self._reg:
- if k is None or k.extends(interface, strict=False):
+ if k is None or k.extends(interface, False):
result.append(k)
return result
More information about the Zope3-Checkins
mailing list