• 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

93.81
/src/zope/interface/common/collections.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
"""
7✔
13
Interface definitions paralleling the abstract base classes defined in
14
:mod:`collections.abc`.
15

16
After this module is imported, the standard library types will declare that
17
they implement the appropriate interface. While most standard library types
18
will properly implement that interface (that is, ``verifyObject(ISequence,
19
list()))`` will pass, for example), a few might not:
20

21
    - `memoryview` doesn't feature all the defined methods of
22
      ``ISequence`` such as ``count``; it is still declared to provide
23
      ``ISequence`` though.
24

25
    - `collections.deque.pop` doesn't accept the ``index`` argument of
26
      `collections.abc.MutableSequence.pop`
27

28
    - `range.index` does not accept the ``start`` and ``stop`` arguments.
29

30
.. versionadded:: 5.0.0
31
"""
32

33
import sys
7✔
34
from abc import ABCMeta
7✔
35
from collections import OrderedDict
7✔
36
from collections import UserDict
7✔
37
from collections import UserList
7✔
38
from collections import UserString
7✔
39
from collections import abc
7✔
40

41
from zope.interface._compat import PY313_OR_OLDER
7✔
42
from zope.interface.common import ABCInterface
7✔
43
from zope.interface.common import optional
7✔
44

45

46
# pylint:disable=inherit-non-class,
47
# pylint:disable=no-self-argument,no-method-argument
48
# pylint:disable=unexpected-special-method-signature
49
# pylint:disable=no-value-for-parameter
50

51

52
def _new_in_ver(name, ver,
7✔
53
                bases_if_missing=(ABCMeta,),
54
                register_if_missing=()):
55
    if ver:
7!
56
        return getattr(abc, name)
7✔
57

58
    # TODO: It's a shame to have to repeat the bases when
59
    # the ABC is missing. Can we DRY that?
60
    missing = ABCMeta(name, bases_if_missing, {
×
61
        '__doc__': "The ABC %s is not defined in this version of Python." % (
62
            name
63
        ),
64
    })
65

66
    for c in register_if_missing:
×
67
        missing.register(c)
×
68

69
    return missing
×
70

71

72
__all__ = [
7✔
73
    'IAsyncGenerator',
74
    'IAsyncIterable',
75
    'IAsyncIterator',
76
    'IAwaitable',
77
    'ICollection',
78
    'IContainer',
79
    'ICoroutine',
80
    'IGenerator',
81
    'IHashable',
82
    'IItemsView',
83
    'IIterable',
84
    'IIterator',
85
    'IKeysView',
86
    'IMapping',
87
    'IMappingView',
88
    'IMutableMapping',
89
    'IMutableSequence',
90
    'IMutableSet',
91
    'IReversible',
92
    'ISequence',
93
    'ISet',
94
    'ISized',
95
    'IValuesView',
96
]
97

98

99
class IContainer(ABCInterface):
7✔
100
    abc = abc.Container
7✔
101

102
    @optional
7✔
103
    def __contains__(other):
7✔
104
        """
105
        Optional method. If not provided, the interpreter will use
106
        ``__iter__`` or the old ``__getitem__`` protocol
107
        to implement ``in``.
108
        """
109

110

111
class IHashable(ABCInterface):
7✔
112
    abc = abc.Hashable
7✔
113

114

115
class IIterable(ABCInterface):
7✔
116
    abc = abc.Iterable
7✔
117

118
    @optional
7✔
119
    def __iter__():
7✔
120
        """
121
        Optional method. If not provided, the interpreter will
122
        implement `iter` using the old ``__getitem__`` protocol.
123
        """
124

125

126
class IIterator(IIterable):
7✔
127
    abc = abc.Iterator
7✔
128

129

130
class IReversible(IIterable):
7✔
131
    abc = _new_in_ver('Reversible', True, (IIterable.getABC(),))
7✔
132

133
    @optional
7✔
134
    def __reversed__():
7✔
135
        """
136
        Optional method. If this isn't present, the interpreter
137
        will use ``__len__`` and ``__getitem__`` to implement the
138
        `reversed` builtin.
139
        """
140

141

142
class IGenerator(IIterator):
7✔
143
    # New in Python 3.5
144
    abc = _new_in_ver('Generator', True, (IIterator.getABC(),))
7✔
145

146

147
class ISized(ABCInterface):
7✔
148
    abc = abc.Sized
7✔
149

150

151
# ICallable is not defined because there's no standard signature.
152

153

154
class ICollection(ISized,
7✔
155
                  IIterable,
156
                  IContainer):
157
    abc = _new_in_ver(
7✔
158
        'Collection',
159
        True,
160
        (ISized.getABC(), IIterable.getABC(), IContainer.getABC())
161
    )
162

163

164
class ISequence(IReversible,
7✔
165
                ICollection):
166
    abc = abc.Sequence
7✔
167
    extra_classes = (UserString,)
7✔
168
    # On Python 2, basestring was registered as an ISequence, and
169
    # its subclass str is an IByteString. If we also register str as
170
    # an ISequence, that tends to lead to inconsistent resolution order.
171
    ignored_classes = ()
7✔
172

173
    @optional
7✔
174
    def __reversed__():
7✔
175
        """
176
        Optional method. If this isn't present, the interpreter
177
        will use ``__len__`` and ``__getitem__`` to implement the
178
        `reversed` builtin.
179
        """
180

181
    @optional
7✔
182
    def __iter__():
7✔
183
        """
184
        Optional method. If not provided, the interpreter will
185
        implement `iter` using the old ``__getitem__`` protocol.
186
        """
187

188

189
class IMutableSequence(ISequence):
7✔
190
    abc = abc.MutableSequence
7✔
191
    extra_classes = (UserList,)
7✔
192

193

194
if PY313_OR_OLDER:
7✔
195
    class IByteString(ISequence):
6✔
196
        """
197
        This unifies `bytes` and `bytearray`.
198
        """
199
        abc = _new_in_ver(
6✔
200
            'ByteString', True, (ISequence.getABC(),), (bytes, bytearray),
201
        )
202

203

204
class ISet(ICollection):
7✔
205
    abc = abc.Set
7✔
206

207

208
class IMutableSet(ISet):
7✔
209
    abc = abc.MutableSet
7✔
210

211

212
class IMapping(ICollection):
7✔
213
    abc = abc.Mapping
7✔
214
    extra_classes = (dict,)
7✔
215
    # OrderedDict is a subclass of dict. On CPython 2,
216
    # it winds up registered as a IMutableMapping, which
217
    # produces an inconsistent IRO if we also try to register it
218
    # here.
219
    ignored_classes = (OrderedDict,)
7✔
220

221

222
class IMutableMapping(IMapping):
7✔
223
    abc = abc.MutableMapping
7✔
224
    extra_classes = (dict, UserDict,)
7✔
225
    ignored_classes = (OrderedDict,)
7✔
226

227

228
class IMappingView(ISized):
7✔
229
    abc = abc.MappingView
7✔
230

231

232
class IItemsView(IMappingView, ISet):
7✔
233
    abc = abc.ItemsView
7✔
234

235

236
class IKeysView(IMappingView, ISet):
7✔
237
    abc = abc.KeysView
7✔
238

239

240
class IValuesView(IMappingView, ICollection):
7✔
241
    abc = abc.ValuesView
7✔
242

243
    @optional
7✔
244
    def __contains__(other):
7✔
245
        """
246
        Optional method. If not provided, the interpreter will use
247
        ``__iter__`` or the old ``__len__`` and ``__getitem__`` protocol
248
        to implement ``in``.
249
        """
250

251

252
class IAwaitable(ABCInterface):
7✔
253
    abc = _new_in_ver('Awaitable', True)
7✔
254

255

256
class ICoroutine(IAwaitable):
7✔
257
    abc = _new_in_ver('Coroutine', True)
7✔
258

259

260
class IAsyncIterable(ABCInterface):
7✔
261
    abc = _new_in_ver('AsyncIterable', True)
7✔
262

263

264
class IAsyncIterator(IAsyncIterable):
7✔
265
    abc = _new_in_ver('AsyncIterator', True)
7✔
266

267

268
class IAsyncGenerator(IAsyncIterator):
7✔
269
    abc = _new_in_ver('AsyncGenerator', True)
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