• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / zope.interface / 16098775349

04 Mar 2025 10:16PM UTC coverage: 99.073% (+0.05%) from 99.022%
16098775349

push

github

web-flow
Merge pull request #338 from zopefoundation/config-with-c-code-template-3c1c588c

Apply latest meta templates, drop support for Python 3.8

2436 of 2464 branches covered (98.86%)

Branch coverage included in aggregate %.

12209 of 12318 relevant lines covered (99.12%)

6.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.19
/src/zope/interface/common/tests/__init__.py
1
##############################################################################
2
# Copyright (c) 2020 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

13
import unittest
7✔
14

15
from zope.interface.common import ABCInterface
7✔
16
from zope.interface.common import ABCInterfaceClass
7✔
17
from zope.interface.verify import verifyClass
7✔
18
from zope.interface.verify import verifyObject
7✔
19

20

21
def iter_abc_interfaces(predicate=lambda iface: True):
7!
22
    # Iterate ``(iface, classes)``, where ``iface`` is a descendent of
23
    # the ABCInterfaceClass passing the *predicate* and ``classes`` is
24
    # an iterable of classes registered to conform to that interface.
25
    #
26
    # Note that some builtin classes are registered for two distinct parts of
27
    # the ABC/interface tree. For example, bytearray is both ByteString and
28
    # MutableSequence.
29
    seen = set()
7✔
30
    stack = list(
7✔
31
        ABCInterface.dependents
32
    )  # subclasses, but also implementedBy objects
33

34
    while stack:
7✔
35
        iface = stack.pop(0)
7✔
36
        if iface in seen or not isinstance(iface, ABCInterfaceClass):
7✔
37
            continue
7✔
38
        seen.add(iface)
7✔
39
        stack.extend(list(iface.dependents))
7✔
40
        if not predicate(iface):
7✔
41
            continue
7✔
42

43
        registered = set(iface.getRegisteredConformers())
7✔
44
        registered -= set(iface._ABCInterfaceClass__ignored_classes)
7✔
45
        if registered:
7✔
46
            yield iface, registered
7✔
47

48

49
def add_abc_interface_tests(cls, module):
7✔
50
    def predicate(iface):
7✔
51
        return iface.__module__ == module
7✔
52
    add_verify_tests(cls, iter_abc_interfaces(predicate))
7✔
53

54

55
def add_verify_tests(cls, iface_classes_iter):
7✔
56
    cls.maxDiff = None
7✔
57
    for iface, registered_classes in iface_classes_iter:
7✔
58
        for stdlib_class in registered_classes:
7✔
59
            def test(self, stdlib_class=stdlib_class, iface=iface):
7✔
60
                if (
7✔
61
                    stdlib_class in self.UNVERIFIABLE or
62
                    stdlib_class.__name__ in self.UNVERIFIABLE
63
                ):
64
                    self.skipTest("Unable to verify %s" % stdlib_class)
7✔
65

66
                self.assertTrue(self.verify(iface, stdlib_class))
7✔
67

68
            suffix = "{}_{}_{}_{}".format(
7✔
69
                stdlib_class.__module__.replace('.', '_'),
70
                stdlib_class.__name__,
71
                iface.__module__.replace('.', '_'),
72
                iface.__name__
73
            )
74
            name = 'test_auto_' + suffix
7✔
75
            test.__name__ = name
7✔
76
            assert not hasattr(cls, name), (name, list(cls.__dict__))
7✔
77
            setattr(cls, name, test)
7✔
78

79
            def test_ro(self, stdlib_class=stdlib_class, iface=iface):
7✔
80
                from zope.interface import Interface
7✔
81
                from zope.interface import implementedBy
7✔
82
                from zope.interface import ro
7✔
83
                self.assertEqual(
7✔
84
                    tuple(ro.ro(iface, strict=True)),
85
                    iface.__sro__)
86
                implements = implementedBy(stdlib_class)
7✔
87
                sro = implements.__sro__
7✔
88
                self.assertIs(sro[-1], Interface)
7✔
89

90
                if stdlib_class not in self.UNVERIFIABLE_RO:
7✔
91
                    # Check that we got the strict C3 resolution order, unless
92
                    # we know we cannot. Note that 'Interface' is virtual base
93
                    # that doesn't necessarily appear at the same place in the
94
                    # calculated SRO as in the final SRO.
95
                    strict = stdlib_class not in self.NON_STRICT_RO
7✔
96
                    isro = ro.ro(implements, strict=strict)
7✔
97
                    isro.remove(Interface)
7✔
98
                    isro.append(Interface)
7✔
99

100
                    self.assertEqual(tuple(isro), sro)
7✔
101

102
            name = 'test_auto_ro_' + suffix
7✔
103
            test_ro.__name__ = name
7✔
104
            assert not hasattr(cls, name)
7✔
105
            setattr(cls, name, test_ro)
7✔
106

107

108
class VerifyClassMixin(unittest.TestCase):
7✔
109
    verifier = staticmethod(verifyClass)
7✔
110
    UNVERIFIABLE = ()
7✔
111
    NON_STRICT_RO = ()
7✔
112
    UNVERIFIABLE_RO = ()
7✔
113

114
    def _adjust_object_before_verify(self, iface, x):
7✔
115
        return x
7✔
116

117
    def verify(self, iface, klass, **kwargs):
7✔
118
        return self.verifier(iface,
7✔
119
                             self._adjust_object_before_verify(iface, klass),
120
                             **kwargs)
121

122

123
class VerifyObjectMixin(VerifyClassMixin):
7✔
124
    verifier = staticmethod(verifyObject)
7✔
125
    CONSTRUCTORS = {
7✔
126
    }
127

128
    def _adjust_object_before_verify(self, iface, x):
7✔
129
        constructor = self.CONSTRUCTORS.get(x)
7✔
130
        if not constructor:
7✔
131
            constructor = self.CONSTRUCTORS.get(iface)
7✔
132
        if not constructor:
7✔
133
            constructor = self.CONSTRUCTORS.get(x.__name__)
7✔
134
        if not constructor:
7✔
135
            constructor = x
7✔
136
        if constructor is unittest.SkipTest:
7✔
137
            self.skipTest("Cannot create " + str(x))
7✔
138

139
        try:
7✔
140
            result = constructor()
7✔
141
        except Exception as e:  # pragma: no cover
142
            raise TypeError(
143
                f'Failed to create instance of {constructor}') from e
144
        if hasattr(result, 'close'):
7✔
145
            self.addCleanup(result.close)
7✔
146
        return result
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc