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

2320

import _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-3021

from operator import itemgetter as _itemgetter, eq as _eq

3122

from keyword import iskeyword as _iskeyword

3223

import sys as _sys

@@ -40,30 +31,45 @@

4031

except ImportError:

4132

pass

4233

else:

43-

MutableSequence.register(deque)

34+

_collections_abc.MutableSequence.register(deque)

44354536

try:

4637

from _collections import defaultdict

4738

except ImportError:

4839

pass

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):

56625763

def __reversed__(self):

5864

yield from reversed(self._mapping)

596560-

class _OrderedDictItemsView(ItemsView):

66+

class _OrderedDictItemsView(_collections_abc.ItemsView):

61676268

def __reversed__(self):

6369

for key in reversed(self._mapping):

6470

yield (key, self._mapping[key])

657166-

class _OrderedDictValuesView(ValuesView):

72+

class _OrderedDictValuesView(_collections_abc.ValuesView):

67736874

def __reversed__(self):

6975

for key in reversed(self._mapping):

@@ -215,7 +221,7 @@ def __sizeof__(self):

215221

size += sizeof(self.__root) * n # proxy objects

216222

return size

217223218-

update = __update = MutableMapping.update

224+

update = __update = _collections_abc.MutableMapping.update

219225220226

def 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"

230236

return _OrderedDictValuesView(self)

231237232-

__ne__ = MutableMapping.__ne__

238+

__ne__ = _collections_abc.MutableMapping.__ne__

233239234240

__marker = object()

235241

@@ -636,7 +642,7 @@ def update(*args, **kwds):

636642

raise TypeError('expected at most 1 arguments, got %d' % len(args))

637643

iterable = args[0] if args else None

638644

if iterable is not None:

639-

if isinstance(iterable, Mapping):

645+

if isinstance(iterable, _collections_abc.Mapping):

640646

if self:

641647

self_get = self.get

642648

for elem, count in iterable.items():

@@ -673,7 +679,7 @@ def subtract(*args, **kwds):

673679

iterable = args[0] if args else None

674680

if iterable is not None:

675681

self_get = self.get

676-

if isinstance(iterable, Mapping):

682+

if isinstance(iterable, _collections_abc.Mapping):

677683

for elem, count in iterable.items():

678684

self[elem] = self_get(elem, 0) - count

679685

else:

@@ -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

992998

def __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."""

10581064

def __init__(self, initlist=None):

10591065

self.data = []

@@ -1126,7 +1132,7 @@ def extend(self, other):

11261132

### UserString

11271133

################################################################################

112811341129-

class UserString(Sequence):

1135+

class UserString(_collections_abc.Sequence):

11301136

def __init__(self, seq):

11311137

if isinstance(seq, str):

11321138

self.data = seq