##// END OF EJS Templates
thirdparty: allow zope.interface.advice to be lazily imported...
Gregory Szorc -
r37196:49630e75 default
parent child Browse files
Show More
@@ -1,931 +1,931 b''
1 ##############################################################################
1 ##############################################################################
2 # Copyright (c) 2003 Zope Foundation and Contributors.
2 # Copyright (c) 2003 Zope Foundation and Contributors.
3 # All Rights Reserved.
3 # All Rights Reserved.
4 #
4 #
5 # This software is subject to the provisions of the Zope Public License,
5 # This software is subject to the provisions of the Zope Public License,
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10 # FOR A PARTICULAR PURPOSE.
10 # FOR A PARTICULAR PURPOSE.
11 ##############################################################################
11 ##############################################################################
12 """Implementation of interface declarations
12 """Implementation of interface declarations
13
13
14 There are three flavors of declarations:
14 There are three flavors of declarations:
15
15
16 - Declarations are used to simply name declared interfaces.
16 - Declarations are used to simply name declared interfaces.
17
17
18 - ImplementsDeclarations are used to express the interfaces that a
18 - ImplementsDeclarations are used to express the interfaces that a
19 class implements (that instances of the class provides).
19 class implements (that instances of the class provides).
20
20
21 Implements specifications support inheriting interfaces.
21 Implements specifications support inheriting interfaces.
22
22
23 - ProvidesDeclarations are used to express interfaces directly
23 - ProvidesDeclarations are used to express interfaces directly
24 provided by objects.
24 provided by objects.
25
25
26 """
26 """
27 from __future__ import absolute_import
27 from __future__ import absolute_import
28
28
29 __docformat__ = 'restructuredtext'
29 __docformat__ = 'restructuredtext'
30
30
31 import sys
31 import sys
32 from types import FunctionType
32 from types import FunctionType
33 from types import MethodType
33 from types import MethodType
34 from types import ModuleType
34 from types import ModuleType
35 import weakref
35 import weakref
36
36
37 from .advice import addClassAdvisor
37 from . import advice as advicemod
38 from .interface import InterfaceClass
38 from .interface import InterfaceClass
39 from .interface import SpecificationBase
39 from .interface import SpecificationBase
40 from .interface import Specification
40 from .interface import Specification
41 from ._compat import CLASS_TYPES as DescriptorAwareMetaClasses
41 from ._compat import CLASS_TYPES as DescriptorAwareMetaClasses
42 from ._compat import PYTHON3
42 from ._compat import PYTHON3
43
43
44 # Registry of class-implementation specifications
44 # Registry of class-implementation specifications
45 BuiltinImplementationSpecifications = {}
45 BuiltinImplementationSpecifications = {}
46
46
47 _ADVICE_ERROR = ('Class advice impossible in Python3. '
47 _ADVICE_ERROR = ('Class advice impossible in Python3. '
48 'Use the @%s class decorator instead.')
48 'Use the @%s class decorator instead.')
49
49
50 _ADVICE_WARNING = ('The %s API is deprecated, and will not work in Python3 '
50 _ADVICE_WARNING = ('The %s API is deprecated, and will not work in Python3 '
51 'Use the @%s class decorator instead.')
51 'Use the @%s class decorator instead.')
52
52
53 class named(object):
53 class named(object):
54
54
55 def __init__(self, name):
55 def __init__(self, name):
56 self.name = name
56 self.name = name
57
57
58 def __call__(self, ob):
58 def __call__(self, ob):
59 ob.__component_name__ = self.name
59 ob.__component_name__ = self.name
60 return ob
60 return ob
61
61
62 class Declaration(Specification):
62 class Declaration(Specification):
63 """Interface declarations"""
63 """Interface declarations"""
64
64
65 def __init__(self, *interfaces):
65 def __init__(self, *interfaces):
66 Specification.__init__(self, _normalizeargs(interfaces))
66 Specification.__init__(self, _normalizeargs(interfaces))
67
67
68 def changed(self, originally_changed):
68 def changed(self, originally_changed):
69 Specification.changed(self, originally_changed)
69 Specification.changed(self, originally_changed)
70 try:
70 try:
71 del self._v_attrs
71 del self._v_attrs
72 except AttributeError:
72 except AttributeError:
73 pass
73 pass
74
74
75 def __contains__(self, interface):
75 def __contains__(self, interface):
76 """Test whether an interface is in the specification
76 """Test whether an interface is in the specification
77 """
77 """
78
78
79 return self.extends(interface) and interface in self.interfaces()
79 return self.extends(interface) and interface in self.interfaces()
80
80
81 def __iter__(self):
81 def __iter__(self):
82 """Return an iterator for the interfaces in the specification
82 """Return an iterator for the interfaces in the specification
83 """
83 """
84 return self.interfaces()
84 return self.interfaces()
85
85
86 def flattened(self):
86 def flattened(self):
87 """Return an iterator of all included and extended interfaces
87 """Return an iterator of all included and extended interfaces
88 """
88 """
89 return iter(self.__iro__)
89 return iter(self.__iro__)
90
90
91 def __sub__(self, other):
91 def __sub__(self, other):
92 """Remove interfaces from a specification
92 """Remove interfaces from a specification
93 """
93 """
94 return Declaration(
94 return Declaration(
95 *[i for i in self.interfaces()
95 *[i for i in self.interfaces()
96 if not [j for j in other.interfaces()
96 if not [j for j in other.interfaces()
97 if i.extends(j, 0)]
97 if i.extends(j, 0)]
98 ]
98 ]
99 )
99 )
100
100
101 def __add__(self, other):
101 def __add__(self, other):
102 """Add two specifications or a specification and an interface
102 """Add two specifications or a specification and an interface
103 """
103 """
104 seen = {}
104 seen = {}
105 result = []
105 result = []
106 for i in self.interfaces():
106 for i in self.interfaces():
107 seen[i] = 1
107 seen[i] = 1
108 result.append(i)
108 result.append(i)
109 for i in other.interfaces():
109 for i in other.interfaces():
110 if i not in seen:
110 if i not in seen:
111 seen[i] = 1
111 seen[i] = 1
112 result.append(i)
112 result.append(i)
113
113
114 return Declaration(*result)
114 return Declaration(*result)
115
115
116 __radd__ = __add__
116 __radd__ = __add__
117
117
118
118
119 ##############################################################################
119 ##############################################################################
120 #
120 #
121 # Implementation specifications
121 # Implementation specifications
122 #
122 #
123 # These specify interfaces implemented by instances of classes
123 # These specify interfaces implemented by instances of classes
124
124
125 class Implements(Declaration):
125 class Implements(Declaration):
126
126
127 # class whose specification should be used as additional base
127 # class whose specification should be used as additional base
128 inherit = None
128 inherit = None
129
129
130 # interfaces actually declared for a class
130 # interfaces actually declared for a class
131 declared = ()
131 declared = ()
132
132
133 __name__ = '?'
133 __name__ = '?'
134
134
135 @classmethod
135 @classmethod
136 def named(cls, name, *interfaces):
136 def named(cls, name, *interfaces):
137 # Implementation method: Produce an Implements interface with
137 # Implementation method: Produce an Implements interface with
138 # a fully fleshed out __name__ before calling the constructor, which
138 # a fully fleshed out __name__ before calling the constructor, which
139 # sets bases to the given interfaces and which may pass this object to
139 # sets bases to the given interfaces and which may pass this object to
140 # other objects (e.g., to adjust dependents). If they're sorting or comparing
140 # other objects (e.g., to adjust dependents). If they're sorting or comparing
141 # by name, this needs to be set.
141 # by name, this needs to be set.
142 inst = cls.__new__(cls)
142 inst = cls.__new__(cls)
143 inst.__name__ = name
143 inst.__name__ = name
144 inst.__init__(*interfaces)
144 inst.__init__(*interfaces)
145 return inst
145 return inst
146
146
147 def __repr__(self):
147 def __repr__(self):
148 return '<implementedBy %s>' % (self.__name__)
148 return '<implementedBy %s>' % (self.__name__)
149
149
150 def __reduce__(self):
150 def __reduce__(self):
151 return implementedBy, (self.inherit, )
151 return implementedBy, (self.inherit, )
152
152
153 def __cmp(self, other):
153 def __cmp(self, other):
154 # Yes, I did mean to name this __cmp, rather than __cmp__.
154 # Yes, I did mean to name this __cmp, rather than __cmp__.
155 # It is a private method used by __lt__ and __gt__.
155 # It is a private method used by __lt__ and __gt__.
156 # This is based on, and compatible with, InterfaceClass.
156 # This is based on, and compatible with, InterfaceClass.
157 # (The two must be mutually comparable to be able to work in e.g., BTrees.)
157 # (The two must be mutually comparable to be able to work in e.g., BTrees.)
158 # Instances of this class generally don't have a __module__ other than
158 # Instances of this class generally don't have a __module__ other than
159 # `zope.interface.declarations`, whereas they *do* have a __name__ that is the
159 # `zope.interface.declarations`, whereas they *do* have a __name__ that is the
160 # fully qualified name of the object they are representing.
160 # fully qualified name of the object they are representing.
161
161
162 # Note, though, that equality and hashing are still identity based. This
162 # Note, though, that equality and hashing are still identity based. This
163 # accounts for things like nested objects that have the same name (typically
163 # accounts for things like nested objects that have the same name (typically
164 # only in tests) and is consistent with pickling. As far as comparisons to InterfaceClass
164 # only in tests) and is consistent with pickling. As far as comparisons to InterfaceClass
165 # goes, we'll never have equal name and module to those, so we're still consistent there.
165 # goes, we'll never have equal name and module to those, so we're still consistent there.
166 # Instances of this class are essentially intended to be unique and are
166 # Instances of this class are essentially intended to be unique and are
167 # heavily cached (note how our __reduce__ handles this) so having identity
167 # heavily cached (note how our __reduce__ handles this) so having identity
168 # based hash and eq should also work.
168 # based hash and eq should also work.
169 if other is None:
169 if other is None:
170 return -1
170 return -1
171
171
172 n1 = (self.__name__, self.__module__)
172 n1 = (self.__name__, self.__module__)
173 n2 = (getattr(other, '__name__', ''), getattr(other, '__module__', ''))
173 n2 = (getattr(other, '__name__', ''), getattr(other, '__module__', ''))
174
174
175 # This spelling works under Python3, which doesn't have cmp().
175 # This spelling works under Python3, which doesn't have cmp().
176 return (n1 > n2) - (n1 < n2)
176 return (n1 > n2) - (n1 < n2)
177
177
178 def __hash__(self):
178 def __hash__(self):
179 return Declaration.__hash__(self)
179 return Declaration.__hash__(self)
180
180
181 # We want equality to be based on identity. However, we can't actually
181 # We want equality to be based on identity. However, we can't actually
182 # implement __eq__/__ne__ to do this because sometimes we get wrapped in a proxy.
182 # implement __eq__/__ne__ to do this because sometimes we get wrapped in a proxy.
183 # We need to let the proxy types implement these methods so they can handle unwrapping
183 # We need to let the proxy types implement these methods so they can handle unwrapping
184 # and then rely on: (1) the interpreter automatically changing `implements == proxy` into
184 # and then rely on: (1) the interpreter automatically changing `implements == proxy` into
185 # `proxy == implements` (which will call proxy.__eq__ to do the unwrapping) and then
185 # `proxy == implements` (which will call proxy.__eq__ to do the unwrapping) and then
186 # (2) the default equality semantics being identity based.
186 # (2) the default equality semantics being identity based.
187
187
188 def __lt__(self, other):
188 def __lt__(self, other):
189 c = self.__cmp(other)
189 c = self.__cmp(other)
190 return c < 0
190 return c < 0
191
191
192 def __le__(self, other):
192 def __le__(self, other):
193 c = self.__cmp(other)
193 c = self.__cmp(other)
194 return c <= 0
194 return c <= 0
195
195
196 def __gt__(self, other):
196 def __gt__(self, other):
197 c = self.__cmp(other)
197 c = self.__cmp(other)
198 return c > 0
198 return c > 0
199
199
200 def __ge__(self, other):
200 def __ge__(self, other):
201 c = self.__cmp(other)
201 c = self.__cmp(other)
202 return c >= 0
202 return c >= 0
203
203
204 def _implements_name(ob):
204 def _implements_name(ob):
205 # Return the __name__ attribute to be used by its __implemented__
205 # Return the __name__ attribute to be used by its __implemented__
206 # property.
206 # property.
207 # This must be stable for the "same" object across processes
207 # This must be stable for the "same" object across processes
208 # because it is used for sorting. It needn't be unique, though, in cases
208 # because it is used for sorting. It needn't be unique, though, in cases
209 # like nested classes named Foo created by different functions, because
209 # like nested classes named Foo created by different functions, because
210 # equality and hashing is still based on identity.
210 # equality and hashing is still based on identity.
211 # It might be nice to use __qualname__ on Python 3, but that would produce
211 # It might be nice to use __qualname__ on Python 3, but that would produce
212 # different values between Py2 and Py3.
212 # different values between Py2 and Py3.
213 return (getattr(ob, '__module__', '?') or '?') + \
213 return (getattr(ob, '__module__', '?') or '?') + \
214 '.' + (getattr(ob, '__name__', '?') or '?')
214 '.' + (getattr(ob, '__name__', '?') or '?')
215
215
216 def implementedByFallback(cls):
216 def implementedByFallback(cls):
217 """Return the interfaces implemented for a class' instances
217 """Return the interfaces implemented for a class' instances
218
218
219 The value returned is an IDeclaration.
219 The value returned is an IDeclaration.
220 """
220 """
221 try:
221 try:
222 spec = cls.__dict__.get('__implemented__')
222 spec = cls.__dict__.get('__implemented__')
223 except AttributeError:
223 except AttributeError:
224
224
225 # we can't get the class dict. This is probably due to a
225 # we can't get the class dict. This is probably due to a
226 # security proxy. If this is the case, then probably no
226 # security proxy. If this is the case, then probably no
227 # descriptor was installed for the class.
227 # descriptor was installed for the class.
228
228
229 # We don't want to depend directly on zope.security in
229 # We don't want to depend directly on zope.security in
230 # zope.interface, but we'll try to make reasonable
230 # zope.interface, but we'll try to make reasonable
231 # accommodations in an indirect way.
231 # accommodations in an indirect way.
232
232
233 # We'll check to see if there's an implements:
233 # We'll check to see if there's an implements:
234
234
235 spec = getattr(cls, '__implemented__', None)
235 spec = getattr(cls, '__implemented__', None)
236 if spec is None:
236 if spec is None:
237 # There's no spec stred in the class. Maybe its a builtin:
237 # There's no spec stred in the class. Maybe its a builtin:
238 spec = BuiltinImplementationSpecifications.get(cls)
238 spec = BuiltinImplementationSpecifications.get(cls)
239 if spec is not None:
239 if spec is not None:
240 return spec
240 return spec
241 return _empty
241 return _empty
242
242
243 if spec.__class__ == Implements:
243 if spec.__class__ == Implements:
244 # we defaulted to _empty or there was a spec. Good enough.
244 # we defaulted to _empty or there was a spec. Good enough.
245 # Return it.
245 # Return it.
246 return spec
246 return spec
247
247
248 # TODO: need old style __implements__ compatibility?
248 # TODO: need old style __implements__ compatibility?
249 # Hm, there's an __implemented__, but it's not a spec. Must be
249 # Hm, there's an __implemented__, but it's not a spec. Must be
250 # an old-style declaration. Just compute a spec for it
250 # an old-style declaration. Just compute a spec for it
251 return Declaration(*_normalizeargs((spec, )))
251 return Declaration(*_normalizeargs((spec, )))
252
252
253 if isinstance(spec, Implements):
253 if isinstance(spec, Implements):
254 return spec
254 return spec
255
255
256 if spec is None:
256 if spec is None:
257 spec = BuiltinImplementationSpecifications.get(cls)
257 spec = BuiltinImplementationSpecifications.get(cls)
258 if spec is not None:
258 if spec is not None:
259 return spec
259 return spec
260
260
261 # TODO: need old style __implements__ compatibility?
261 # TODO: need old style __implements__ compatibility?
262 spec_name = _implements_name(cls)
262 spec_name = _implements_name(cls)
263 if spec is not None:
263 if spec is not None:
264 # old-style __implemented__ = foo declaration
264 # old-style __implemented__ = foo declaration
265 spec = (spec, ) # tuplefy, as it might be just an int
265 spec = (spec, ) # tuplefy, as it might be just an int
266 spec = Implements.named(spec_name, *_normalizeargs(spec))
266 spec = Implements.named(spec_name, *_normalizeargs(spec))
267 spec.inherit = None # old-style implies no inherit
267 spec.inherit = None # old-style implies no inherit
268 del cls.__implemented__ # get rid of the old-style declaration
268 del cls.__implemented__ # get rid of the old-style declaration
269 else:
269 else:
270 try:
270 try:
271 bases = cls.__bases__
271 bases = cls.__bases__
272 except AttributeError:
272 except AttributeError:
273 if not callable(cls):
273 if not callable(cls):
274 raise TypeError("ImplementedBy called for non-factory", cls)
274 raise TypeError("ImplementedBy called for non-factory", cls)
275 bases = ()
275 bases = ()
276
276
277 spec = Implements.named(spec_name, *[implementedBy(c) for c in bases])
277 spec = Implements.named(spec_name, *[implementedBy(c) for c in bases])
278 spec.inherit = cls
278 spec.inherit = cls
279
279
280 try:
280 try:
281 cls.__implemented__ = spec
281 cls.__implemented__ = spec
282 if not hasattr(cls, '__providedBy__'):
282 if not hasattr(cls, '__providedBy__'):
283 cls.__providedBy__ = objectSpecificationDescriptor
283 cls.__providedBy__ = objectSpecificationDescriptor
284
284
285 if (isinstance(cls, DescriptorAwareMetaClasses)
285 if (isinstance(cls, DescriptorAwareMetaClasses)
286 and
286 and
287 '__provides__' not in cls.__dict__):
287 '__provides__' not in cls.__dict__):
288 # Make sure we get a __provides__ descriptor
288 # Make sure we get a __provides__ descriptor
289 cls.__provides__ = ClassProvides(
289 cls.__provides__ = ClassProvides(
290 cls,
290 cls,
291 getattr(cls, '__class__', type(cls)),
291 getattr(cls, '__class__', type(cls)),
292 )
292 )
293
293
294 except TypeError:
294 except TypeError:
295 if not isinstance(cls, type):
295 if not isinstance(cls, type):
296 raise TypeError("ImplementedBy called for non-type", cls)
296 raise TypeError("ImplementedBy called for non-type", cls)
297 BuiltinImplementationSpecifications[cls] = spec
297 BuiltinImplementationSpecifications[cls] = spec
298
298
299 return spec
299 return spec
300
300
301 implementedBy = implementedByFallback
301 implementedBy = implementedByFallback
302
302
303 def classImplementsOnly(cls, *interfaces):
303 def classImplementsOnly(cls, *interfaces):
304 """Declare the only interfaces implemented by instances of a class
304 """Declare the only interfaces implemented by instances of a class
305
305
306 The arguments after the class are one or more interfaces or interface
306 The arguments after the class are one or more interfaces or interface
307 specifications (``IDeclaration`` objects).
307 specifications (``IDeclaration`` objects).
308
308
309 The interfaces given (including the interfaces in the specifications)
309 The interfaces given (including the interfaces in the specifications)
310 replace any previous declarations.
310 replace any previous declarations.
311 """
311 """
312 spec = implementedBy(cls)
312 spec = implementedBy(cls)
313 spec.declared = ()
313 spec.declared = ()
314 spec.inherit = None
314 spec.inherit = None
315 classImplements(cls, *interfaces)
315 classImplements(cls, *interfaces)
316
316
317 def classImplements(cls, *interfaces):
317 def classImplements(cls, *interfaces):
318 """Declare additional interfaces implemented for instances of a class
318 """Declare additional interfaces implemented for instances of a class
319
319
320 The arguments after the class are one or more interfaces or
320 The arguments after the class are one or more interfaces or
321 interface specifications (``IDeclaration`` objects).
321 interface specifications (``IDeclaration`` objects).
322
322
323 The interfaces given (including the interfaces in the specifications)
323 The interfaces given (including the interfaces in the specifications)
324 are added to any interfaces previously declared.
324 are added to any interfaces previously declared.
325 """
325 """
326 spec = implementedBy(cls)
326 spec = implementedBy(cls)
327 spec.declared += tuple(_normalizeargs(interfaces))
327 spec.declared += tuple(_normalizeargs(interfaces))
328
328
329 # compute the bases
329 # compute the bases
330 bases = []
330 bases = []
331 seen = {}
331 seen = {}
332 for b in spec.declared:
332 for b in spec.declared:
333 if b not in seen:
333 if b not in seen:
334 seen[b] = 1
334 seen[b] = 1
335 bases.append(b)
335 bases.append(b)
336
336
337 if spec.inherit is not None:
337 if spec.inherit is not None:
338
338
339 for c in spec.inherit.__bases__:
339 for c in spec.inherit.__bases__:
340 b = implementedBy(c)
340 b = implementedBy(c)
341 if b not in seen:
341 if b not in seen:
342 seen[b] = 1
342 seen[b] = 1
343 bases.append(b)
343 bases.append(b)
344
344
345 spec.__bases__ = tuple(bases)
345 spec.__bases__ = tuple(bases)
346
346
347 def _implements_advice(cls):
347 def _implements_advice(cls):
348 interfaces, classImplements = cls.__dict__['__implements_advice_data__']
348 interfaces, classImplements = cls.__dict__['__implements_advice_data__']
349 del cls.__implements_advice_data__
349 del cls.__implements_advice_data__
350 classImplements(cls, *interfaces)
350 classImplements(cls, *interfaces)
351 return cls
351 return cls
352
352
353
353
354 class implementer:
354 class implementer:
355 """Declare the interfaces implemented by instances of a class.
355 """Declare the interfaces implemented by instances of a class.
356
356
357 This function is called as a class decorator.
357 This function is called as a class decorator.
358
358
359 The arguments are one or more interfaces or interface
359 The arguments are one or more interfaces or interface
360 specifications (IDeclaration objects).
360 specifications (IDeclaration objects).
361
361
362 The interfaces given (including the interfaces in the
362 The interfaces given (including the interfaces in the
363 specifications) are added to any interfaces previously
363 specifications) are added to any interfaces previously
364 declared.
364 declared.
365
365
366 Previous declarations include declarations for base classes
366 Previous declarations include declarations for base classes
367 unless implementsOnly was used.
367 unless implementsOnly was used.
368
368
369 This function is provided for convenience. It provides a more
369 This function is provided for convenience. It provides a more
370 convenient way to call classImplements. For example::
370 convenient way to call classImplements. For example::
371
371
372 @implementer(I1)
372 @implementer(I1)
373 class C(object):
373 class C(object):
374 pass
374 pass
375
375
376 is equivalent to calling::
376 is equivalent to calling::
377
377
378 classImplements(C, I1)
378 classImplements(C, I1)
379
379
380 after the class has been created.
380 after the class has been created.
381 """
381 """
382
382
383 def __init__(self, *interfaces):
383 def __init__(self, *interfaces):
384 self.interfaces = interfaces
384 self.interfaces = interfaces
385
385
386 def __call__(self, ob):
386 def __call__(self, ob):
387 if isinstance(ob, DescriptorAwareMetaClasses):
387 if isinstance(ob, DescriptorAwareMetaClasses):
388 classImplements(ob, *self.interfaces)
388 classImplements(ob, *self.interfaces)
389 return ob
389 return ob
390
390
391 spec_name = _implements_name(ob)
391 spec_name = _implements_name(ob)
392 spec = Implements.named(spec_name, *self.interfaces)
392 spec = Implements.named(spec_name, *self.interfaces)
393 try:
393 try:
394 ob.__implemented__ = spec
394 ob.__implemented__ = spec
395 except AttributeError:
395 except AttributeError:
396 raise TypeError("Can't declare implements", ob)
396 raise TypeError("Can't declare implements", ob)
397 return ob
397 return ob
398
398
399 class implementer_only:
399 class implementer_only:
400 """Declare the only interfaces implemented by instances of a class
400 """Declare the only interfaces implemented by instances of a class
401
401
402 This function is called as a class decorator.
402 This function is called as a class decorator.
403
403
404 The arguments are one or more interfaces or interface
404 The arguments are one or more interfaces or interface
405 specifications (IDeclaration objects).
405 specifications (IDeclaration objects).
406
406
407 Previous declarations including declarations for base classes
407 Previous declarations including declarations for base classes
408 are overridden.
408 are overridden.
409
409
410 This function is provided for convenience. It provides a more
410 This function is provided for convenience. It provides a more
411 convenient way to call classImplementsOnly. For example::
411 convenient way to call classImplementsOnly. For example::
412
412
413 @implementer_only(I1)
413 @implementer_only(I1)
414 class C(object): pass
414 class C(object): pass
415
415
416 is equivalent to calling::
416 is equivalent to calling::
417
417
418 classImplementsOnly(I1)
418 classImplementsOnly(I1)
419
419
420 after the class has been created.
420 after the class has been created.
421 """
421 """
422
422
423 def __init__(self, *interfaces):
423 def __init__(self, *interfaces):
424 self.interfaces = interfaces
424 self.interfaces = interfaces
425
425
426 def __call__(self, ob):
426 def __call__(self, ob):
427 if isinstance(ob, (FunctionType, MethodType)):
427 if isinstance(ob, (FunctionType, MethodType)):
428 # XXX Does this decorator make sense for anything but classes?
428 # XXX Does this decorator make sense for anything but classes?
429 # I don't think so. There can be no inheritance of interfaces
429 # I don't think so. There can be no inheritance of interfaces
430 # on a method pr function....
430 # on a method pr function....
431 raise ValueError('The implementer_only decorator is not '
431 raise ValueError('The implementer_only decorator is not '
432 'supported for methods or functions.')
432 'supported for methods or functions.')
433 else:
433 else:
434 # Assume it's a class:
434 # Assume it's a class:
435 classImplementsOnly(ob, *self.interfaces)
435 classImplementsOnly(ob, *self.interfaces)
436 return ob
436 return ob
437
437
438 def _implements(name, interfaces, classImplements):
438 def _implements(name, interfaces, classImplements):
439 # This entire approach is invalid under Py3K. Don't even try to fix
439 # This entire approach is invalid under Py3K. Don't even try to fix
440 # the coverage for this block there. :(
440 # the coverage for this block there. :(
441 frame = sys._getframe(2)
441 frame = sys._getframe(2)
442 locals = frame.f_locals
442 locals = frame.f_locals
443
443
444 # Try to make sure we were called from a class def. In 2.2.0 we can't
444 # Try to make sure we were called from a class def. In 2.2.0 we can't
445 # check for __module__ since it doesn't seem to be added to the locals
445 # check for __module__ since it doesn't seem to be added to the locals
446 # until later on.
446 # until later on.
447 if locals is frame.f_globals or '__module__' not in locals:
447 if locals is frame.f_globals or '__module__' not in locals:
448 raise TypeError(name+" can be used only from a class definition.")
448 raise TypeError(name+" can be used only from a class definition.")
449
449
450 if '__implements_advice_data__' in locals:
450 if '__implements_advice_data__' in locals:
451 raise TypeError(name+" can be used only once in a class definition.")
451 raise TypeError(name+" can be used only once in a class definition.")
452
452
453 locals['__implements_advice_data__'] = interfaces, classImplements
453 locals['__implements_advice_data__'] = interfaces, classImplements
454 addClassAdvisor(_implements_advice, depth=3)
454 advicemod.addClassAdvisor(_implements_advice, depth=3)
455
455
456 def implements(*interfaces):
456 def implements(*interfaces):
457 """Declare interfaces implemented by instances of a class
457 """Declare interfaces implemented by instances of a class
458
458
459 This function is called in a class definition.
459 This function is called in a class definition.
460
460
461 The arguments are one or more interfaces or interface
461 The arguments are one or more interfaces or interface
462 specifications (IDeclaration objects).
462 specifications (IDeclaration objects).
463
463
464 The interfaces given (including the interfaces in the
464 The interfaces given (including the interfaces in the
465 specifications) are added to any interfaces previously
465 specifications) are added to any interfaces previously
466 declared.
466 declared.
467
467
468 Previous declarations include declarations for base classes
468 Previous declarations include declarations for base classes
469 unless implementsOnly was used.
469 unless implementsOnly was used.
470
470
471 This function is provided for convenience. It provides a more
471 This function is provided for convenience. It provides a more
472 convenient way to call classImplements. For example::
472 convenient way to call classImplements. For example::
473
473
474 implements(I1)
474 implements(I1)
475
475
476 is equivalent to calling::
476 is equivalent to calling::
477
477
478 classImplements(C, I1)
478 classImplements(C, I1)
479
479
480 after the class has been created.
480 after the class has been created.
481 """
481 """
482 # This entire approach is invalid under Py3K. Don't even try to fix
482 # This entire approach is invalid under Py3K. Don't even try to fix
483 # the coverage for this block there. :(
483 # the coverage for this block there. :(
484 if PYTHON3:
484 if PYTHON3:
485 raise TypeError(_ADVICE_ERROR % 'implementer')
485 raise TypeError(_ADVICE_ERROR % 'implementer')
486 _implements("implements", interfaces, classImplements)
486 _implements("implements", interfaces, classImplements)
487
487
488 def implementsOnly(*interfaces):
488 def implementsOnly(*interfaces):
489 """Declare the only interfaces implemented by instances of a class
489 """Declare the only interfaces implemented by instances of a class
490
490
491 This function is called in a class definition.
491 This function is called in a class definition.
492
492
493 The arguments are one or more interfaces or interface
493 The arguments are one or more interfaces or interface
494 specifications (IDeclaration objects).
494 specifications (IDeclaration objects).
495
495
496 Previous declarations including declarations for base classes
496 Previous declarations including declarations for base classes
497 are overridden.
497 are overridden.
498
498
499 This function is provided for convenience. It provides a more
499 This function is provided for convenience. It provides a more
500 convenient way to call classImplementsOnly. For example::
500 convenient way to call classImplementsOnly. For example::
501
501
502 implementsOnly(I1)
502 implementsOnly(I1)
503
503
504 is equivalent to calling::
504 is equivalent to calling::
505
505
506 classImplementsOnly(I1)
506 classImplementsOnly(I1)
507
507
508 after the class has been created.
508 after the class has been created.
509 """
509 """
510 # This entire approach is invalid under Py3K. Don't even try to fix
510 # This entire approach is invalid under Py3K. Don't even try to fix
511 # the coverage for this block there. :(
511 # the coverage for this block there. :(
512 if PYTHON3:
512 if PYTHON3:
513 raise TypeError(_ADVICE_ERROR % 'implementer_only')
513 raise TypeError(_ADVICE_ERROR % 'implementer_only')
514 _implements("implementsOnly", interfaces, classImplementsOnly)
514 _implements("implementsOnly", interfaces, classImplementsOnly)
515
515
516 ##############################################################################
516 ##############################################################################
517 #
517 #
518 # Instance declarations
518 # Instance declarations
519
519
520 class Provides(Declaration): # Really named ProvidesClass
520 class Provides(Declaration): # Really named ProvidesClass
521 """Implement __provides__, the instance-specific specification
521 """Implement __provides__, the instance-specific specification
522
522
523 When an object is pickled, we pickle the interfaces that it implements.
523 When an object is pickled, we pickle the interfaces that it implements.
524 """
524 """
525
525
526 def __init__(self, cls, *interfaces):
526 def __init__(self, cls, *interfaces):
527 self.__args = (cls, ) + interfaces
527 self.__args = (cls, ) + interfaces
528 self._cls = cls
528 self._cls = cls
529 Declaration.__init__(self, *(interfaces + (implementedBy(cls), )))
529 Declaration.__init__(self, *(interfaces + (implementedBy(cls), )))
530
530
531 def __reduce__(self):
531 def __reduce__(self):
532 return Provides, self.__args
532 return Provides, self.__args
533
533
534 __module__ = 'zope.interface'
534 __module__ = 'zope.interface'
535
535
536 def __get__(self, inst, cls):
536 def __get__(self, inst, cls):
537 """Make sure that a class __provides__ doesn't leak to an instance
537 """Make sure that a class __provides__ doesn't leak to an instance
538 """
538 """
539 if inst is None and cls is self._cls:
539 if inst is None and cls is self._cls:
540 # We were accessed through a class, so we are the class'
540 # We were accessed through a class, so we are the class'
541 # provides spec. Just return this object, but only if we are
541 # provides spec. Just return this object, but only if we are
542 # being called on the same class that we were defined for:
542 # being called on the same class that we were defined for:
543 return self
543 return self
544
544
545 raise AttributeError('__provides__')
545 raise AttributeError('__provides__')
546
546
547 ProvidesClass = Provides
547 ProvidesClass = Provides
548
548
549 # Registry of instance declarations
549 # Registry of instance declarations
550 # This is a memory optimization to allow objects to share specifications.
550 # This is a memory optimization to allow objects to share specifications.
551 InstanceDeclarations = weakref.WeakValueDictionary()
551 InstanceDeclarations = weakref.WeakValueDictionary()
552
552
553 def Provides(*interfaces):
553 def Provides(*interfaces):
554 """Cache instance declarations
554 """Cache instance declarations
555
555
556 Instance declarations are shared among instances that have the same
556 Instance declarations are shared among instances that have the same
557 declaration. The declarations are cached in a weak value dictionary.
557 declaration. The declarations are cached in a weak value dictionary.
558 """
558 """
559 spec = InstanceDeclarations.get(interfaces)
559 spec = InstanceDeclarations.get(interfaces)
560 if spec is None:
560 if spec is None:
561 spec = ProvidesClass(*interfaces)
561 spec = ProvidesClass(*interfaces)
562 InstanceDeclarations[interfaces] = spec
562 InstanceDeclarations[interfaces] = spec
563
563
564 return spec
564 return spec
565
565
566 Provides.__safe_for_unpickling__ = True
566 Provides.__safe_for_unpickling__ = True
567
567
568
568
569 def directlyProvides(object, *interfaces):
569 def directlyProvides(object, *interfaces):
570 """Declare interfaces declared directly for an object
570 """Declare interfaces declared directly for an object
571
571
572 The arguments after the object are one or more interfaces or interface
572 The arguments after the object are one or more interfaces or interface
573 specifications (``IDeclaration`` objects).
573 specifications (``IDeclaration`` objects).
574
574
575 The interfaces given (including the interfaces in the specifications)
575 The interfaces given (including the interfaces in the specifications)
576 replace interfaces previously declared for the object.
576 replace interfaces previously declared for the object.
577 """
577 """
578 cls = getattr(object, '__class__', None)
578 cls = getattr(object, '__class__', None)
579 if cls is not None and getattr(cls, '__class__', None) is cls:
579 if cls is not None and getattr(cls, '__class__', None) is cls:
580 # It's a meta class (well, at least it it could be an extension class)
580 # It's a meta class (well, at least it it could be an extension class)
581 # Note that we can't get here from Py3k tests: there is no normal
581 # Note that we can't get here from Py3k tests: there is no normal
582 # class which isn't descriptor aware.
582 # class which isn't descriptor aware.
583 if not isinstance(object,
583 if not isinstance(object,
584 DescriptorAwareMetaClasses):
584 DescriptorAwareMetaClasses):
585 raise TypeError("Attempt to make an interface declaration on a "
585 raise TypeError("Attempt to make an interface declaration on a "
586 "non-descriptor-aware class")
586 "non-descriptor-aware class")
587
587
588 interfaces = _normalizeargs(interfaces)
588 interfaces = _normalizeargs(interfaces)
589 if cls is None:
589 if cls is None:
590 cls = type(object)
590 cls = type(object)
591
591
592 issub = False
592 issub = False
593 for damc in DescriptorAwareMetaClasses:
593 for damc in DescriptorAwareMetaClasses:
594 if issubclass(cls, damc):
594 if issubclass(cls, damc):
595 issub = True
595 issub = True
596 break
596 break
597 if issub:
597 if issub:
598 # we have a class or type. We'll use a special descriptor
598 # we have a class or type. We'll use a special descriptor
599 # that provides some extra caching
599 # that provides some extra caching
600 object.__provides__ = ClassProvides(object, cls, *interfaces)
600 object.__provides__ = ClassProvides(object, cls, *interfaces)
601 else:
601 else:
602 object.__provides__ = Provides(cls, *interfaces)
602 object.__provides__ = Provides(cls, *interfaces)
603
603
604
604
605 def alsoProvides(object, *interfaces):
605 def alsoProvides(object, *interfaces):
606 """Declare interfaces declared directly for an object
606 """Declare interfaces declared directly for an object
607
607
608 The arguments after the object are one or more interfaces or interface
608 The arguments after the object are one or more interfaces or interface
609 specifications (``IDeclaration`` objects).
609 specifications (``IDeclaration`` objects).
610
610
611 The interfaces given (including the interfaces in the specifications) are
611 The interfaces given (including the interfaces in the specifications) are
612 added to the interfaces previously declared for the object.
612 added to the interfaces previously declared for the object.
613 """
613 """
614 directlyProvides(object, directlyProvidedBy(object), *interfaces)
614 directlyProvides(object, directlyProvidedBy(object), *interfaces)
615
615
616 def noLongerProvides(object, interface):
616 def noLongerProvides(object, interface):
617 """ Removes a directly provided interface from an object.
617 """ Removes a directly provided interface from an object.
618 """
618 """
619 directlyProvides(object, directlyProvidedBy(object) - interface)
619 directlyProvides(object, directlyProvidedBy(object) - interface)
620 if interface.providedBy(object):
620 if interface.providedBy(object):
621 raise ValueError("Can only remove directly provided interfaces.")
621 raise ValueError("Can only remove directly provided interfaces.")
622
622
623 class ClassProvidesBaseFallback(object):
623 class ClassProvidesBaseFallback(object):
624
624
625 def __get__(self, inst, cls):
625 def __get__(self, inst, cls):
626 if cls is self._cls:
626 if cls is self._cls:
627 # We only work if called on the class we were defined for
627 # We only work if called on the class we were defined for
628
628
629 if inst is None:
629 if inst is None:
630 # We were accessed through a class, so we are the class'
630 # We were accessed through a class, so we are the class'
631 # provides spec. Just return this object as is:
631 # provides spec. Just return this object as is:
632 return self
632 return self
633
633
634 return self._implements
634 return self._implements
635
635
636 raise AttributeError('__provides__')
636 raise AttributeError('__provides__')
637
637
638 ClassProvidesBasePy = ClassProvidesBaseFallback # BBB
638 ClassProvidesBasePy = ClassProvidesBaseFallback # BBB
639 ClassProvidesBase = ClassProvidesBaseFallback
639 ClassProvidesBase = ClassProvidesBaseFallback
640
640
641 # Try to get C base:
641 # Try to get C base:
642 try:
642 try:
643 from . import _zope_interface_coptimizations
643 from . import _zope_interface_coptimizations
644 except ImportError:
644 except ImportError:
645 pass
645 pass
646 else:
646 else:
647 from ._zope_interface_coptimizations import ClassProvidesBase
647 from ._zope_interface_coptimizations import ClassProvidesBase
648
648
649
649
650 class ClassProvides(Declaration, ClassProvidesBase):
650 class ClassProvides(Declaration, ClassProvidesBase):
651 """Special descriptor for class __provides__
651 """Special descriptor for class __provides__
652
652
653 The descriptor caches the implementedBy info, so that
653 The descriptor caches the implementedBy info, so that
654 we can get declarations for objects without instance-specific
654 we can get declarations for objects without instance-specific
655 interfaces a bit quicker.
655 interfaces a bit quicker.
656 """
656 """
657 def __init__(self, cls, metacls, *interfaces):
657 def __init__(self, cls, metacls, *interfaces):
658 self._cls = cls
658 self._cls = cls
659 self._implements = implementedBy(cls)
659 self._implements = implementedBy(cls)
660 self.__args = (cls, metacls, ) + interfaces
660 self.__args = (cls, metacls, ) + interfaces
661 Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
661 Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
662
662
663 def __reduce__(self):
663 def __reduce__(self):
664 return self.__class__, self.__args
664 return self.__class__, self.__args
665
665
666 # Copy base-class method for speed
666 # Copy base-class method for speed
667 __get__ = ClassProvidesBase.__get__
667 __get__ = ClassProvidesBase.__get__
668
668
669 def directlyProvidedBy(object):
669 def directlyProvidedBy(object):
670 """Return the interfaces directly provided by the given object
670 """Return the interfaces directly provided by the given object
671
671
672 The value returned is an ``IDeclaration``.
672 The value returned is an ``IDeclaration``.
673 """
673 """
674 provides = getattr(object, "__provides__", None)
674 provides = getattr(object, "__provides__", None)
675 if (provides is None # no spec
675 if (provides is None # no spec
676 or
676 or
677 # We might have gotten the implements spec, as an
677 # We might have gotten the implements spec, as an
678 # optimization. If so, it's like having only one base, that we
678 # optimization. If so, it's like having only one base, that we
679 # lop off to exclude class-supplied declarations:
679 # lop off to exclude class-supplied declarations:
680 isinstance(provides, Implements)
680 isinstance(provides, Implements)
681 ):
681 ):
682 return _empty
682 return _empty
683
683
684 # Strip off the class part of the spec:
684 # Strip off the class part of the spec:
685 return Declaration(provides.__bases__[:-1])
685 return Declaration(provides.__bases__[:-1])
686
686
687 def classProvides(*interfaces):
687 def classProvides(*interfaces):
688 """Declare interfaces provided directly by a class
688 """Declare interfaces provided directly by a class
689
689
690 This function is called in a class definition.
690 This function is called in a class definition.
691
691
692 The arguments are one or more interfaces or interface specifications
692 The arguments are one or more interfaces or interface specifications
693 (``IDeclaration`` objects).
693 (``IDeclaration`` objects).
694
694
695 The given interfaces (including the interfaces in the specifications)
695 The given interfaces (including the interfaces in the specifications)
696 are used to create the class's direct-object interface specification.
696 are used to create the class's direct-object interface specification.
697 An error will be raised if the module class has an direct interface
697 An error will be raised if the module class has an direct interface
698 specification. In other words, it is an error to call this function more
698 specification. In other words, it is an error to call this function more
699 than once in a class definition.
699 than once in a class definition.
700
700
701 Note that the given interfaces have nothing to do with the interfaces
701 Note that the given interfaces have nothing to do with the interfaces
702 implemented by instances of the class.
702 implemented by instances of the class.
703
703
704 This function is provided for convenience. It provides a more convenient
704 This function is provided for convenience. It provides a more convenient
705 way to call directlyProvides for a class. For example::
705 way to call directlyProvides for a class. For example::
706
706
707 classProvides(I1)
707 classProvides(I1)
708
708
709 is equivalent to calling::
709 is equivalent to calling::
710
710
711 directlyProvides(theclass, I1)
711 directlyProvides(theclass, I1)
712
712
713 after the class has been created.
713 after the class has been created.
714 """
714 """
715 # This entire approach is invalid under Py3K. Don't even try to fix
715 # This entire approach is invalid under Py3K. Don't even try to fix
716 # the coverage for this block there. :(
716 # the coverage for this block there. :(
717
717
718 if PYTHON3:
718 if PYTHON3:
719 raise TypeError(_ADVICE_ERROR % 'provider')
719 raise TypeError(_ADVICE_ERROR % 'provider')
720
720
721 frame = sys._getframe(1)
721 frame = sys._getframe(1)
722 locals = frame.f_locals
722 locals = frame.f_locals
723
723
724 # Try to make sure we were called from a class def
724 # Try to make sure we were called from a class def
725 if (locals is frame.f_globals) or ('__module__' not in locals):
725 if (locals is frame.f_globals) or ('__module__' not in locals):
726 raise TypeError("classProvides can be used only from a "
726 raise TypeError("classProvides can be used only from a "
727 "class definition.")
727 "class definition.")
728
728
729 if '__provides__' in locals:
729 if '__provides__' in locals:
730 raise TypeError(
730 raise TypeError(
731 "classProvides can only be used once in a class definition.")
731 "classProvides can only be used once in a class definition.")
732
732
733 locals["__provides__"] = _normalizeargs(interfaces)
733 locals["__provides__"] = _normalizeargs(interfaces)
734
734
735 addClassAdvisor(_classProvides_advice, depth=2)
735 advicemod.addClassAdvisor(_classProvides_advice, depth=2)
736
736
737 def _classProvides_advice(cls):
737 def _classProvides_advice(cls):
738 # This entire approach is invalid under Py3K. Don't even try to fix
738 # This entire approach is invalid under Py3K. Don't even try to fix
739 # the coverage for this block there. :(
739 # the coverage for this block there. :(
740 interfaces = cls.__dict__['__provides__']
740 interfaces = cls.__dict__['__provides__']
741 del cls.__provides__
741 del cls.__provides__
742 directlyProvides(cls, *interfaces)
742 directlyProvides(cls, *interfaces)
743 return cls
743 return cls
744
744
745 class provider:
745 class provider:
746 """Class decorator version of classProvides"""
746 """Class decorator version of classProvides"""
747
747
748 def __init__(self, *interfaces):
748 def __init__(self, *interfaces):
749 self.interfaces = interfaces
749 self.interfaces = interfaces
750
750
751 def __call__(self, ob):
751 def __call__(self, ob):
752 directlyProvides(ob, *self.interfaces)
752 directlyProvides(ob, *self.interfaces)
753 return ob
753 return ob
754
754
755 def moduleProvides(*interfaces):
755 def moduleProvides(*interfaces):
756 """Declare interfaces provided by a module
756 """Declare interfaces provided by a module
757
757
758 This function is used in a module definition.
758 This function is used in a module definition.
759
759
760 The arguments are one or more interfaces or interface specifications
760 The arguments are one or more interfaces or interface specifications
761 (``IDeclaration`` objects).
761 (``IDeclaration`` objects).
762
762
763 The given interfaces (including the interfaces in the specifications) are
763 The given interfaces (including the interfaces in the specifications) are
764 used to create the module's direct-object interface specification. An
764 used to create the module's direct-object interface specification. An
765 error will be raised if the module already has an interface specification.
765 error will be raised if the module already has an interface specification.
766 In other words, it is an error to call this function more than once in a
766 In other words, it is an error to call this function more than once in a
767 module definition.
767 module definition.
768
768
769 This function is provided for convenience. It provides a more convenient
769 This function is provided for convenience. It provides a more convenient
770 way to call directlyProvides. For example::
770 way to call directlyProvides. For example::
771
771
772 moduleImplements(I1)
772 moduleImplements(I1)
773
773
774 is equivalent to::
774 is equivalent to::
775
775
776 directlyProvides(sys.modules[__name__], I1)
776 directlyProvides(sys.modules[__name__], I1)
777 """
777 """
778 frame = sys._getframe(1)
778 frame = sys._getframe(1)
779 locals = frame.f_locals
779 locals = frame.f_locals
780
780
781 # Try to make sure we were called from a class def
781 # Try to make sure we were called from a class def
782 if (locals is not frame.f_globals) or ('__name__' not in locals):
782 if (locals is not frame.f_globals) or ('__name__' not in locals):
783 raise TypeError(
783 raise TypeError(
784 "moduleProvides can only be used from a module definition.")
784 "moduleProvides can only be used from a module definition.")
785
785
786 if '__provides__' in locals:
786 if '__provides__' in locals:
787 raise TypeError(
787 raise TypeError(
788 "moduleProvides can only be used once in a module definition.")
788 "moduleProvides can only be used once in a module definition.")
789
789
790 locals["__provides__"] = Provides(ModuleType,
790 locals["__provides__"] = Provides(ModuleType,
791 *_normalizeargs(interfaces))
791 *_normalizeargs(interfaces))
792
792
793 ##############################################################################
793 ##############################################################################
794 #
794 #
795 # Declaration querying support
795 # Declaration querying support
796
796
797 # XXX: is this a fossil? Nobody calls it, no unit tests exercise it, no
797 # XXX: is this a fossil? Nobody calls it, no unit tests exercise it, no
798 # doctests import it, and the package __init__ doesn't import it.
798 # doctests import it, and the package __init__ doesn't import it.
799 def ObjectSpecification(direct, cls):
799 def ObjectSpecification(direct, cls):
800 """Provide object specifications
800 """Provide object specifications
801
801
802 These combine information for the object and for it's classes.
802 These combine information for the object and for it's classes.
803 """
803 """
804 return Provides(cls, direct) # pragma: no cover fossil
804 return Provides(cls, direct) # pragma: no cover fossil
805
805
806 def getObjectSpecificationFallback(ob):
806 def getObjectSpecificationFallback(ob):
807
807
808 provides = getattr(ob, '__provides__', None)
808 provides = getattr(ob, '__provides__', None)
809 if provides is not None:
809 if provides is not None:
810 if isinstance(provides, SpecificationBase):
810 if isinstance(provides, SpecificationBase):
811 return provides
811 return provides
812
812
813 try:
813 try:
814 cls = ob.__class__
814 cls = ob.__class__
815 except AttributeError:
815 except AttributeError:
816 # We can't get the class, so just consider provides
816 # We can't get the class, so just consider provides
817 return _empty
817 return _empty
818
818
819 return implementedBy(cls)
819 return implementedBy(cls)
820
820
821 getObjectSpecification = getObjectSpecificationFallback
821 getObjectSpecification = getObjectSpecificationFallback
822
822
823 def providedByFallback(ob):
823 def providedByFallback(ob):
824
824
825 # Here we have either a special object, an old-style declaration
825 # Here we have either a special object, an old-style declaration
826 # or a descriptor
826 # or a descriptor
827
827
828 # Try to get __providedBy__
828 # Try to get __providedBy__
829 try:
829 try:
830 r = ob.__providedBy__
830 r = ob.__providedBy__
831 except AttributeError:
831 except AttributeError:
832 # Not set yet. Fall back to lower-level thing that computes it
832 # Not set yet. Fall back to lower-level thing that computes it
833 return getObjectSpecification(ob)
833 return getObjectSpecification(ob)
834
834
835 try:
835 try:
836 # We might have gotten a descriptor from an instance of a
836 # We might have gotten a descriptor from an instance of a
837 # class (like an ExtensionClass) that doesn't support
837 # class (like an ExtensionClass) that doesn't support
838 # descriptors. We'll make sure we got one by trying to get
838 # descriptors. We'll make sure we got one by trying to get
839 # the only attribute, which all specs have.
839 # the only attribute, which all specs have.
840 r.extends
840 r.extends
841
841
842 except AttributeError:
842 except AttributeError:
843
843
844 # The object's class doesn't understand descriptors.
844 # The object's class doesn't understand descriptors.
845 # Sigh. We need to get an object descriptor, but we have to be
845 # Sigh. We need to get an object descriptor, but we have to be
846 # careful. We want to use the instance's __provides__, if
846 # careful. We want to use the instance's __provides__, if
847 # there is one, but only if it didn't come from the class.
847 # there is one, but only if it didn't come from the class.
848
848
849 try:
849 try:
850 r = ob.__provides__
850 r = ob.__provides__
851 except AttributeError:
851 except AttributeError:
852 # No __provides__, so just fall back to implementedBy
852 # No __provides__, so just fall back to implementedBy
853 return implementedBy(ob.__class__)
853 return implementedBy(ob.__class__)
854
854
855 # We need to make sure we got the __provides__ from the
855 # We need to make sure we got the __provides__ from the
856 # instance. We'll do this by making sure we don't get the same
856 # instance. We'll do this by making sure we don't get the same
857 # thing from the class:
857 # thing from the class:
858
858
859 try:
859 try:
860 cp = ob.__class__.__provides__
860 cp = ob.__class__.__provides__
861 except AttributeError:
861 except AttributeError:
862 # The ob doesn't have a class or the class has no
862 # The ob doesn't have a class or the class has no
863 # provides, assume we're done:
863 # provides, assume we're done:
864 return r
864 return r
865
865
866 if r is cp:
866 if r is cp:
867 # Oops, we got the provides from the class. This means
867 # Oops, we got the provides from the class. This means
868 # the object doesn't have it's own. We should use implementedBy
868 # the object doesn't have it's own. We should use implementedBy
869 return implementedBy(ob.__class__)
869 return implementedBy(ob.__class__)
870
870
871 return r
871 return r
872 providedBy = providedByFallback
872 providedBy = providedByFallback
873
873
874 class ObjectSpecificationDescriptorFallback(object):
874 class ObjectSpecificationDescriptorFallback(object):
875 """Implement the `__providedBy__` attribute
875 """Implement the `__providedBy__` attribute
876
876
877 The `__providedBy__` attribute computes the interfaces peovided by
877 The `__providedBy__` attribute computes the interfaces peovided by
878 an object.
878 an object.
879 """
879 """
880
880
881 def __get__(self, inst, cls):
881 def __get__(self, inst, cls):
882 """Get an object specification for an object
882 """Get an object specification for an object
883 """
883 """
884 if inst is None:
884 if inst is None:
885 return getObjectSpecification(cls)
885 return getObjectSpecification(cls)
886
886
887 provides = getattr(inst, '__provides__', None)
887 provides = getattr(inst, '__provides__', None)
888 if provides is not None:
888 if provides is not None:
889 return provides
889 return provides
890
890
891 return implementedBy(cls)
891 return implementedBy(cls)
892
892
893 ObjectSpecificationDescriptor = ObjectSpecificationDescriptorFallback
893 ObjectSpecificationDescriptor = ObjectSpecificationDescriptorFallback
894
894
895 ##############################################################################
895 ##############################################################################
896
896
897 def _normalizeargs(sequence, output = None):
897 def _normalizeargs(sequence, output = None):
898 """Normalize declaration arguments
898 """Normalize declaration arguments
899
899
900 Normalization arguments might contain Declarions, tuples, or single
900 Normalization arguments might contain Declarions, tuples, or single
901 interfaces.
901 interfaces.
902
902
903 Anything but individial interfaces or implements specs will be expanded.
903 Anything but individial interfaces or implements specs will be expanded.
904 """
904 """
905 if output is None:
905 if output is None:
906 output = []
906 output = []
907
907
908 cls = sequence.__class__
908 cls = sequence.__class__
909 if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
909 if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
910 output.append(sequence)
910 output.append(sequence)
911 else:
911 else:
912 for v in sequence:
912 for v in sequence:
913 _normalizeargs(v, output)
913 _normalizeargs(v, output)
914
914
915 return output
915 return output
916
916
917 _empty = Declaration()
917 _empty = Declaration()
918
918
919 try:
919 try:
920 from . import _zope_interface_coptimizations
920 from . import _zope_interface_coptimizations
921 except ImportError:
921 except ImportError:
922 pass
922 pass
923 else:
923 else:
924 from ._zope_interface_coptimizations import implementedBy
924 from ._zope_interface_coptimizations import implementedBy
925 from ._zope_interface_coptimizations import providedBy
925 from ._zope_interface_coptimizations import providedBy
926 from ._zope_interface_coptimizations import (
926 from ._zope_interface_coptimizations import (
927 getObjectSpecification)
927 getObjectSpecification)
928 from ._zope_interface_coptimizations import (
928 from ._zope_interface_coptimizations import (
929 ObjectSpecificationDescriptor)
929 ObjectSpecificationDescriptor)
930
930
931 objectSpecificationDescriptor = ObjectSpecificationDescriptor()
931 objectSpecificationDescriptor = ObjectSpecificationDescriptor()
General Comments 0
You need to be logged in to leave comments. Login now