"""Various utility functions."""from collections import namedtuple, Counterfrom os.path import commonprefix__unittest = True_MAX_LENGTH = 80_PLACEHOLDER_LEN = 12_MIN_BEGIN_LEN = 5_MIN_END_LEN = 5_MIN_COMMON_LEN = 5_MIN_DIFF_LEN = _MAX_LENGTH - \(_MIN_BEGIN_LEN + _PLACEHOLDER_LEN + _MIN_COMMON_LEN +_PLACEHOLDER_LEN + _MIN_END_LEN)assert _MIN_DIFF_LEN >= 0def _shorten(s, prefixlen, suffixlen):skip = len(s) - prefixlen - suffixlenif skip > _PLACEHOLDER_LEN:s = '%s[%d chars]%s' % (s[:prefixlen], skip, s[len(s) - suffixlen:])return sdef _common_shorten_repr(*args):args = tuple(map(safe_repr, args))maxlen = max(map(len, args))if maxlen <= _MAX_LENGTH:return argsprefix = commonprefix(args)prefixlen = len(prefix)common_len = _MAX_LENGTH - \(maxlen - prefixlen + _MIN_BEGIN_LEN + _PLACEHOLDER_LEN)if common_len > _MIN_COMMON_LEN:assert _MIN_BEGIN_LEN + _PLACEHOLDER_LEN + _MIN_COMMON_LEN + \(maxlen - prefixlen) < _MAX_LENGTHprefix = _shorten(prefix, _MIN_BEGIN_LEN, common_len)return tuple(prefix + s[prefixlen:] for s in args)prefix = _shorten(prefix, _MIN_BEGIN_LEN, _MIN_COMMON_LEN)return tuple(prefix + _shorten(s[prefixlen:], _MIN_DIFF_LEN, _MIN_END_LEN)for s in args)def safe_repr(obj, short=False):try:result = repr(obj)except Exception:result = object.__repr__(obj)if not short or len(result) < _MAX_LENGTH:return resultreturn result[:_MAX_LENGTH] + ' [truncated]...'def strclass(cls):return "%s.%s" % (cls.__module__, cls.__qualname__)def sorted_list_difference(expected, actual):"""Finds elements in only one or the other of two, sorted input lists.Returns a two-element tuple of lists. The first list contains thoseelements in the "expected" list but not in the "actual" list, and thesecond contains those elements in the "actual" list but not in the"expected" list. Duplicate elements in either input list are ignored."""i = j = 0missing = []unexpected = []while True:try:e = expected[i]a = actual[j]if e < a:missing.append(e)i += 1while expected[i] == e:i += 1elif e > a:unexpected.append(a)j += 1while actual[j] == a:j += 1else:i += 1try:while expected[i] == e:i += 1finally:j += 1while actual[j] == a:j += 1except IndexError:missing.extend(expected[i:])unexpected.extend(actual[j:])breakreturn missing, unexpecteddef unorderable_list_difference(expected, actual):"""Same behavior as sorted_list_difference butfor lists of unorderable items (like dicts).As it does a linear search per item (remove) ithas O(n*n) performance."""missing = []while expected:item = expected.pop()try:actual.remove(item)except ValueError:missing.append(item)# anything left in actual is unexpectedreturn missing, actualdef three_way_cmp(x, y):"""Return -1 if x < y, 0 if x == y and 1 if x > y"""return (x > y) - (x < y)_Mismatch = namedtuple('Mismatch', 'actual expected value')def _count_diff_all_purpose(actual, expected):'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ'# elements need not be hashables, t = list(actual), list(expected)m, n = len(s), len(t)NULL = object()result = []for i, elem in enumerate(s):if elem is NULL:continuecnt_s = cnt_t = 0for j in range(i, m):if s[j] == elem:cnt_s += 1s[j] = NULLfor j, other_elem in enumerate(t):if other_elem == elem:cnt_t += 1t[j] = NULLif cnt_s != cnt_t:diff = _Mismatch(cnt_s, cnt_t, elem)result.append(diff)for i, elem in enumerate(t):if elem is NULL:continuecnt_t = 0for j in range(i, n):if t[j] == elem:cnt_t += 1t[j] = NULLdiff = _Mismatch(0, cnt_t, elem)result.append(diff)return resultdef _count_diff_hashable(actual, expected):'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ'# elements must be hashables, t = Counter(actual), Counter(expected)result = []for elem, cnt_s in s.items():cnt_t = t.get(elem, 0)if cnt_s != cnt_t:diff = _Mismatch(cnt_s, cnt_t, elem)result.append(diff)for elem, cnt_t in t.items():if elem not in s:diff = _Mismatch(0, cnt_t, elem)result.append(diff)return result
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。