collections.py 6.6 KB

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