How to use collections.abc from both Python 3.8+ and Python 2.7
Question:
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?
Answers:
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
Looks like fresh version of the six module have collections_abc
alias, so you can use:
from six.moves import collections_abc
One way to solve this is to simply try to get abc
from collections
, else assume the members of abc
are already in collections
.
import collections
collections_abc = getattr(collections, 'abc', collections)
I was getting error like this:
C:Usersgsc-30431Anaconda3libsite-packagesunittest2compatibility.py:148
C:Usersgsc-30431Anaconda3libsite-packagesunittest2compatibility.py:148: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is depr
ecated since Python 3.3,and in 3.9 it will stop working
class ChainMap(collections.MutableMapping):
-- Docs: https://docs.pytest.org/en/latest/warnings.html
SO i opened the File Compatibility.py
by visiting the path showing in the error above! and Searched there the code where this Collections package is being used and Changed the previous line i.e:
class ChainMap(collections.MutableMapping):
to new Line:
class ChainMap(collections.abc.MutableMapping):
Just by adding .abc has solved my problem and i’m not getting warning anymore!
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
Looks like fresh version of the six module have collections_abc
alias, so you can use:
from six.moves import collections_abc
One way to solve this is to simply try to get abc
from collections
, else assume the members of abc
are already in collections
.
import collections
collections_abc = getattr(collections, 'abc', collections)
I was getting error like this:
C:Usersgsc-30431Anaconda3libsite-packagesunittest2compatibility.py:148
C:Usersgsc-30431Anaconda3libsite-packagesunittest2compatibility.py:148: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is depr
ecated since Python 3.3,and in 3.9 it will stop working
class ChainMap(collections.MutableMapping):
-- Docs: https://docs.pytest.org/en/latest/warnings.html
SO i opened the File Compatibility.py
by visiting the path showing in the error above! and Searched there the code where this Collections package is being used and Changed the previous line i.e:
class ChainMap(collections.MutableMapping):
to new Line:
class ChainMap(collections.abc.MutableMapping):
Just by adding .abc has solved my problem and i’m not getting warning anymore!