collections.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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. Interface definitions paralleling the abstract base classes defined in
  14. :mod:`collections.abc`.
  15. After this module is imported, the standard library types will declare that
  16. they implement the appropriate interface. While most standard library types
  17. will properly implement that interface (that is, ``verifyObject(ISequence,
  18. list()))`` will pass, for example), a few might not:
  19. - `memoryview` doesn't feature all the defined methods of
  20. ``ISequence`` such as ``count``; it is still declared to provide
  21. ``ISequence`` though.
  22. - `collections.deque.pop` doesn't accept the ``index`` argument of
  23. `collections.abc.MutableSequence.pop`
  24. - `range.index` does not accept the ``start`` and ``stop`` arguments.
  25. .. versionadded:: 5.0.0
  26. """
  27. import sys
  28. from abc import ABCMeta
  29. from collections import OrderedDict
  30. from collections import UserDict
  31. from collections import UserList
  32. from collections import UserString
  33. from collections import abc
  34. from zope.interface._compat import PY313_OR_OLDER
  35. from zope.interface.common import ABCInterface
  36. from zope.interface.common import optional
  37. # pylint:disable=inherit-non-class,
  38. # pylint:disable=no-self-argument,no-method-argument
  39. # pylint:disable=unexpected-special-method-signature
  40. # pylint:disable=no-value-for-parameter
  41. def _new_in_ver(name, ver,
  42. bases_if_missing=(ABCMeta,),
  43. register_if_missing=()):
  44. if ver:
  45. return getattr(abc, name)
  46. # TODO: It's a shame to have to repeat the bases when
  47. # the ABC is missing. Can we DRY that?
  48. missing = ABCMeta(name, bases_if_missing, {
  49. '__doc__': "The ABC %s is not defined in this version of Python." % (
  50. name
  51. ),
  52. })
  53. for c in register_if_missing:
  54. missing.register(c)
  55. return missing
  56. __all__ = [
  57. 'IAsyncGenerator',
  58. 'IAsyncIterable',
  59. 'IAsyncIterator',
  60. 'IAwaitable',
  61. 'ICollection',
  62. 'IContainer',
  63. 'ICoroutine',
  64. 'IGenerator',
  65. 'IHashable',
  66. 'IItemsView',
  67. 'IIterable',
  68. 'IIterator',
  69. 'IKeysView',
  70. 'IMapping',
  71. 'IMappingView',
  72. 'IMutableMapping',
  73. 'IMutableSequence',
  74. 'IMutableSet',
  75. 'IReversible',
  76. 'ISequence',
  77. 'ISet',
  78. 'ISized',
  79. 'IValuesView',
  80. ]
  81. class IContainer(ABCInterface):
  82. abc = abc.Container
  83. @optional
  84. def __contains__(other):
  85. """
  86. Optional method. If not provided, the interpreter will use
  87. ``__iter__`` or the old ``__getitem__`` protocol
  88. to implement ``in``.
  89. """
  90. class IHashable(ABCInterface):
  91. abc = abc.Hashable
  92. class IIterable(ABCInterface):
  93. abc = abc.Iterable
  94. @optional
  95. def __iter__():
  96. """
  97. Optional method. If not provided, the interpreter will
  98. implement `iter` using the old ``__getitem__`` protocol.
  99. """
  100. class IIterator(IIterable):
  101. abc = abc.Iterator
  102. class IReversible(IIterable):
  103. abc = _new_in_ver('Reversible', True, (IIterable.getABC(),))
  104. @optional
  105. def __reversed__():
  106. """
  107. Optional method. If this isn't present, the interpreter
  108. will use ``__len__`` and ``__getitem__`` to implement the
  109. `reversed` builtin.
  110. """
  111. class IGenerator(IIterator):
  112. # New in Python 3.5
  113. abc = _new_in_ver('Generator', True, (IIterator.getABC(),))
  114. class ISized(ABCInterface):
  115. abc = abc.Sized
  116. # ICallable is not defined because there's no standard signature.
  117. class ICollection(ISized,
  118. IIterable,
  119. IContainer):
  120. abc = _new_in_ver(
  121. 'Collection',
  122. True,
  123. (ISized.getABC(), IIterable.getABC(), IContainer.getABC())
  124. )
  125. class ISequence(IReversible,
  126. ICollection):
  127. abc = abc.Sequence
  128. extra_classes = (UserString,)
  129. # On Python 2, basestring was registered as an ISequence, and
  130. # its subclass str is an IByteString. If we also register str as
  131. # an ISequence, that tends to lead to inconsistent resolution order.
  132. ignored_classes = ()
  133. @optional
  134. def __reversed__():
  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. @optional
  141. def __iter__():
  142. """
  143. Optional method. If not provided, the interpreter will
  144. implement `iter` using the old ``__getitem__`` protocol.
  145. """
  146. class IMutableSequence(ISequence):
  147. abc = abc.MutableSequence
  148. extra_classes = (UserList,)
  149. if PY313_OR_OLDER:
  150. class IByteString(ISequence):
  151. """
  152. This unifies `bytes` and `bytearray`.
  153. """
  154. abc = _new_in_ver(
  155. 'ByteString', True, (ISequence.getABC(),), (bytes, bytearray),
  156. )
  157. class ISet(ICollection):
  158. abc = abc.Set
  159. class IMutableSet(ISet):
  160. abc = abc.MutableSet
  161. class IMapping(ICollection):
  162. abc = abc.Mapping
  163. extra_classes = (dict,)
  164. # OrderedDict is a subclass of dict. On CPython 2,
  165. # it winds up registered as a IMutableMapping, which
  166. # produces an inconsistent IRO if we also try to register it
  167. # here.
  168. ignored_classes = (OrderedDict,)
  169. class IMutableMapping(IMapping):
  170. abc = abc.MutableMapping
  171. extra_classes = (dict, UserDict,)
  172. ignored_classes = (OrderedDict,)
  173. class IMappingView(ISized):
  174. abc = abc.MappingView
  175. class IItemsView(IMappingView, ISet):
  176. abc = abc.ItemsView
  177. class IKeysView(IMappingView, ISet):
  178. abc = abc.KeysView
  179. class IValuesView(IMappingView, ICollection):
  180. abc = abc.ValuesView
  181. @optional
  182. def __contains__(other):
  183. """
  184. Optional method. If not provided, the interpreter will use
  185. ``__iter__`` or the old ``__len__`` and ``__getitem__`` protocol
  186. to implement ``in``.
  187. """
  188. class IAwaitable(ABCInterface):
  189. abc = _new_in_ver('Awaitable', True)
  190. class ICoroutine(IAwaitable):
  191. abc = _new_in_ver('Coroutine', True)
  192. class IAsyncIterable(ABCInterface):
  193. abc = _new_in_ver('AsyncIterable', True)
  194. class IAsyncIterator(IAsyncIterable):
  195. abc = _new_in_ver('AsyncIterator', True)
  196. class IAsyncGenerator(IAsyncIterator):
  197. abc = _new_in_ver('AsyncGenerator', True)