xref: /openbsd-src/gnu/llvm/lldb/third_party/Python/module/unittest2/unittest2/util.py (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick"""Various utility functions."""
2*061da546Spatrick
3*061da546Spatrick__unittest = True
4*061da546Spatrick
5*061da546Spatrick
6*061da546Spatrick_MAX_LENGTH = 80
7*061da546Spatrick
8*061da546Spatrick
9*061da546Spatrickdef safe_repr(obj, short=False):
10*061da546Spatrick    try:
11*061da546Spatrick        result = repr(obj)
12*061da546Spatrick    except Exception:
13*061da546Spatrick        result = object.__repr__(obj)
14*061da546Spatrick    if not short or len(result) < _MAX_LENGTH:
15*061da546Spatrick        return result
16*061da546Spatrick    return result[:_MAX_LENGTH] + ' [truncated]...'
17*061da546Spatrick
18*061da546Spatrick
19*061da546Spatrickdef safe_str(obj):
20*061da546Spatrick    try:
21*061da546Spatrick        return str(obj)
22*061da546Spatrick    except Exception:
23*061da546Spatrick        return object.__str__(obj)
24*061da546Spatrick
25*061da546Spatrick
26*061da546Spatrickdef strclass(cls):
27*061da546Spatrick    return "%s.%s" % (cls.__module__, cls.__name__)
28*061da546Spatrick
29*061da546Spatrick
30*061da546Spatrickdef sorted_list_difference(expected, actual):
31*061da546Spatrick    """Finds elements in only one or the other of two, sorted input lists.
32*061da546Spatrick
33*061da546Spatrick    Returns a two-element tuple of lists.    The first list contains those
34*061da546Spatrick    elements in the "expected" list but not in the "actual" list, and the
35*061da546Spatrick    second contains those elements in the "actual" list but not in the
36*061da546Spatrick    "expected" list.    Duplicate elements in either input list are ignored.
37*061da546Spatrick    """
38*061da546Spatrick    i = j = 0
39*061da546Spatrick    missing = []
40*061da546Spatrick    unexpected = []
41*061da546Spatrick    while True:
42*061da546Spatrick        try:
43*061da546Spatrick            e = expected[i]
44*061da546Spatrick            a = actual[j]
45*061da546Spatrick            if e < a:
46*061da546Spatrick                missing.append(e)
47*061da546Spatrick                i += 1
48*061da546Spatrick                while expected[i] == e:
49*061da546Spatrick                    i += 1
50*061da546Spatrick            elif e > a:
51*061da546Spatrick                unexpected.append(a)
52*061da546Spatrick                j += 1
53*061da546Spatrick                while actual[j] == a:
54*061da546Spatrick                    j += 1
55*061da546Spatrick            else:
56*061da546Spatrick                i += 1
57*061da546Spatrick                try:
58*061da546Spatrick                    while expected[i] == e:
59*061da546Spatrick                        i += 1
60*061da546Spatrick                finally:
61*061da546Spatrick                    j += 1
62*061da546Spatrick                    while actual[j] == a:
63*061da546Spatrick                        j += 1
64*061da546Spatrick        except IndexError:
65*061da546Spatrick            missing.extend(expected[i:])
66*061da546Spatrick            unexpected.extend(actual[j:])
67*061da546Spatrick            break
68*061da546Spatrick    return missing, unexpected
69*061da546Spatrick
70*061da546Spatrick
71*061da546Spatrickdef unorderable_list_difference(expected, actual, ignore_duplicate=False):
72*061da546Spatrick    """Same behavior as sorted_list_difference but
73*061da546Spatrick    for lists of unorderable items (like dicts).
74*061da546Spatrick
75*061da546Spatrick    As it does a linear search per item (remove) it
76*061da546Spatrick    has O(n*n) performance.
77*061da546Spatrick    """
78*061da546Spatrick    missing = []
79*061da546Spatrick    unexpected = []
80*061da546Spatrick    while expected:
81*061da546Spatrick        item = expected.pop()
82*061da546Spatrick        try:
83*061da546Spatrick            actual.remove(item)
84*061da546Spatrick        except ValueError:
85*061da546Spatrick            missing.append(item)
86*061da546Spatrick        if ignore_duplicate:
87*061da546Spatrick            for lst in expected, actual:
88*061da546Spatrick                try:
89*061da546Spatrick                    while True:
90*061da546Spatrick                        lst.remove(item)
91*061da546Spatrick                except ValueError:
92*061da546Spatrick                    pass
93*061da546Spatrick    if ignore_duplicate:
94*061da546Spatrick        while actual:
95*061da546Spatrick            item = actual.pop()
96*061da546Spatrick            unexpected.append(item)
97*061da546Spatrick            try:
98*061da546Spatrick                while True:
99*061da546Spatrick                    actual.remove(item)
100*061da546Spatrick            except ValueError:
101*061da546Spatrick                pass
102*061da546Spatrick        return missing, unexpected
103*061da546Spatrick
104*061da546Spatrick    # anything left in actual is unexpected
105*061da546Spatrick    return missing, actual
106