class_docstr: Widget for displaying differences between hierarchical python data structures
  (eg, nested dicts, lists, and arrays)
docstr: Compare data structure *a* to structure *b*. 
  
  Return True if the objects match completely. 
  Otherwise, return a structure that describes the differences:
  
      { 'type': bool
        'len': bool,
        'str': bool,
        'shape': bool,
        'dtype': bool,
        'mask': array,
        }
  
          
code: def compare(self, a, b, path=()):
      """
      Compare data structure *a* to structure *b*.
  
      Return True if the objects match completely.
      Otherwise, return a structure that describes the differences:
  
          { 'type': bool
            'len': bool,
            'str': bool,
            'shape': bool,
            'dtype': bool,
            'mask': array,
            }
  
  
      """
      bad = (255, 200, 200)
      # generate typestr, desc, childs for each object
      typeA, descA, childsA, _ = self.trees[0].parse(a)
      typeB, descB, childsB, _ = self.trees[1].parse(b)
  
      if typeA != typeB:
          self.setColor(path, 1, bad)
      if descA != descB:
          self.setColor(path, 2, bad)
  
      if isinstance(a, dict) and isinstance(b, dict):
          keysA = set(a.keys())
          keysB = set(b.keys())
          for key in keysA - keysB:
              self.setColor(path + (key,), 0, bad, tree=0)
          for key in keysB - keysA:
              self.setColor(path + (key,), 0, bad, tree=1)
          for key in keysA & keysB:
              self.compare(a[key], b[key], path + (key,))
  
      elif isinstance(a, (list, tuple)) and isinstance(
          b, (list, tuple)
      ):
          for i in range(max(len(a), len(b))):
              if len(a) <= i:
                  self.setColor(path + (i,), 0, bad, tree=1)
              elif len(b) <= i:
                  self.setColor(path + (i,), 0, bad, tree=0)
              else:
                  self.compare(a[i], b[i], path + (i,))
  
      elif (
          isinstance(a, np.ndarray)
          and isinstance(b, np.ndarray)
          and a.shape == b.shape
      ):
          tableNodes = [
              tree.nodes[path].child(0) for tree in self.trees
          ]
          if a.dtype.fields is None and b.dtype.fields is None:
              eq = self.compareArrays(a, b)
              if not np.all(eq):
                  for n in tableNodes:
                      n.setBackground(0, fn.mkBrush(bad))
              # for i in np.argwhere(~eq):
  
          else:
              if a.dtype == b.dtype:
                  for i, k in enumerate(a.dtype.fields.keys()):
                      eq = self.compareArrays(a[k], b[k])
                      if not np.all(eq):
                          for n in tableNodes:
                              n.setBackground(0, fn.mkBrush(bad))
  
file_path: pyqtgraph/pyqtgraph/widgets/DiffTreeWidget.py
imports: import numpy
  from ..None import functions
  from ..Qt import QtWidgets
  from .DataTreeWidget import DataTreeWidget
label_desc: Use image node_id 3 for calling the DiffTreeWidget obj's underlying member method code with example usage: obj.compare(a, b, path) without return types