K2LL33D SHELL

 Apache/2.4.7 (Ubuntu)
 Linux sman1baleendah 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64
 uid=33(www-data) gid=33(www-data) groups=33(www-data)
 safemode : OFF
 MySQL: ON | Perl: ON | cURL: OFF | WGet: ON
  >  / usr / lib / python2.7 / dist-packages / zope / interface /
server ip : 104.21.89.46

your ip : 172.69.59.191

H O M E


Filename/usr/lib/python2.7/dist-packages/zope/interface/adapter.py
Size22.51 kb
Permissionrw-r--r--
Ownerroot : root
Create time27-Apr-2025 09:56
Last modified01-Mar-2013 00:51
Last accessed06-Jul-2025 23:36
Actionsedit | rename | delete | download (gzip)
Viewtext | code | image
##############################################################################
#
# Copyright (c) 2004 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
from zope.interface import Interface
from zope.interface import ro
from zope.interface._compat import _u
from zope.interface._compat import _normalize_name

_BLANK = _u('')

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 LookupBaseFallback 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=_BLANK):
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 = _BLANK
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(_BLANK)
if not old:
# this is belt-and-suspenders against the failure of cleanup below
return #pragma NO COVERAGE

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[_BLANK] = new
else:
# Instead of setting components[_BLANK] = 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 _BLANK in components:
del components[_BLANK]
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, _): #pragma NO COVER
class XXXTwistedFakeOut:
selfImplied = {}
return XXXTwistedFakeOut


_not_in_mapping = object()
class LookupBaseFallback(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=_BLANK, default=None):
cache = self._getcache(provided, name)
required = tuple(required)
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=_BLANK, 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=_BLANK, default=None):
return self.adapter_hook(provided, object, name, default)

def adapter_hook(self, provided, object, name=_BLANK, 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

LookupBasePy = LookupBaseFallback # BBB

try:
from _zope_interface_coptimizations import LookupBase
except ImportError: #pragma NO COVER
LookupBase = LookupBaseFallback


class VerifyingBaseFallback(LookupBaseFallback):
# Mixin for lookups against registries which "chain" upwards, and
# whose lookups invalidate their own caches whenever a parent registry
# bumps its own '_generation' counter. E.g., used by
# zope.component.persistentregistry

def changed(self, originally_changed):
LookupBaseFallback.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 LookupBaseFallback._getcache(self, provided, name)

def lookupAll(self, required, provided):
self._verify()
return LookupBaseFallback.lookupAll(self, required, provided)

def subscriptions(self, required, provided):
self._verify()
return LookupBaseFallback.subscriptions(self, required, provided)

VerifyingBasePy = VerifyingBaseFallback #BBB

try:
from _zope_interface_coptimizations import VerifyingBase
except ImportError: #pragma NO COVER
VerifyingBase = VerifyingBaseFallback


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=_BLANK):
required = tuple(required)
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=_BLANK, 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):
required = tuple(required)
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.items())

def names(self, required, provided):
return [c[0] for c in self.lookupAll(required, provided)]

def _uncached_subscriptions(self, required, provided):
required = tuple(required)
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, _BLANK,
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 _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)