From 542f4b446b98e26a08d1a815e0534578a06ed0d1 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Fri, 3 Aug 2018 18:18:28 -0700 Subject: [PATCH] Add eq() support for comparing dict, list, tuple --- pyqtgraph/functions.py | 20 ++++++++++++++++++++ pyqtgraph/tests/test_functions.py | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index 5cbb177e..ef2d7449 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -424,6 +424,8 @@ def eq(a, b): 3. When comparing arrays, returns False if the array shapes are not the same. 4. When comparing arrays of the same shape, returns True only if all elements are equal (whereas the == operator would return a boolean array). + 5. Collections (dict, list, etc.) must have the same type to be considered equal. One + consequence is that comparing a dict to an OrderedDict will always return False. """ if a is b: return True @@ -440,6 +442,24 @@ def eq(a, b): if aIsArr and bIsArr and (a.shape != b.shape or a.dtype != b.dtype): return False + # Recursively handle common containers + if isinstance(a, dict) and isinstance(b, dict): + if type(a) != type(b) or len(a) != len(b): + return False + if a.keys() != b.keys(): + return False + for k,v in a.items(): + if not eq(v, b[k]): + return False + return True + if isinstance(a, (list, tuple)) and isinstance(b, (list, tuple)): + if type(a) != type(b) or len(a) != len(b): + return False + for v1,v2 in zip(a, b): + if not eq(v1, v2): + return False + return True + # Test for equivalence. # If the test raises a recognized exception, then return Falase try: diff --git a/pyqtgraph/tests/test_functions.py b/pyqtgraph/tests/test_functions.py index e013fe42..fcd16254 100644 --- a/pyqtgraph/tests/test_functions.py +++ b/pyqtgraph/tests/test_functions.py @@ -1,11 +1,15 @@ import pyqtgraph as pg import numpy as np import sys +from copy import deepcopy +from collections import OrderedDict from numpy.testing import assert_array_almost_equal, assert_almost_equal import pytest + np.random.seed(12345) + def testSolve3D(): p1 = np.array([[0,0,0,1], [1,0,0,1], @@ -356,6 +360,29 @@ def test_eq(): assert eq(a4, a4.copy()) assert not eq(a4, a4.T) + # test containers + + assert not eq({'a': 1}, {'a': 1, 'b': 2}) + assert not eq({'a': 1}, {'a': 2}) + d1 = {'x': 1, 'y': np.nan, 3: ['a', np.nan, a3, 7, 2.3], 4: a4} + d2 = deepcopy(d1) + assert eq(d1, d2) + assert eq(OrderedDict(d1), OrderedDict(d2)) + assert not eq(OrderedDict(d1), d2) + items = list(d1.items()) + assert not eq(OrderedDict(items), OrderedDict(reversed(items))) + + assert not eq([1,2,3], [1,2,3,4]) + l1 = [d1, np.inf, -np.inf, np.nan] + l2 = deepcopy(l1) + t1 = tuple(l1) + t2 = tuple(l2) + assert eq(l1, l2) + assert eq(t1, t2) + + assert eq(set(range(10)), set(range(10))) + assert not eq(set(range(10)), set(range(9))) + if __name__ == '__main__': test_interpolateArray() \ No newline at end of file