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