shell bypass 403
曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.かつては雑草やヨモギと共に雨や露を分かち合っていたが、今では松やヒノキと共に霜や雪に耐えている。曾与蒿藜同雨露,Once sharing rain and dew with weeds and wormwood, now enduring frost and snow with pines and cypresses.终随松柏到冰霜.曾与蒿藜同雨露한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.,终随松柏到冰霜.譖セ荳手珍阯懷酔髮ィ髴イ�檎サ磯囂譚セ譟丞芦蜀ー髴�曾与蒿藜同雨露,鏇句笌钂胯棞鍚岄洦闇诧紝缁堥殢鏉炬煆鍒板啺闇�终随松柏到冰霜.曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.曾与蒿藜同雨露,终随松柏到冰霜.
##############################################################################
#
# 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)