Repository: pyqtgraph/pyqtgraph

Issue:
[CI-fail] python3.7 issues deprecation warning for collections.abc
running python3.7 on

https://github.com/pyqtgraph/pyqtgraph/blob/20c74954a5a18ee37958383e0d4e5c4769bd98e5/pyqtgraph/pgcollections.py#L329
generates a warning message 
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

See https://docs.python.org/3/library/collections.abc.html


Discussion:

Resolving patch:
diff --git a/pyqtgraph/graphicsItems/ImageItem.py b/pyqtgraph/graphicsItems/ImageItem.py
--- a/pyqtgraph/graphicsItems/ImageItem.py
+++ b/pyqtgraph/graphicsItems/ImageItem.py
@@ -2,13 +2,17 @@
 
 from ..Qt import QtGui, QtCore
 import numpy as np
-import collections
 from .. import functions as fn
 from .. import debug as debug
 from .GraphicsObject import GraphicsObject
 from ..Point import Point
 from .. import getConfigOption
 
+try:
+    from collections.abc import Callable
+except ImportError:
+    # fallback for python < 3.3
+    from collections import Callable
 
 __all__ = ['ImageItem']
 
@@ -357,7 +361,7 @@ def render(self):
 
         # Request a lookup table if this image has only one channel
         if self.image.ndim == 2 or self.image.shape[2] == 1:
-            if isinstance(self.lut, collections.Callable):
+            if isinstance(self.lut, Callable):
                 lut = self.lut(self.image)
             else:
                 lut = self.lut
@@ -624,7 +628,7 @@ def drawAt(self, pos, ev=None):
         mask = self.drawMask
         src = dk
 
-        if isinstance(self.drawMode, collections.Callable):
+        if isinstance(self.drawMode, Callable):
             self.drawMode(dk, self.image, mask, ss, ts, ev)
         else:
             src = src[ss]
diff --git a/pyqtgraph/pgcollections.py b/pyqtgraph/pgcollections.py
--- a/pyqtgraph/pgcollections.py
+++ b/pyqtgraph/pgcollections.py
@@ -10,15 +10,22 @@
   - ThreadsafeDict, ThreadsafeList - Self-mutexed data structures
 """
 
-import threading, sys, copy, collections
-#from debug import *
+import threading
+import sys
+import copy
 
 try:
     from collections import OrderedDict
 except ImportError:
     # fallback: try to use the ordereddict backport when using python 2.6
     from ordereddict import OrderedDict
-        
+
+try:
+    from collections.abc import Sequence
+except ImportError:
+    # fallback for python < 3.3
+    from collections import Sequence
+
 
 class ReverseDict(dict):
     """extends dict so that reverse lookups are possible by requesting the key as a list of length 1:
@@ -326,7 +333,7 @@ def __deepcopy__(self, memo):
 
 
             
-class ProtectedList(collections.Sequence):
+class ProtectedList(Sequence):
     """
     A class allowing read-only 'view' of a list or dict. 
     The object can be treated like a normal list, but will never modify the original list it points to.
@@ -408,7 +415,7 @@ def poop(self):
         raise Exception("This is a list. It does not poop.")
 
 
-class ProtectedTuple(collections.Sequence):
+class ProtectedTuple(Sequence):
     """
     A class allowing read-only 'view' of a tuple.
     The object can be treated like a normal tuple, but its contents will be returned as protected objects.


Test patch: