Mini Shell
##############################################################################
# Copyright (c) 2020 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""
Interface definitions paralleling the abstract base classes defined in
:mod:`collections.abc`.
After this module is imported, the standard library types will declare that
they implement the appropriate interface. While most standard library types
will properly implement that interface (that is, ``verifyObject(ISequence,
list()))`` will pass, for example), a few might not:
- `memoryview` doesn't feature all the defined methods of
``ISequence`` such as ``count``; it is still declared to provide
``ISequence`` though.
- `collections.deque.pop` doesn't accept the ``index`` argument of
`collections.abc.MutableSequence.pop`
- `range.index` does not accept the ``start`` and ``stop`` arguments.
.. versionadded:: 5.0.0
"""
import sys
from abc import ABCMeta
from collections import OrderedDict
from collections import UserDict
from collections import UserList
from collections import UserString
from collections import abc
from zope.interface._compat import PY313_OR_OLDER
from zope.interface.common import ABCInterface
from zope.interface.common import optional
# pylint:disable=inherit-non-class,
# pylint:disable=no-self-argument,no-method-argument
# pylint:disable=unexpected-special-method-signature
# pylint:disable=no-value-for-parameter
def _new_in_ver(name, ver,
bases_if_missing=(ABCMeta,),
register_if_missing=()):
if ver:
return getattr(abc, name)
# TODO: It's a shame to have to repeat the bases when
# the ABC is missing. Can we DRY that?
missing = ABCMeta(name, bases_if_missing, {
'__doc__': "The ABC %s is not defined in this version of Python." % (
name
),
})
for c in register_if_missing:
missing.register(c)
return missing
__all__ = [
'IAsyncGenerator',
'IAsyncIterable',
'IAsyncIterator',
'IAwaitable',
'ICollection',
'IContainer',
'ICoroutine',
'IGenerator',
'IHashable',
'IItemsView',
'IIterable',
'IIterator',
'IKeysView',
'IMapping',
'IMappingView',
'IMutableMapping',
'IMutableSequence',
'IMutableSet',
'IReversible',
'ISequence',
'ISet',
'ISized',
'IValuesView',
]
class IContainer(ABCInterface):
abc = abc.Container
@optional
def __contains__(other):
"""
Optional method. If not provided, the interpreter will use
``__iter__`` or the old ``__getitem__`` protocol
to implement ``in``.
"""
class IHashable(ABCInterface):
abc = abc.Hashable
class IIterable(ABCInterface):
abc = abc.Iterable
@optional
def __iter__():
"""
Optional method. If not provided, the interpreter will
implement `iter` using the old ``__getitem__`` protocol.
"""
class IIterator(IIterable):
abc = abc.Iterator
class IReversible(IIterable):
abc = _new_in_ver('Reversible', True, (IIterable.getABC(),))
@optional
def __reversed__():
"""
Optional method. If this isn't present, the interpreter
will use ``__len__`` and ``__getitem__`` to implement the
`reversed` builtin.
"""
class IGenerator(IIterator):
# New in Python 3.5
abc = _new_in_ver('Generator', True, (IIterator.getABC(),))
class ISized(ABCInterface):
abc = abc.Sized
# ICallable is not defined because there's no standard signature.
class ICollection(ISized,
IIterable,
IContainer):
abc = _new_in_ver(
'Collection',
True,
(ISized.getABC(), IIterable.getABC(), IContainer.getABC())
)
class ISequence(IReversible,
ICollection):
abc = abc.Sequence
extra_classes = (UserString,)
# On Python 2, basestring was registered as an ISequence, and
# its subclass str is an IByteString. If we also register str as
# an ISequence, that tends to lead to inconsistent resolution order.
ignored_classes = ()
@optional
def __reversed__():
"""
Optional method. If this isn't present, the interpreter
will use ``__len__`` and ``__getitem__`` to implement the
`reversed` builtin.
"""
@optional
def __iter__():
"""
Optional method. If not provided, the interpreter will
implement `iter` using the old ``__getitem__`` protocol.
"""
class IMutableSequence(ISequence):
abc = abc.MutableSequence
extra_classes = (UserList,)
if PY313_OR_OLDER:
class IByteString(ISequence):
"""
This unifies `bytes` and `bytearray`.
"""
abc = _new_in_ver(
'ByteString', True, (ISequence.getABC(),), (bytes, bytearray),
)
class ISet(ICollection):
abc = abc.Set
class IMutableSet(ISet):
abc = abc.MutableSet
class IMapping(ICollection):
abc = abc.Mapping
extra_classes = (dict,)
# OrderedDict is a subclass of dict. On CPython 2,
# it winds up registered as a IMutableMapping, which
# produces an inconsistent IRO if we also try to register it
# here.
ignored_classes = (OrderedDict,)
class IMutableMapping(IMapping):
abc = abc.MutableMapping
extra_classes = (dict, UserDict,)
ignored_classes = (OrderedDict,)
class IMappingView(ISized):
abc = abc.MappingView
class IItemsView(IMappingView, ISet):
abc = abc.ItemsView
class IKeysView(IMappingView, ISet):
abc = abc.KeysView
class IValuesView(IMappingView, ICollection):
abc = abc.ValuesView
@optional
def __contains__(other):
"""
Optional method. If not provided, the interpreter will use
``__iter__`` or the old ``__len__`` and ``__getitem__`` protocol
to implement ``in``.
"""
class IAwaitable(ABCInterface):
abc = _new_in_ver('Awaitable', True)
class ICoroutine(IAwaitable):
abc = _new_in_ver('Coroutine', True)
class IAsyncIterable(ABCInterface):
abc = _new_in_ver('AsyncIterable', True)
class IAsyncIterator(IAsyncIterable):
abc = _new_in_ver('AsyncIterator', True)
class IAsyncGenerator(IAsyncIterator):
abc = _new_in_ver('AsyncGenerator', True)
Zerion Mini Shell 1.0