Skip to content

bpo-30144: Import collections ABC from collections.abc rather than collections. #1263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/library/http.client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ also send your request step by step, by using the four functions below.
Section 3.3.1. How the data is encoded is dependent on the type of
*message_body*. If *message_body* implements the :ref:`buffer interface
<bufferobjects>` the encoding will result in a single chunk.
If *message_body* is a :class:`collections.Iterable`, each iteration
If *message_body* is a :class:`collections.abc.Iterable`, each iteration
of *message_body* will result in a chunk. If *message_body* is a
:term:`file object`, each call to ``.read()`` will result in a chunk.
The method automatically signals the end of the chunk-encoded data
Expand Down
6 changes: 3 additions & 3 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,7 @@ Basic customization
:meth:`__hash__` method of a class is ``None``, instances of the class will
raise an appropriate :exc:`TypeError` when a program attempts to retrieve
their hash value, and will also be correctly identified as unhashable when
checking ``isinstance(obj, collections.Hashable)``.
checking ``isinstance(obj, collections.abc.Hashable)``.

If a class that overrides :meth:`__eq__` needs to retain the implementation
of :meth:`__hash__` from a parent class, the interpreter must be told this
Expand All @@ -1385,7 +1385,7 @@ Basic customization
support, it should include ``__hash__ = None`` in the class definition.
A class which defines its own :meth:`__hash__` that explicitly raises
a :exc:`TypeError` would be incorrectly identified as hashable by
an ``isinstance(obj, collections.Hashable)`` call.
an ``isinstance(obj, collections.abc.Hashable)`` call.


.. note::
Expand Down Expand Up @@ -1981,7 +1981,7 @@ range of items. It is also recommended that mappings provide the methods
:meth:`keys`, :meth:`values`, :meth:`items`, :meth:`get`, :meth:`clear`,
:meth:`setdefault`, :meth:`pop`, :meth:`popitem`, :meth:`!copy`, and
:meth:`update` behaving similar to those for Python's standard dictionary
objects. The :mod:`collections` module provides a
objects. The :mod:`collections.abc` module provides a
:class:`~collections.abc.MutableMapping`
abstract base class to help create those methods from a base set of
:meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__`, and :meth:`keys`.
Expand Down
3 changes: 2 additions & 1 deletion Lib/asyncio/base_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""

import collections
import collections.abc
import concurrent.futures
import heapq
import itertools
Expand Down Expand Up @@ -1001,7 +1002,7 @@ def create_server(self, protocol_factory, host=None, port=None,
if host == '':
hosts = [None]
elif (isinstance(host, str) or
not isinstance(host, collections.Iterable)):
not isinstance(host, collections.abc.Iterable)):
hosts = [host]
else:
hosts = host
Expand Down
2 changes: 1 addition & 1 deletion Lib/cgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# =======

from io import StringIO, BytesIO, TextIOWrapper
from collections import Mapping
from collections.abc import Mapping
import sys
import os
import urllib.parse
Expand Down
4 changes: 2 additions & 2 deletions Lib/dbm/dumb.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
import ast as _ast
import io as _io
import os as _os
import collections
import collections.abc

__all__ = ["error", "open"]

_BLOCKSIZE = 512

error = OSError

class _Database(collections.MutableMapping):
class _Database(collections.abc.MutableMapping):

# The on-disk directory and data files can remain in mutually
# inconsistent states for an arbitrarily long time (see comments
Expand Down
4 changes: 2 additions & 2 deletions Lib/http/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
import io
import re
import socket
import collections
import collections.abc
from urllib.parse import urlsplit

# HTTPMessage, parse_headers(), and the HTTP status code constants are
Expand Down Expand Up @@ -977,7 +977,7 @@ def send(self, data):
try:
self.sock.sendall(data)
except TypeError:
if isinstance(data, collections.Iterable):
if isinstance(data, collections.abc.Iterable):
for d in data:
self.sock.sendall(d)
else:
Expand Down
2 changes: 1 addition & 1 deletion Lib/idlelib/pyparse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from collections import Mapping
from collections.abc import Mapping
import re
import sys

Expand Down
4 changes: 2 additions & 2 deletions Lib/lib2to3/fixes/fix_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
operator.irepeat(obj, n) -> operator.imul(obj, n)
"""

import collections
import collections.abc

# Local imports
from lib2to3 import fixer_base
Expand Down Expand Up @@ -88,7 +88,7 @@ def _handle_type2abc(self, node, results, module, abc):

def _check_method(self, node, results):
method = getattr(self, "_" + results["method"][0].value)
if isinstance(method, collections.Callable):
if isinstance(method, collections.abc.Callable):
if "module" in results:
return method
else:
Expand Down
4 changes: 2 additions & 2 deletions Lib/locale.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import encodings
import encodings.aliases
import re
import collections
import collections.abc
from builtins import str as _builtin_str
import functools
import warnings
Expand Down Expand Up @@ -215,7 +215,7 @@ def format_string(f, val, grouping=False, monetary=False):
percents = list(_percent_re.finditer(f))
new_f = _percent_re.sub('%s', f)

if isinstance(val, collections.Mapping):
if isinstance(val, collections.abc.Mapping):
new_val = []
for perc in percents:
if perc.group()[-1]=='%':
Expand Down
6 changes: 3 additions & 3 deletions Lib/logging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
To use, simply 'import logging' and log away!
"""

import sys, os, time, io, traceback, warnings, weakref, collections
import sys, os, time, io, traceback, warnings, weakref, collections.abc

from string import Template

Expand Down Expand Up @@ -273,8 +273,8 @@ def __init__(self, name, level, pathname, lineno,
# to hasattr(args[0], '__getitem__'). However, the docs on string
# formatting still seem to suggest a mapping object is required.
# Thus, while not removing the isinstance check, it does now look
# for collections.Mapping rather than, as before, dict.
if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
# for collections.abc.Mapping rather than, as before, dict.
if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping)
and args[0]):
args = args[0]
self.args = args
Expand Down
2 changes: 1 addition & 1 deletion Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import posixpath
import re
import sys
from collections import Sequence
from collections.abc import Sequence
from errno import EINVAL, ENOENT, ENOTDIR
from operator import attrgetter
from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
Expand Down
3 changes: 2 additions & 1 deletion Lib/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@


from abc import ABCMeta, abstractmethod
from collections import namedtuple, Mapping
from collections import namedtuple
from collections.abc import Mapping
import math
import select
import sys
Expand Down
6 changes: 3 additions & 3 deletions Lib/shelve.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@
from pickle import Pickler, Unpickler
from io import BytesIO

import collections
import collections.abc

__all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"]

class _ClosedDict(collections.MutableMapping):
class _ClosedDict(collections.abc.MutableMapping):
'Marker for a closed dict. Access attempts raise a ValueError.'

def closed(self, *args):
Expand All @@ -74,7 +74,7 @@ def __repr__(self):
return '<Closed Dictionary>'


class Shelf(collections.MutableMapping):
class Shelf(collections.abc.MutableMapping):
"""Base class for shelf implementations.

This is initialized with a dictionary-like object.
Expand Down
36 changes: 18 additions & 18 deletions Lib/test/test_dictviews.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import collections
import collections.abc
import copy
import pickle
import unittest
Expand Down Expand Up @@ -249,23 +249,23 @@ def test_pickle(self):
def test_abc_registry(self):
d = dict(a=1)

self.assertIsInstance(d.keys(), collections.KeysView)
self.assertIsInstance(d.keys(), collections.MappingView)
self.assertIsInstance(d.keys(), collections.Set)
self.assertIsInstance(d.keys(), collections.Sized)
self.assertIsInstance(d.keys(), collections.Iterable)
self.assertIsInstance(d.keys(), collections.Container)

self.assertIsInstance(d.values(), collections.ValuesView)
self.assertIsInstance(d.values(), collections.MappingView)
self.assertIsInstance(d.values(), collections.Sized)

self.assertIsInstance(d.items(), collections.ItemsView)
self.assertIsInstance(d.items(), collections.MappingView)
self.assertIsInstance(d.items(), collections.Set)
self.assertIsInstance(d.items(), collections.Sized)
self.assertIsInstance(d.items(), collections.Iterable)
self.assertIsInstance(d.items(), collections.Container)
self.assertIsInstance(d.keys(), collections.abc.KeysView)
self.assertIsInstance(d.keys(), collections.abc.MappingView)
self.assertIsInstance(d.keys(), collections.abc.Set)
self.assertIsInstance(d.keys(), collections.abc.Sized)
self.assertIsInstance(d.keys(), collections.abc.Iterable)
self.assertIsInstance(d.keys(), collections.abc.Container)

self.assertIsInstance(d.values(), collections.abc.ValuesView)
self.assertIsInstance(d.values(), collections.abc.MappingView)
self.assertIsInstance(d.values(), collections.abc.Sized)

self.assertIsInstance(d.items(), collections.abc.ItemsView)
self.assertIsInstance(d.items(), collections.abc.MappingView)
self.assertIsInstance(d.items(), collections.abc.Set)
self.assertIsInstance(d.items(), collections.abc.Sized)
self.assertIsInstance(d.items(), collections.abc.Iterable)
self.assertIsInstance(d.items(), collections.abc.Container)


if __name__ == "__main__":
Expand Down
39 changes: 20 additions & 19 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import abc
import builtins
import collections
import collections.abc
import copy
from itertools import permutations
import pickle
Expand Down Expand Up @@ -910,7 +911,7 @@ def mycmp(x, y):
key = self.cmp_to_key(mycmp)
k = key(10)
self.assertRaises(TypeError, hash, k)
self.assertNotIsInstance(k, collections.Hashable)
self.assertNotIsInstance(k, collections.abc.Hashable)


@unittest.skipUnless(c_functools, 'requires the C _functools module')
Expand Down Expand Up @@ -1707,18 +1708,18 @@ def _(obj):

def test_compose_mro(self):
# None of the examples in this test depend on haystack ordering.
c = collections
c = collections.abc
mro = functools._compose_mro
bases = [c.Sequence, c.MutableMapping, c.Mapping, c.Set]
for haystack in permutations(bases):
m = mro(dict, haystack)
self.assertEqual(m, [dict, c.MutableMapping, c.Mapping,
c.Collection, c.Sized, c.Iterable,
c.Container, object])
bases = [c.Container, c.Mapping, c.MutableMapping, c.OrderedDict]
bases = [c.Container, c.Mapping, c.MutableMapping, collections.OrderedDict]
for haystack in permutations(bases):
m = mro(c.ChainMap, haystack)
self.assertEqual(m, [c.ChainMap, c.MutableMapping, c.Mapping,
m = mro(collections.ChainMap, haystack)
self.assertEqual(m, [collections.ChainMap, c.MutableMapping, c.Mapping,
c.Collection, c.Sized, c.Iterable,
c.Container, object])

Expand All @@ -1728,39 +1729,39 @@ def test_compose_mro(self):
# test_mro_conflicts).
bases = [c.Container, c.Sized, str]
for haystack in permutations(bases):
m = mro(c.defaultdict, [c.Sized, c.Container, str])
self.assertEqual(m, [c.defaultdict, dict, c.Sized, c.Container,
object])
m = mro(collections.defaultdict, [c.Sized, c.Container, str])
self.assertEqual(m, [collections.defaultdict, dict, c.Sized,
c.Container, object])

# MutableSequence below is registered directly on D. In other words, it
# precedes MutableMapping which means single dispatch will always
# choose MutableSequence here.
class D(c.defaultdict):
class D(collections.defaultdict):
pass
c.MutableSequence.register(D)
bases = [c.MutableSequence, c.MutableMapping]
for haystack in permutations(bases):
m = mro(D, bases)
self.assertEqual(m, [D, c.MutableSequence, c.Sequence, c.Reversible,
c.defaultdict, dict, c.MutableMapping, c.Mapping,
collections.defaultdict, dict, c.MutableMapping, c.Mapping,
c.Collection, c.Sized, c.Iterable, c.Container,
object])

# Container and Callable are registered on different base classes and
# a generic function supporting both should always pick the Callable
# implementation if a C instance is passed.
class C(c.defaultdict):
class C(collections.defaultdict):
def __call__(self):
pass
bases = [c.Sized, c.Callable, c.Container, c.Mapping]
for haystack in permutations(bases):
m = mro(C, haystack)
self.assertEqual(m, [C, c.Callable, c.defaultdict, dict, c.Mapping,
self.assertEqual(m, [C, c.Callable, collections.defaultdict, dict, c.Mapping,
c.Collection, c.Sized, c.Iterable,
c.Container, object])

def test_register_abc(self):
c = collections
c = collections.abc
d = {"a": "b"}
l = [1, 2, 3]
s = {object(), None}
Expand All @@ -1786,7 +1787,7 @@ def g(obj):
self.assertEqual(g(s), "sized")
self.assertEqual(g(f), "sized")
self.assertEqual(g(t), "sized")
g.register(c.ChainMap, lambda obj: "chainmap")
g.register(collections.ChainMap, lambda obj: "chainmap")
self.assertEqual(g(d), "mutablemapping") # irrelevant ABCs registered
self.assertEqual(g(l), "sized")
self.assertEqual(g(s), "sized")
Expand Down Expand Up @@ -1854,7 +1855,7 @@ def g(obj):
self.assertEqual(g(t), "tuple")

def test_c3_abc(self):
c = collections
c = collections.abc
mro = functools._c3_mro
class A(object):
pass
Expand Down Expand Up @@ -1895,7 +1896,7 @@ def _(a):
self.assertEqual(fun(aa), 'fun A')

def test_mro_conflicts(self):
c = collections
c = collections.abc
@functools.singledispatch
def g(arg):
return "base"
Expand Down Expand Up @@ -1956,15 +1957,15 @@ def _(arg):
# MutableMapping's bases implicit as well from defaultdict's
# perspective.
with self.assertRaises(RuntimeError) as re_two:
h(c.defaultdict(lambda: 0))
h(collections.defaultdict(lambda: 0))
self.assertIn(
str(re_two.exception),
(("Ambiguous dispatch: <class 'collections.abc.Container'> "
"or <class 'collections.abc.Sized'>"),
("Ambiguous dispatch: <class 'collections.abc.Sized'> "
"or <class 'collections.abc.Container'>")),
)
class R(c.defaultdict):
class R(collections.defaultdict):
pass
c.MutableSequence.register(R)
@functools.singledispatch
Expand Down Expand Up @@ -2041,7 +2042,7 @@ def clear(self):
_orig_wkd = functools.WeakKeyDictionary
td = TracingDict()
functools.WeakKeyDictionary = lambda: td
c = collections
c = collections.abc
@functools.singledispatch
def g(arg):
return "base"
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import sys
import unittest
from test.support.script_helper import assert_python_ok
from collections import Hashable
from collections.abc import Hashable

IS_64BIT = sys.maxsize > 2**32

Expand Down
Loading