Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: third_party/twisted_8_1/twisted/python/components.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.python.test.test_components -*-
2
3 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6
7 """
8 Component architecture for Twisted, based on Zope3 components.
9
10 Using the Zope3 API directly is strongly recommended. Everything
11 you need is in the top-level of the zope.interface package, e.g.::
12
13 from zope.interface import Interface, implements
14
15 class IFoo(Interface):
16 pass
17
18 class Foo:
19 implements(IFoo)
20
21 print IFoo.implementedBy(Foo) # True
22 print IFoo.providedBy(Foo()) # True
23
24 The one exception is L{twisted.python.components.registerAdapter}, which is
25 still the way to register adapters (at least, if you want Twisted's global
26 adapter registry).
27 """
28
29 # twisted imports
30 from twisted.python import reflect
31 from twisted.persisted import styles
32
33 # system imports
34 import warnings
35
36 # zope3 imports
37 from zope.interface import directlyProvides, interface, declarations
38 from zope.interface.adapter import AdapterRegistry
39
40
41
42 class ComponentsDeprecationWarning(DeprecationWarning):
43 """Nothing emits this warning anymore."""
44 pass
45
46 # Twisted's global adapter registry
47 globalRegistry = AdapterRegistry()
48
49 # Attribute that registerAdapter looks at. Is this supposed to be public?
50 ALLOW_DUPLICATES = 0
51
52 # Define a function to find the registered adapter factory, using either a
53 # version of Zope Interface which has the `registered' method or an older
54 # version which does not.
55 if getattr(AdapterRegistry, 'registered', None) is None:
56 def _registered(registry, required, provided):
57 """
58 Return the adapter factory for the given parameters in the given
59 registry, or None if there is not one.
60 """
61 return registry.get(required).selfImplied.get(provided, {}).get('')
62 else:
63 def _registered(registry, required, provided):
64 """
65 Return the adapter factory for the given parameters in the given
66 registry, or None if there is not one.
67 """
68 return registry.registered([required], provided)
69
70
71 def registerAdapter(adapterFactory, origInterface, *interfaceClasses):
72 """Register an adapter class.
73
74 An adapter class is expected to implement the given interface, by
75 adapting instances implementing 'origInterface'. An adapter class's
76 __init__ method should accept one parameter, an instance implementing
77 'origInterface'.
78 """
79 self = globalRegistry
80 assert interfaceClasses, "You need to pass an Interface"
81 global ALLOW_DUPLICATES
82
83 # deal with class->interface adapters:
84 if not isinstance(origInterface, interface.InterfaceClass):
85 origInterface = declarations.implementedBy(origInterface)
86
87 for interfaceClass in interfaceClasses:
88 factory = _registered(self, origInterface, interfaceClass)
89 if factory is not None and not ALLOW_DUPLICATES:
90 raise ValueError("an adapter (%s) was already registered." % (factor y, ))
91 for interfaceClass in interfaceClasses:
92 self.register([origInterface], interfaceClass, '', adapterFactory)
93
94
95 def getAdapterFactory(fromInterface, toInterface, default):
96 """Return registered adapter for a given class and interface.
97
98 Note that is tied to the *Twisted* global registry, and will
99 thus not find adapters registered elsewhere.
100 """
101 self = globalRegistry
102 if not isinstance(fromInterface, interface.InterfaceClass):
103 fromInterface = declarations.implementedBy(fromInterface)
104 factory = self.lookup1(fromInterface, toInterface)
105 if factory is None:
106 factory = default
107 return factory
108
109
110 # add global adapter lookup hook for our newly created registry
111 def _hook(iface, ob, lookup=globalRegistry.lookup1):
112 factory = lookup(declarations.providedBy(ob), iface)
113 if factory is None:
114 return None
115 else:
116 return factory(ob)
117 interface.adapter_hooks.append(_hook)
118
119 ## backwardsCompatImplements and fixClassImplements should probably stick around for another
120 ## release cycle. No harm doing so in any case.
121
122 def backwardsCompatImplements(klass):
123 """DEPRECATED.
124
125 Does nothing. Previously handled backwards compat from a
126 zope.interface using class to a class wanting old twisted
127 components interface behaviors.
128 """
129 warnings.warn("components.backwardsCompatImplements doesn't do anything in T wisted 2.3, stop calling it.", ComponentsDeprecationWarning, stacklevel=2)
130
131 def fixClassImplements(klass):
132 """DEPRECATED.
133
134 Does nothing. Previously converted class from __implements__ to
135 zope implementation.
136 """
137 warnings.warn("components.fixClassImplements doesn't do anything in Twisted 2.3, stop calling it.", ComponentsDeprecationWarning, stacklevel=2)
138
139
140 def getRegistry():
141 """Returns the Twisted global
142 C{zope.interface.adapter.AdapterRegistry} instance.
143 """
144 return globalRegistry
145
146 # FIXME: deprecate attribute somehow?
147 CannotAdapt = TypeError
148
149 class Adapter:
150 """I am the default implementation of an Adapter for some interface.
151
152 This docstring contains a limerick, by popular demand::
153
154 Subclassing made Zope and TR
155 much harder to work with by far.
156 So before you inherit,
157 be sure to declare it
158 Adapter, not PyObject*
159
160 @cvar temporaryAdapter: If this is True, the adapter will not be
161 persisted on the Componentized.
162 @cvar multiComponent: If this adapter is persistent, should it be
163 automatically registered for all appropriate interfaces.
164 """
165
166 # These attributes are used with Componentized.
167
168 temporaryAdapter = 0
169 multiComponent = 1
170
171 def __init__(self, original):
172 """Set my 'original' attribute to be the object I am adapting.
173 """
174 self.original = original
175
176 def __conform__(self, interface):
177 """
178 I forward __conform__ to self.original if it has it, otherwise I
179 simply return None.
180 """
181 if hasattr(self.original, "__conform__"):
182 return self.original.__conform__(interface)
183 return None
184
185 def isuper(self, iface, adapter):
186 """
187 Forward isuper to self.original
188 """
189 return self.original.isuper(iface, adapter)
190
191
192 class Componentized(styles.Versioned):
193 """I am a mixin to allow you to be adapted in various ways persistently.
194
195 I define a list of persistent adapters. This is to allow adapter classes
196 to store system-specific state, and initialized on demand. The
197 getComponent method implements this. You must also register adapters for
198 this class for the interfaces that you wish to pass to getComponent.
199
200 Many other classes and utilities listed here are present in Zope3; this one
201 is specific to Twisted.
202 """
203
204 persistenceVersion = 1
205
206 def __init__(self):
207 self._adapterCache = {}
208
209 def locateAdapterClass(self, klass, interfaceClass, default):
210 return getAdapterFactory(klass, interfaceClass, default)
211
212 def setAdapter(self, interfaceClass, adapterClass):
213 self.setComponent(interfaceClass, adapterClass(self))
214
215 def addAdapter(self, adapterClass, ignoreClass=0):
216 """Utility method that calls addComponent. I take an adapter class and
217 instantiate it with myself as the first argument.
218
219 @return: The adapter instantiated.
220 """
221 adapt = adapterClass(self)
222 self.addComponent(adapt, ignoreClass)
223 return adapt
224
225 def setComponent(self, interfaceClass, component):
226 """
227 """
228 self._adapterCache[reflect.qual(interfaceClass)] = component
229
230 def addComponent(self, component, ignoreClass=0):
231 """
232 Add a component to me, for all appropriate interfaces.
233
234 In order to determine which interfaces are appropriate, the component's
235 provided interfaces will be scanned.
236
237 If the argument 'ignoreClass' is True, then all interfaces are
238 considered appropriate.
239
240 Otherwise, an 'appropriate' interface is one for which its class has
241 been registered as an adapter for my class according to the rules of
242 getComponent.
243
244 @return: the list of appropriate interfaces
245 """
246 for iface in declarations.providedBy(component):
247 if (ignoreClass or
248 (self.locateAdapterClass(self.__class__, iface, None)
249 == component.__class__)):
250 self._adapterCache[reflect.qual(iface)] = component
251
252 def unsetComponent(self, interfaceClass):
253 """Remove my component specified by the given interface class."""
254 del self._adapterCache[reflect.qual(interfaceClass)]
255
256 def removeComponent(self, component):
257 """
258 Remove the given component from me entirely, for all interfaces for whic h
259 it has been registered.
260
261 @return: a list of the interfaces that were removed.
262 """
263 l = []
264 for k, v in self._adapterCache.items():
265 if v is component:
266 del self._adapterCache[k]
267 l.append(reflect.namedObject(k))
268 return l
269
270 def getComponent(self, interface, default=None):
271 """Create or retrieve an adapter for the given interface.
272
273 If such an adapter has already been created, retrieve it from the cache
274 that this instance keeps of all its adapters. Adapters created through
275 this mechanism may safely store system-specific state.
276
277 If you want to register an adapter that will be created through
278 getComponent, but you don't require (or don't want) your adapter to be
279 cached and kept alive for the lifetime of this Componentized object,
280 set the attribute 'temporaryAdapter' to True on your adapter class.
281
282 If you want to automatically register an adapter for all appropriate
283 interfaces (with addComponent), set the attribute 'multiComponent' to
284 True on your adapter class.
285 """
286 k = reflect.qual(interface)
287 if self._adapterCache.has_key(k):
288 return self._adapterCache[k]
289 else:
290 adapter = interface.__adapt__(self)
291 if adapter is not None and not (
292 hasattr(adapter, "temporaryAdapter") and
293 adapter.temporaryAdapter):
294 self._adapterCache[k] = adapter
295 if (hasattr(adapter, "multiComponent") and
296 adapter.multiComponent):
297 self.addComponent(adapter)
298 if adapter is None:
299 return default
300 return adapter
301
302
303 def __conform__(self, interface):
304 return self.getComponent(interface)
305
306
307 class ReprableComponentized(Componentized):
308 def __init__(self):
309 Componentized.__init__(self)
310
311 def __repr__(self):
312 from cStringIO import StringIO
313 from pprint import pprint
314 sio = StringIO()
315 pprint(self._adapterCache, sio)
316 return sio.getvalue()
317
318
319
320 def proxyForInterface(iface, originalAttribute='original'):
321 """
322 Create a class which proxies all method calls which adhere to an interface
323 to another provider of that interface.
324
325 This function is intended for creating specialized proxies. The typical way
326 to use it is by subclassing the result::
327
328 class MySpecializedProxy(proxyForInterface(IFoo)):
329 def someInterfaceMethod(self, arg):
330 if arg == 3:
331 return 3
332 return self.original.someInterfaceMethod(arg)
333
334 @param iface: The Interface to which the resulting object will conform, and
335 which the wrapped object must provide.
336
337 @param originalAttribute: name of the attribute used to save the original
338 object in the resulting class. Default to C{original}.
339 @type originalAttribute: C{str}
340
341 @return: A class whose constructor takes the original object as its only
342 argument. Constructing the class creates the proxy.
343 """
344 def __init__(self, original):
345 setattr(self, originalAttribute, original)
346 contents = {"__init__": __init__}
347 for name in iface:
348 contents[name] = _ProxyDescriptor(name, originalAttribute)
349 proxy = type("(Proxy for %s)"
350 % (reflect.qual(iface),), (object,), contents)
351 directlyProvides(proxy, iface)
352 return proxy
353
354
355
356 class _ProxiedClassMethod(object):
357 """
358 A proxied class method.
359
360 @ivar methodName: the name of the method which this should invoke when
361 called.
362 @type methodName: C{str}
363
364 @ivar originalAttribute: name of the attribute of the proxy where the
365 original object is stored.
366 @type orginalAttribute: C{str}
367 """
368 def __init__(self, methodName, originalAttribute):
369 self.methodName = methodName
370 self.originalAttribute = originalAttribute
371
372
373 def __call__(self, oself, *args, **kw):
374 """
375 Invoke the specified L{methodName} method of the C{original} attribute
376 for proxyForInterface.
377
378 @param oself: an instance of a L{proxyForInterface} object.
379
380 @return: the result of the underlying method.
381 """
382 original = getattr(oself, self.originalAttribute)
383 actualMethod = getattr(original, self.methodName)
384 return actualMethod(*args, **kw)
385
386
387
388 class _ProxyDescriptor(object):
389 """
390 A descriptor which will proxy attribute access, mutation, and
391 deletion to the L{original} attribute of the object it is being accessed
392 from.
393
394 @ivar attributeName: the name of the attribute which this descriptor will
395 retrieve from instances' C{original} attribute.
396 @type attributeName: C{str}
397
398 @ivar originalAttribute: name of the attribute of the proxy where the
399 original object is stored.
400 @type orginalAttribute: C{str}
401 """
402 def __init__(self, attributeName, originalAttribute):
403 self.attributeName = attributeName
404 self.originalAttribute = originalAttribute
405
406
407 def __get__(self, oself, type=None):
408 """
409 Retrieve the C{self.attributeName} property from L{oself}.
410 """
411 if oself is None:
412 return _ProxiedClassMethod(self.attributeName,
413 self.originalAttribute)
414 original = getattr(oself, self.originalAttribute)
415 return getattr(original, self.attributeName)
416
417
418 def __set__(self, oself, value):
419 """
420 Set the C{self.attributeName} property of L{oself}.
421 """
422 original = getattr(oself, self.originalAttribute)
423 setattr(original, self.attributeName, value)
424
425
426 def __delete__(self, oself):
427 """
428 Delete the C{self.attributeName} property of L{oself}.
429 """
430 original = getattr(oself, self.originalAttribute)
431 delattr(original, self.attributeName)
432
433
434
435 __all__ = [
436 # Sticking around:
437 "ComponentsDeprecationWarning",
438 "registerAdapter", "getAdapterFactory",
439 "Adapter", "Componentized", "ReprableComponentized", "getRegistry",
440 "proxyForInterface",
441
442 # Deprecated:
443 "backwardsCompatImplements",
444 "fixClassImplements",
445 ]
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/python/compat.py ('k') | third_party/twisted_8_1/twisted/python/context.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698