bpo-25988: Emit a warning when use or import ABCs from 'collections'. (#5460)

This commit is contained in:
Serhiy Storchaka 2018-01-31 19:19:33 +02:00 committed by GitHub
parent a29ddf4078
commit c66f9f8d39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 22 deletions

View file

@ -17,16 +17,7 @@
__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
'UserString', 'Counter', 'OrderedDict', 'ChainMap']
# For backwards compatibility, continue to make the collections ABCs
# through Python 3.6 available through the collections module.
# Note, no new collections ABCs were added in Python 3.7
import _collections_abc
from _collections_abc import (AsyncGenerator, AsyncIterable, AsyncIterator,
Awaitable, ByteString, Callable, Collection, Container, Coroutine,
Generator, Hashable, ItemsView, Iterable, Iterator, KeysView, Mapping,
MappingView, MutableMapping, MutableSequence, MutableSet, Reversible,
Sequence, Set, Sized, ValuesView)
from operator import itemgetter as _itemgetter, eq as _eq
from keyword import iskeyword as _iskeyword
import sys as _sys
@ -40,7 +31,7 @@
except ImportError:
pass
else:
MutableSequence.register(deque)
_collections_abc.MutableSequence.register(deque)
try:
from _collections import defaultdict
@ -48,22 +39,37 @@
pass
def __getattr__(name):
# For backwards compatibility, continue to make the collections ABCs
# through Python 3.6 available through the collections module.
# Note, no new collections ABCs were added in Python 3.7
if name in _collections_abc.__all__:
obj = getattr(_collections_abc, name)
import warnings
warnings.warn("Using or importing the ABCs from 'collections' instead "
"of from 'collections.abc' is deprecated, "
"and in 3.8 it will stop working",
DeprecationWarning, stacklevel=2)
globals()[name] = obj
return obj
raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
################################################################################
### OrderedDict
################################################################################
class _OrderedDictKeysView(KeysView):
class _OrderedDictKeysView(_collections_abc.KeysView):
def __reversed__(self):
yield from reversed(self._mapping)
class _OrderedDictItemsView(ItemsView):
class _OrderedDictItemsView(_collections_abc.ItemsView):
def __reversed__(self):
for key in reversed(self._mapping):
yield (key, self._mapping[key])
class _OrderedDictValuesView(ValuesView):
class _OrderedDictValuesView(_collections_abc.ValuesView):
def __reversed__(self):
for key in reversed(self._mapping):
@ -215,7 +221,7 @@ def __sizeof__(self):
size += sizeof(self.__root) * n # proxy objects
return size
update = __update = MutableMapping.update
update = __update = _collections_abc.MutableMapping.update
def keys(self):
"D.keys() -> a set-like object providing a view on D's keys"
@ -229,7 +235,7 @@ def values(self):
"D.values() -> an object providing a view on D's values"
return _OrderedDictValuesView(self)
__ne__ = MutableMapping.__ne__
__ne__ = _collections_abc.MutableMapping.__ne__
__marker = object()
@ -636,7 +642,7 @@ def update(*args, **kwds):
raise TypeError('expected at most 1 arguments, got %d' % len(args))
iterable = args[0] if args else None
if iterable is not None:
if isinstance(iterable, Mapping):
if isinstance(iterable, _collections_abc.Mapping):
if self:
self_get = self.get
for elem, count in iterable.items():
@ -673,7 +679,7 @@ def subtract(*args, **kwds):
iterable = args[0] if args else None
if iterable is not None:
self_get = self.get
if isinstance(iterable, Mapping):
if isinstance(iterable, _collections_abc.Mapping):
for elem, count in iterable.items():
self[elem] = self_get(elem, 0) - count
else:
@ -875,7 +881,7 @@ def __iand__(self, other):
### ChainMap
########################################################################
class ChainMap(MutableMapping):
class ChainMap(_collections_abc.MutableMapping):
''' A ChainMap groups multiple dicts (or other mappings) together
to create a single, updateable view.
@ -983,7 +989,7 @@ def clear(self):
### UserDict
################################################################################
class UserDict(MutableMapping):
class UserDict(_collections_abc.MutableMapping):
# Start by filling-out the abstract methods
def __init__(*args, **kwargs):
@ -1050,7 +1056,7 @@ def fromkeys(cls, iterable, value=None):
### UserList
################################################################################
class UserList(MutableSequence):
class UserList(_collections_abc.MutableSequence):
"""A more or less complete user-defined wrapper around list objects."""
def __init__(self, initlist=None):
self.data = []
@ -1123,7 +1129,7 @@ def extend(self, other):
### UserString
################################################################################
class UserString(Sequence):
class UserString(_collections_abc.Sequence):
def __init__(self, seq):
if isinstance(seq, str):
self.data = seq

View file

@ -5521,6 +5521,7 @@ PyInit__decimal(void)
PyObject *numbers = NULL;
PyObject *Number = NULL;
PyObject *collections = NULL;
PyObject *collections_abc = NULL;
PyObject *MutableMapping = NULL;
PyObject *obj = NULL;
DecCondMap *cm;
@ -5595,7 +5596,8 @@ PyInit__decimal(void)
Py_CLEAR(obj);
/* MutableMapping */
ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections,
ASSIGN_PTR(collections_abc, PyImport_ImportModule("collections.abc"));
ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections_abc,
"MutableMapping"));
/* Create SignalDict type */
ASSIGN_PTR(PyDecSignalDict_Type,
@ -5606,6 +5608,7 @@ PyInit__decimal(void)
/* Done with collections, MutableMapping */
Py_CLEAR(collections);
Py_CLEAR(collections_abc);
Py_CLEAR(MutableMapping);
@ -5765,6 +5768,7 @@ PyInit__decimal(void)
Py_CLEAR(Number); /* GCOV_NOT_REACHED */
Py_CLEAR(Rational); /* GCOV_NOT_REACHED */
Py_CLEAR(collections); /* GCOV_NOT_REACHED */
Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */
Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */