/usr/share/pyshared/protocols/adapters.py is in python-protocols 1.0a.svn20070625-5build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | """Basic Adapters and Adapter Operations"""
__all__ = [
'NO_ADAPTER_NEEDED','DOES_NOT_SUPPORT', 'Adapter',
'minimumAdapter', 'composeAdapters', 'updateWithSimplestAdapter',
'StickyAdapter', 'AdaptationFailure', 'bindAdapter',
]
from types import FunctionType,ClassType,MethodType
try:
PendingDeprecationWarning
except NameError:
class PendingDeprecationWarning(Warning):
'Base class for warnings about features which will be deprecated in the future.'
class AdaptationFailure(NotImplementedError,TypeError):
"""A suitable implementation/adapter could not be found"""
# Fundamental Adapters
def NO_ADAPTER_NEEDED(obj, protocol=None):
"""Assume 'obj' implements 'protocol' directly"""
return obj
def DOES_NOT_SUPPORT(obj, protocol=None):
"""Prevent 'obj' from supporting 'protocol'"""
return None
try:
from _speedups import NO_ADAPTER_NEEDED, DOES_NOT_SUPPORT
except ImportError:
pass
class Adapter(object):
"""Convenient base class for adapters"""
def __init__(self, ob):
self.subject = ob
class StickyAdapter(object):
"""Adapter that attaches itself to its subject for repeated use"""
attachForProtocols = ()
def __init__(self, ob):
self.subject = ob
# Declare this instance as a per-instance adaptation for the
# given protocols
provides = list(self.attachForProtocols)
from protocols.api import declareAdapter
declareAdapter(lambda s: self, provides, forObjects=[ob])
# Adapter "arithmetic"
def minimumAdapter(a1,a2,d1=0,d2=0):
"""Shortest route to implementation, 'a1' @ depth 'd1', or 'a2' @ 'd2'?
Assuming both a1 and a2 are interchangeable adapters (i.e. have the same
source and destination protocols), return the one which is preferable; that
is, the one with the shortest implication depth, or, if the depths are
equal, then the adapter that is composed of the fewest chained adapters.
If both are the same, then prefer 'NO_ADAPTER_NEEDED', followed by
anything but 'DOES_NOT_SUPPORT', with 'DOES_NOT_SUPPORT' being least
preferable. If there is no unambiguous choice, and 'not a1 is a2',
TypeError is raised.
"""
if d1<d2:
return a1
elif d2<d1:
return a2
if getattr(a1,'__unbound_adapter__',a1) is getattr(a2,'__unbound_adapter__',a2):
return a1 # don't care which
a1ct = getattr(a1,'__adapterCount__',1)
a2ct = getattr(a2,'__adapterCount__',1)
if a1ct<a2ct:
return a1
elif a2ct<a1ct:
return a2
if a1 is NO_ADAPTER_NEEDED or a2 is DOES_NOT_SUPPORT:
return a1
if a1 is DOES_NOT_SUPPORT or a2 is NO_ADAPTER_NEEDED:
return a2
# it's ambiguous
raise TypeError("Ambiguous adapter choice", a1, a2, d1, d2)
def composeAdapters(baseAdapter, baseProtocol, extendingAdapter):
"""Return the composition of 'baseAdapter'+'extendingAdapter'"""
if baseAdapter is DOES_NOT_SUPPORT or extendingAdapter is DOES_NOT_SUPPORT:
# fuhgeddaboudit
return DOES_NOT_SUPPORT
if baseAdapter is NO_ADAPTER_NEEDED:
return extendingAdapter
if extendingAdapter is NO_ADAPTER_NEEDED:
return baseAdapter
def newAdapter(ob):
ob = baseAdapter(ob)
if ob is not None:
return extendingAdapter(ob)
newAdapter.__adapterCount__ = (
getattr(extendingAdapter,'__adapterCount__',1)+
getattr(baseAdapter,'__adapterCount__',1)
)
return newAdapter
def bindAdapter(adapter,proto):
"""Backward compatibility: wrap 'adapter' to support old 2-arg signature"""
maxargs = 2; f = adapter; tries = 10
while not isinstance(f,FunctionType) and tries:
if isinstance(f,MethodType):
maxargs += (f.im_self is not None)
f = f.im_func
tries = 10
elif isinstance(f,(ClassType,type)):
maxargs += 1
f = f.__init__
tries -=1
else:
f = f.__call__
tries -=1
if isinstance(f,FunctionType):
from inspect import getargspec
args, varargs, varkw, defaults = getargspec(f)
if defaults:
args = args[:-len(defaults)]
if len(args)>=maxargs:
newAdapter = lambda ob: adapter(ob,proto)
newAdapter.__adapterCount__ = getattr(
adapter,'__adapterCount__',1
)
newAdapter.__unbound_adapter__ = adapter
from warnings import warn
warn("Adapter %r to protocol %r needs multiple arguments"
% (adapter,proto), PendingDeprecationWarning, 6)
return newAdapter
return adapter
def updateWithSimplestAdapter(mapping, key, adapter, depth):
"""Replace 'mapping[key]' w/'adapter' @ 'depth', return true if changed"""
new = adapter
old = mapping.get(key)
if old is not None:
old, oldDepth = old
new = minimumAdapter(old,adapter,oldDepth,depth)
if old is new and depth>=oldDepth:
return False
mapping[key] = new, depth
return True
|