pyobjcomparer.py (2881B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\brennivin\pyobjcomparer.py 2 from pprint import pformat as _pformat 3 from . import compat as _compat 4 TOLERANCE = 0.0001 5 6 def _check_type(b, type_, breadcrumb): 7 if not isinstance(b, type_): 8 breadcrumb.append('%s is not a %s' % (type(b).__name__, type_.__name__)) 9 return False 10 return True 11 12 13 def _compare_default(a, b, breadcrumb): 14 if a != b: 15 breadcrumb.append('%r != %r' % (a, b)) 16 return False 17 return True 18 19 20 def _compare_number(a, b, breadcrumb): 21 if abs(a - b) >= TOLERANCE: 22 breadcrumb.append('%r != %r' % (a, b)) 23 return False 24 return True 25 26 27 def _compare_set(a, b, breadcrumb): 28 if not _check_type(b, set, breadcrumb): 29 return False 30 a = sorted(a) 31 b = sorted(b) 32 return _compare(a, b, breadcrumb) 33 34 35 def _compare_tuple(a, b, breadcrumb): 36 if not _check_type(b, tuple, breadcrumb): 37 return False 38 return _compare(list(a), list(b), breadcrumb) 39 40 41 def _compare_list(a, b, breadcrumb): 42 if not _check_type(b, list, breadcrumb): 43 return False 44 if len(a) != len(b): 45 breadcrumb.append('len neq (%s != %s)' % (len(a), len(b))) 46 return False 47 for i, (aitem, bitem) in enumerate(zip(a, b)): 48 eq = _compare(aitem, bitem, breadcrumb) 49 if not eq: 50 breadcrumb.append(i) 51 return False 52 53 return True 54 55 56 def _compare_dict(a, b, breadcrumb): 57 if not _check_type(b, dict, breadcrumb): 58 return False 59 sorted_a_keys = sorted(a.keys()) 60 sorted_b_keys = sorted(b.keys()) 61 eq = _compare(sorted_a_keys, sorted_b_keys, breadcrumb) 62 if not eq: 63 return False 64 for akey, bkey in zip(sorted_a_keys, sorted_b_keys): 65 aval = a[akey] 66 bval = b[bkey] 67 eq = _compare(aval, bval, breadcrumb) 68 if not eq: 69 breadcrumb.append(akey) 70 return False 71 72 return True 73 74 75 MAP = {int: _compare_number, 76 str: _compare_default, 77 _compat.long: _compare_number, 78 set: _compare_set, 79 list: _compare_list, 80 tuple: _compare_tuple, 81 dict: _compare_dict, 82 float: _compare_number, 83 object: _compare_default} 84 85 def compare(a, b): 86 return _compare(a, b, []) 87 88 89 def _compare(a, b, breadcrumb): 90 comparer_func = MAP.get(type(a), _compare_default) 91 eq = comparer_func(a, b, breadcrumb) 92 return eq 93 94 95 def get_compound_diff(a, b): 96 crumbs = [] 97 eq = _compare(a, b, crumbs) 98 crumbs.reverse() 99 if not eq and not crumbs: 100 return [a, b] 101 return crumbs 102 103 104 def assert_compare(a, b, print_objs = True): 105 path = get_compound_diff(a, b) 106 if path: 107 contents = ['Value at path %s does not match.' % path] 108 if print_objs: 109 contents.append('a: %s' % _pformat(a)) 110 contents.append('b: %s' % _pformat(b)) 111 raise AssertionError('\n'.join(contents))