NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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))