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