In Python 3.3 "abstract base classes" in collections
(like MutableMapping
or MutableSequence
) were moved to second-level module collections.abc
. So in Python 3.3+ the real type is collections.abc.MutableMapping
and so on. Documentation states that the old alias names (e.g. collections.MutableMapping
) will be available up to Python 3.7 (currently the latest version), however in 3.8 these aliases will be removed.
Current version of Python 3.7 even produces a warning when you use the alias names:
./scripts/generateBoard.py:145: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
elif isinstance(value, (collections.MutableMapping, collections.MutableSequence)) == True:
In python 2.7 there is no collections.abc
.
How can Python script handle this difference in the most convenient way, when it is meant to be used with (almost) any Python version? I'm looking for a solution which would ideally solve this mess in one central place, without having to use try: ... except: ...
all over the script everywhere I need this type?
Place this at the top of the script:
import collections
try:
collectionsAbc = collections.abc
except AttributeError:
collectionsAbc = collections
Then change all prefixes of the abstract base types, e.g. change collections.abc.MutableMapping
or collections.MutableMapping
to collectionsAbc.MutableMapping
.
Alternatively, import what you require in the script at the top in a single place:
try:
from collections.abc import Callable # noqa
except ImportError:
from collections import Callable # noqa