diff options
Diffstat (limited to 'lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py')
-rw-r--r-- | lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py deleted file mode 100644 index 2ad145bf..00000000 --- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/adapter.py +++ /dev/null @@ -1,692 +0,0 @@ -############################################################################## -# -# Copyright (c) 2004 Zope Foundation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Adapter management -""" - -import weakref -from zope.interface import providedBy, Interface, ro - -_marker = object -class BaseAdapterRegistry(object): - - # List of methods copied from lookup sub-objects: - _delegated = ('lookup', 'queryMultiAdapter', 'lookup1', 'queryAdapter', - 'adapter_hook', 'lookupAll', 'names', - 'subscriptions', 'subscribers') - - # All registries maintain a generation that can be used by verifying - # registries - _generation = 0 - - def __init__(self, bases=()): - - # The comments here could be improved. Possibly this bit needs - # explaining in a separate document, as the comments here can - # be quite confusing. /regebro - - # {order -> {required -> {provided -> {name -> value}}}} - # Here "order" is actually an index in a list, "required" and - # "provided" are interfaces, and "required" is really a nested - # key. So, for example: - # for order == 0 (that is, self._adapters[0]), we have: - # {provided -> {name -> value}} - # but for order == 2 (that is, self._adapters[2]), we have: - # {r1 -> {r2 -> {provided -> {name -> value}}}} - # - self._adapters = [] - - # {order -> {required -> {provided -> {name -> [value]}}}} - # where the remarks about adapters above apply - self._subscribers = [] - - # Set, with a reference count, keeping track of the interfaces - # for which we have provided components: - self._provided = {} - - # Create ``_v_lookup`` object to perform lookup. We make this a - # separate object to to make it easier to implement just the - # lookup functionality in C. This object keeps track of cache - # invalidation data in two kinds of registries. - - # Invalidating registries have caches that are invalidated - # when they or their base registies change. An invalidating - # registry can only have invalidating registries as bases. - # See LookupBasePy below for the pertinent logic. - - # Verifying registies can't rely on getting invalidation messages, - # so have to check the generations of base registries to determine - # if their cache data are current. See VerifyingBasePy below - # for the pertinent object. - self._createLookup() - - # Setting the bases causes the registries described above - # to be initialized (self._setBases -> self.changed -> - # self._v_lookup.changed). - - self.__bases__ = bases - - def _setBases(self, bases): - self.__dict__['__bases__'] = bases - self.ro = ro.ro(self) - self.changed(self) - - __bases__ = property(lambda self: self.__dict__['__bases__'], - lambda self, bases: self._setBases(bases), - ) - - def _createLookup(self): - self._v_lookup = self.LookupClass(self) - for name in self._delegated: - self.__dict__[name] = getattr(self._v_lookup, name) - - def changed(self, originally_changed): - self._generation += 1 - self._v_lookup.changed(originally_changed) - - def register(self, required, provided, name, value): - if value is None: - self.unregister(required, provided, name, value) - return - - required = tuple(map(_convert_None_to_Interface, required)) - name = _normalize_name(name) - order = len(required) - byorder = self._adapters - while len(byorder) <= order: - byorder.append({}) - components = byorder[order] - key = required + (provided,) - - for k in key: - d = components.get(k) - if d is None: - d = {} - components[k] = d - components = d - - if components.get(name) is value: - return - - components[name] = value - - n = self._provided.get(provided, 0) + 1 - self._provided[provided] = n - if n == 1: - self._v_lookup.add_extendor(provided) - - self.changed(self) - - def registered(self, required, provided, name=u''): - required = tuple(map(_convert_None_to_Interface, required)) - name = _normalize_name(name) - order = len(required) - byorder = self._adapters - if len(byorder) <= order: - return None - - components = byorder[order] - key = required + (provided,) - - for k in key: - d = components.get(k) - if d is None: - return None - components = d - - return components.get(name) - - def unregister(self, required, provided, name, value=None): - required = tuple(map(_convert_None_to_Interface, required)) - order = len(required) - byorder = self._adapters - if order >= len(byorder): - return False - components = byorder[order] - key = required + (provided,) - - # Keep track of how we got to `components`: - lookups = [] - # Keep track of how we got to `components`: - lookups = [] - for k in key: - d = components.get(k) - if d is None: - return - lookups.append((components, k)) - components = d - - old = components.get(name) - if old is None: - return - if (value is not None) and (old is not value): - return - - del components[name] - if not components: - # Clean out empty containers, since we don't want our keys - # to reference global objects (interfaces) unnecessarily. - # This is often a problem when an interface is slated for - # removal; a hold-over entry in the registry can make it - # difficult to remove such interfaces. - for comp, k in reversed(lookups): - d = comp[k] - if d: - break - else: - del comp[k] - while byorder and not byorder[-1]: - del byorder[-1] - n = self._provided[provided] - 1 - if n == 0: - del self._provided[provided] - self._v_lookup.remove_extendor(provided) - else: - self._provided[provided] = n - - self.changed(self) - - def subscribe(self, required, provided, value): - required = tuple(map(_convert_None_to_Interface, required)) - name = u'' - order = len(required) - byorder = self._subscribers - while len(byorder) <= order: - byorder.append({}) - components = byorder[order] - key = required + (provided,) - - for k in key: - d = components.get(k) - if d is None: - d = {} - components[k] = d - components = d - - components[name] = components.get(name, ()) + (value, ) - - if provided is not None: - n = self._provided.get(provided, 0) + 1 - self._provided[provided] = n - if n == 1: - self._v_lookup.add_extendor(provided) - - self.changed(self) - - def unsubscribe(self, required, provided, value=None): - required = tuple(map(_convert_None_to_Interface, required)) - order = len(required) - byorder = self._subscribers - if order >= len(byorder): - return - components = byorder[order] - key = required + (provided,) - - # Keep track of how we got to `components`: - lookups = [] - # Keep track of how we got to `components`: - lookups = [] - for k in key: - d = components.get(k) - if d is None: - return - lookups.append((components, k)) - components = d - - old = components.get(u'') - if not old: - return - - if value is None: - new = () - else: - new = tuple([v for v in old if v is not value]) - - if new == old: - return - - if new: - components[u''] = new - else: - # Instead of setting components[u''] = new, we clean out - # empty containers, since we don't want our keys to - # reference global objects (interfaces) unnecessarily. This - # is often a problem when an interface is slated for - # removal; a hold-over entry in the registry can make it - # difficult to remove such interfaces. - if u'' in components: - del components[u''] - for comp, k in reversed(lookups): - d = comp[k] - if d: - break - else: - del comp[k] - while byorder and not byorder[-1]: - del byorder[-1] - - if provided is not None: - n = self._provided[provided] + len(new) - len(old) - if n == 0: - del self._provided[provided] - self._v_lookup.remove_extendor(provided) - - self.changed(self) - - # XXX hack to fake out twisted's use of a private api. We need to get them - # to use the new registed method. - def get(self, _): - class XXXTwistedFakeOut: - selfImplied = {} - return XXXTwistedFakeOut - - -_not_in_mapping = object() -class LookupBasePy(object): - - def __init__(self): - self._cache = {} - self._mcache = {} - self._scache = {} - - def changed(self, ignored=None): - self._cache.clear() - self._mcache.clear() - self._scache.clear() - - def _getcache(self, provided, name): - cache = self._cache.get(provided) - if cache is None: - cache = {} - self._cache[provided] = cache - if name: - c = cache.get(name) - if c is None: - c = {} - cache[name] = c - cache = c - return cache - - def lookup(self, required, provided, name=u'', default=None): - cache = self._getcache(provided, name) - if len(required) == 1: - result = cache.get(required[0], _not_in_mapping) - else: - result = cache.get(tuple(required), _not_in_mapping) - - if result is _not_in_mapping: - result = self._uncached_lookup(required, provided, name) - if len(required) == 1: - cache[required[0]] = result - else: - cache[tuple(required)] = result - - if result is None: - return default - - return result - - def lookup1(self, required, provided, name=u'', default=None): - cache = self._getcache(provided, name) - result = cache.get(required, _not_in_mapping) - if result is _not_in_mapping: - return self.lookup((required, ), provided, name, default) - - if result is None: - return default - - return result - - def queryAdapter(self, object, provided, name=u'', default=None): - return self.adapter_hook(provided, object, name, default) - - def adapter_hook(self, provided, object, name=u'', default=None): - required = providedBy(object) - cache = self._getcache(provided, name) - factory = cache.get(required, _not_in_mapping) - if factory is _not_in_mapping: - factory = self.lookup((required, ), provided, name) - - if factory is not None: - result = factory(object) - if result is not None: - return result - - return default - - def lookupAll(self, required, provided): - cache = self._mcache.get(provided) - if cache is None: - cache = {} - self._mcache[provided] = cache - - required = tuple(required) - result = cache.get(required, _not_in_mapping) - if result is _not_in_mapping: - result = self._uncached_lookupAll(required, provided) - cache[required] = result - - return result - - - def subscriptions(self, required, provided): - cache = self._scache.get(provided) - if cache is None: - cache = {} - self._scache[provided] = cache - - required = tuple(required) - result = cache.get(required, _not_in_mapping) - if result is _not_in_mapping: - result = self._uncached_subscriptions(required, provided) - cache[required] = result - - return result - -LookupBase = LookupBasePy - -class VerifyingBasePy(LookupBasePy): - - def changed(self, originally_changed): - LookupBasePy.changed(self, originally_changed) - self._verify_ro = self._registry.ro[1:] - self._verify_generations = [r._generation for r in self._verify_ro] - - def _verify(self): - if ([r._generation for r in self._verify_ro] - != self._verify_generations): - self.changed(None) - - def _getcache(self, provided, name): - self._verify() - return LookupBasePy._getcache(self, provided, name) - - def lookupAll(self, required, provided): - self._verify() - return LookupBasePy.lookupAll(self, required, provided) - - def subscriptions(self, required, provided): - self._verify() - return LookupBasePy.subscriptions(self, required, provided) - -VerifyingBase = VerifyingBasePy - - -try: - import _zope_interface_coptimizations -except ImportError: - pass -else: - from _zope_interface_coptimizations import LookupBase, VerifyingBase - -class AdapterLookupBase(object): - - def __init__(self, registry): - self._registry = registry - self._required = {} - self.init_extendors() - super(AdapterLookupBase, self).__init__() - - def changed(self, ignored=None): - super(AdapterLookupBase, self).changed(None) - for r in self._required.keys(): - r = r() - if r is not None: - r.unsubscribe(self) - self._required.clear() - - - # Extendors - # --------- - - # When given an target interface for an adapter lookup, we need to consider - # adapters for interfaces that extend the target interface. This is - # what the extendors dictionary is about. It tells us all of the - # interfaces that extend an interface for which there are adapters - # registered. - - # We could separate this by order and name, thus reducing the - # number of provided interfaces to search at run time. The tradeoff, - # however, is that we have to store more information. For example, - # is the same interface is provided for multiple names and if the - # interface extends many interfaces, we'll have to keep track of - # a fair bit of information for each name. It's better to - # be space efficient here and be time efficient in the cache - # implementation. - - # TODO: add invalidation when a provided interface changes, in case - # the interface's __iro__ has changed. This is unlikely enough that - # we'll take our chances for now. - - def init_extendors(self): - self._extendors = {} - for p in self._registry._provided: - self.add_extendor(p) - - def add_extendor(self, provided): - _extendors = self._extendors - for i in provided.__iro__: - extendors = _extendors.get(i, ()) - _extendors[i] = ( - [e for e in extendors if provided.isOrExtends(e)] - + - [provided] - + - [e for e in extendors if not provided.isOrExtends(e)] - ) - - def remove_extendor(self, provided): - _extendors = self._extendors - for i in provided.__iro__: - _extendors[i] = [e for e in _extendors.get(i, ()) - if e != provided] - - - def _subscribe(self, *required): - _refs = self._required - for r in required: - ref = r.weakref() - if ref not in _refs: - r.subscribe(self) - _refs[ref] = 1 - - def _uncached_lookup(self, required, provided, name=u''): - result = None - order = len(required) - for registry in self._registry.ro: - byorder = registry._adapters - if order >= len(byorder): - continue - - extendors = registry._v_lookup._extendors.get(provided) - if not extendors: - continue - - components = byorder[order] - result = _lookup(components, required, extendors, name, 0, - order) - if result is not None: - break - - self._subscribe(*required) - - return result - - def queryMultiAdapter(self, objects, provided, name=u'', default=None): - factory = self.lookup(map(providedBy, objects), provided, name) - if factory is None: - return default - - result = factory(*objects) - if result is None: - return default - - return result - - def _uncached_lookupAll(self, required, provided): - order = len(required) - result = {} - for registry in reversed(self._registry.ro): - byorder = registry._adapters - if order >= len(byorder): - continue - extendors = registry._v_lookup._extendors.get(provided) - if not extendors: - continue - components = byorder[order] - _lookupAll(components, required, extendors, result, 0, order) - - self._subscribe(*required) - - return tuple(result.iteritems()) - - def names(self, required, provided): - return [c[0] for c in self.lookupAll(required, provided)] - - def _uncached_subscriptions(self, required, provided): - order = len(required) - result = [] - for registry in reversed(self._registry.ro): - byorder = registry._subscribers - if order >= len(byorder): - continue - - if provided is None: - extendors = (provided, ) - else: - extendors = registry._v_lookup._extendors.get(provided) - if extendors is None: - continue - - _subscriptions(byorder[order], required, extendors, u'', - result, 0, order) - - self._subscribe(*required) - - return result - - def subscribers(self, objects, provided): - subscriptions = self.subscriptions(map(providedBy, objects), provided) - if provided is None: - result = () - for subscription in subscriptions: - subscription(*objects) - else: - result = [] - for subscription in subscriptions: - subscriber = subscription(*objects) - if subscriber is not None: - result.append(subscriber) - return result - -class AdapterLookup(AdapterLookupBase, LookupBase): - pass - -class AdapterRegistry(BaseAdapterRegistry): - - LookupClass = AdapterLookup - - def __init__(self, bases=()): - # AdapterRegisties are invalidating registries, so - # we need to keep track of out invalidating subregistries. - self._v_subregistries = weakref.WeakKeyDictionary() - - super(AdapterRegistry, self).__init__(bases) - - def _addSubregistry(self, r): - self._v_subregistries[r] = 1 - - def _removeSubregistry(self, r): - if r in self._v_subregistries: - del self._v_subregistries[r] - - def _setBases(self, bases): - old = self.__dict__.get('__bases__', ()) - for r in old: - if r not in bases: - r._removeSubregistry(self) - for r in bases: - if r not in old: - r._addSubregistry(self) - - super(AdapterRegistry, self)._setBases(bases) - - def changed(self, originally_changed): - super(AdapterRegistry, self).changed(originally_changed) - - for sub in self._v_subregistries.keys(): - sub.changed(originally_changed) - - -class VerifyingAdapterLookup(AdapterLookupBase, VerifyingBase): - pass - -class VerifyingAdapterRegistry(BaseAdapterRegistry): - - LookupClass = VerifyingAdapterLookup - -def _convert_None_to_Interface(x): - if x is None: - return Interface - else: - return x - -def _normalize_name(name): - if isinstance(name, basestring): - return unicode(name) - - raise TypeError("name must be a regular or unicode string") - -def _lookup(components, specs, provided, name, i, l): - if i < l: - for spec in specs[i].__sro__: - comps = components.get(spec) - if comps: - r = _lookup(comps, specs, provided, name, i+1, l) - if r is not None: - return r - else: - for iface in provided: - comps = components.get(iface) - if comps: - r = comps.get(name) - if r is not None: - return r - - return None - -def _lookupAll(components, specs, provided, result, i, l): - if i < l: - for spec in reversed(specs[i].__sro__): - comps = components.get(spec) - if comps: - _lookupAll(comps, specs, provided, result, i+1, l) - else: - for iface in reversed(provided): - comps = components.get(iface) - if comps: - result.update(comps) - -def _subscriptions(components, specs, provided, name, result, i, l): - if i < l: - for spec in reversed(specs[i].__sro__): - comps = components.get(spec) - if comps: - _subscriptions(comps, specs, provided, name, result, i+1, l) - else: - for iface in reversed(provided): - comps = components.get(iface) - if comps: - comps = comps.get(name) - if comps: - result.extend(comps) |