Browse Source

fix(python): fix deprecated collections.abc usage (#5195)

Many classes within collections were moved to collections.abc in Python
3.3 -- their usage as imported directly from collections is now
deprecated as of Python 3.7 and will be removed soon.

The fallback import added in this PR can be removed entirely when
support for versions of Python prior to 3.3 is dropped.
Kevin James 7 năm trước cách đây
mục cha
commit
f50a1f843e

+ 13 - 9
python/google/protobuf/internal/containers.py

@@ -41,12 +41,16 @@ are:
 
 
 __author__ = 'petar@google.com (Petar Petrov)'
 __author__ = 'petar@google.com (Petar Petrov)'
 
 
-import collections
+try:
+    # This fallback applies for all versions of Python before 3.3
+    import collections.abc as collections_abc
+except ImportError:
+    import collections as collections_abc
 import sys
 import sys
 
 
 if sys.version_info[0] < 3:
 if sys.version_info[0] < 3:
-  # We would use collections.MutableMapping all the time, but in Python 2 it
-  # doesn't define __slots__.  This causes two significant problems:
+  # We would use collections_abc.MutableMapping all the time, but in Python 2
+  # it doesn't define __slots__.  This causes two significant problems:
   #
   #
   # 1. we can't disallow arbitrary attribute assignment, even if our derived
   # 1. we can't disallow arbitrary attribute assignment, even if our derived
   #    classes *do* define __slots__.
   #    classes *do* define __slots__.
@@ -59,7 +63,7 @@ if sys.version_info[0] < 3:
   # verbatim, except that:
   # verbatim, except that:
   # 1. We declare __slots__.
   # 1. We declare __slots__.
   # 2. We don't declare this as a virtual base class.  The classes defined
   # 2. We don't declare this as a virtual base class.  The classes defined
-  #    in collections are the interesting base classes, not us.
+  #    in collections_abc are the interesting base classes, not us.
   #
   #
   # Note: deriving from object is critical.  It is the only thing that makes
   # Note: deriving from object is critical.  It is the only thing that makes
   # this a true type, allowing us to derive from it in C++ cleanly and making
   # this a true type, allowing us to derive from it in C++ cleanly and making
@@ -106,7 +110,7 @@ if sys.version_info[0] < 3:
     __hash__ = None
     __hash__ = None
 
 
     def __eq__(self, other):
     def __eq__(self, other):
-      if not isinstance(other, collections.Mapping):
+      if not isinstance(other, collections_abc.Mapping):
         return NotImplemented
         return NotImplemented
       return dict(self.items()) == dict(other.items())
       return dict(self.items()) == dict(other.items())
 
 
@@ -173,13 +177,13 @@ if sys.version_info[0] < 3:
         self[key] = default
         self[key] = default
       return default
       return default
 
 
-  collections.Mapping.register(Mapping)
-  collections.MutableMapping.register(MutableMapping)
+  collections_abc.Mapping.register(Mapping)
+  collections_abc.MutableMapping.register(MutableMapping)
 
 
 else:
 else:
   # In Python 3 we can just use MutableMapping directly, because it defines
   # In Python 3 we can just use MutableMapping directly, because it defines
   # __slots__.
   # __slots__.
-  MutableMapping = collections.MutableMapping
+  MutableMapping = collections_abc.MutableMapping
 
 
 
 
 class BaseContainer(object):
 class BaseContainer(object):
@@ -337,7 +341,7 @@ class RepeatedScalarFieldContainer(BaseContainer):
     # We are presumably comparing against some other sequence type.
     # We are presumably comparing against some other sequence type.
     return other == self._values
     return other == self._values
 
 
-collections.MutableSequence.register(BaseContainer)
+collections_abc.MutableSequence.register(BaseContainer)
 
 
 
 
 class RepeatedCompositeFieldContainer(BaseContainer):
 class RepeatedCompositeFieldContainer(BaseContainer):