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