bpo-25988: Emit a warning when use or import ABCs from 'collections'.… · python/cpython@0442de5
@@ -17,16 +17,7 @@
1717__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
1818'UserString', 'Counter', 'OrderedDict', 'ChainMap']
191920-# For backwards compatibility, continue to make the collections ABCs
21-# through Python 3.6 available through the collections module.
22-# Note, no new collections ABCs were added in Python 3.7
2320import _collections_abc
24-from _collections_abc import (AsyncGenerator, AsyncIterable, AsyncIterator,
25-Awaitable, ByteString, Callable, Collection, Container, Coroutine,
26-Generator, Hashable, ItemsView, Iterable, Iterator, KeysView, Mapping,
27-MappingView, MutableMapping, MutableSequence, MutableSet, Reversible,
28-Sequence, Set, Sized, ValuesView)
29-3021from operator import itemgetter as _itemgetter, eq as _eq
3122from keyword import iskeyword as _iskeyword
3223import sys as _sys
@@ -40,30 +31,45 @@
4031except ImportError:
4132pass
4233else:
43-MutableSequence.register(deque)
34+_collections_abc.MutableSequence.register(deque)
44354536try:
4637from _collections import defaultdict
4738except ImportError:
4839pass
4940504142+def __getattr__(name):
43+# For backwards compatibility, continue to make the collections ABCs
44+# through Python 3.6 available through the collections module.
45+# Note, no new collections ABCs were added in Python 3.7
46+if name in _collections_abc.__all__:
47+obj = getattr(_collections_abc, name)
48+import warnings
49+warnings.warn("Using or importing the ABCs from 'collections' instead "
50+"of from 'collections.abc' is deprecated, "
51+"and in 3.8 it will stop working",
52+DeprecationWarning, stacklevel=2)
53+globals()[name] = obj
54+return obj
55+raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
56+5157################################################################################
5258### OrderedDict
5359################################################################################
546055-class _OrderedDictKeysView(KeysView):
61+class _OrderedDictKeysView(_collections_abc.KeysView):
56625763def __reversed__(self):
5864yield from reversed(self._mapping)
596560-class _OrderedDictItemsView(ItemsView):
66+class _OrderedDictItemsView(_collections_abc.ItemsView):
61676268def __reversed__(self):
6369for key in reversed(self._mapping):
6470yield (key, self._mapping[key])
657166-class _OrderedDictValuesView(ValuesView):
72+class _OrderedDictValuesView(_collections_abc.ValuesView):
67736874def __reversed__(self):
6975for key in reversed(self._mapping):
@@ -215,7 +221,7 @@ def __sizeof__(self):
215221size += sizeof(self.__root) * n # proxy objects
216222return size
217223218-update = __update = MutableMapping.update
224+update = __update = _collections_abc.MutableMapping.update
219225220226def keys(self):
221227"D.keys() -> a set-like object providing a view on D's keys"
@@ -229,7 +235,7 @@ def values(self):
229235"D.values() -> an object providing a view on D's values"
230236return _OrderedDictValuesView(self)
231237232-__ne__ = MutableMapping.__ne__
238+__ne__ = _collections_abc.MutableMapping.__ne__
233239234240__marker = object()
235241@@ -636,7 +642,7 @@ def update(*args, **kwds):
636642raise TypeError('expected at most 1 arguments, got %d' % len(args))
637643iterable = args[0] if args else None
638644if iterable is not None:
639-if isinstance(iterable, Mapping):
645+if isinstance(iterable, _collections_abc.Mapping):
640646if self:
641647self_get = self.get
642648for elem, count in iterable.items():
@@ -673,7 +679,7 @@ def subtract(*args, **kwds):
673679iterable = args[0] if args else None
674680if iterable is not None:
675681self_get = self.get
676-if isinstance(iterable, Mapping):
682+if isinstance(iterable, _collections_abc.Mapping):
677683for elem, count in iterable.items():
678684self[elem] = self_get(elem, 0) - count
679685else:
@@ -875,7 +881,7 @@ def __iand__(self, other):
875881### ChainMap
876882########################################################################
877883878-class ChainMap(MutableMapping):
884+class ChainMap(_collections_abc.MutableMapping):
879885''' A ChainMap groups multiple dicts (or other mappings) together
880886 to create a single, updateable view.
881887@@ -986,7 +992,7 @@ def clear(self):
986992### UserDict
987993################################################################################
988994989-class UserDict(MutableMapping):
995+class UserDict(_collections_abc.MutableMapping):
990996991997# Start by filling-out the abstract methods
992998def __init__(*args, **kwargs):
@@ -1053,7 +1059,7 @@ def fromkeys(cls, iterable, value=None):
10531059### UserList
10541060################################################################################
105510611056-class UserList(MutableSequence):
1062+class UserList(_collections_abc.MutableSequence):
10571063"""A more or less complete user-defined wrapper around list objects."""
10581064def __init__(self, initlist=None):
10591065self.data = []
@@ -1126,7 +1132,7 @@ def extend(self, other):
11261132### UserString
11271133################################################################################
112811341129-class UserString(Sequence):
1135+class UserString(_collections_abc.Sequence):
11301136def __init__(self, seq):
11311137if isinstance(seq, str):
11321138self.data = seq