|
9 | 9 |
|
10 | 10 | import _pytest._code
|
11 | 11 | from ..compat import Sequence
|
| 12 | +from _pytest import outcomes |
12 | 13 | from _pytest._io.saferepr import saferepr
|
13 | 14 |
|
14 | 15 | # The _reprcompare attribute on the util module is used by the new assertion
|
@@ -102,38 +103,45 @@ def _format_lines(lines):
|
102 | 103 | basestring = str
|
103 | 104 |
|
104 | 105 |
|
105 |
| -def assertrepr_compare(config, op, left, right): |
106 |
| - """Return specialised explanations for some operators/operands""" |
107 |
| - width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op |
108 |
| - left_repr = saferepr(left, maxsize=int(width // 2)) |
109 |
| - right_repr = saferepr(right, maxsize=width - len(left_repr)) |
| 106 | +def issequence(x): |
| 107 | + return isinstance(x, Sequence) and not isinstance(x, basestring) |
| 108 | + |
| 109 | + |
| 110 | +def istext(x): |
| 111 | + return isinstance(x, basestring) |
| 112 | + |
| 113 | + |
| 114 | +def isdict(x): |
| 115 | + return isinstance(x, dict) |
110 | 116 |
|
111 |
| - summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr)) |
112 | 117 |
|
113 |
| - def issequence(x): |
114 |
| - return isinstance(x, Sequence) and not isinstance(x, basestring) |
| 118 | +def isset(x): |
| 119 | + return isinstance(x, (set, frozenset)) |
115 | 120 |
|
116 |
| - def istext(x): |
117 |
| - return isinstance(x, basestring) |
118 | 121 |
|
119 |
| - def isdict(x): |
120 |
| - return isinstance(x, dict) |
| 122 | +def isdatacls(obj): |
| 123 | + return getattr(obj, "__dataclass_fields__", None) is not None |
121 | 124 |
|
122 |
| - def isset(x): |
123 |
| - return isinstance(x, (set, frozenset)) |
124 | 125 |
|
125 |
| - def isdatacls(obj): |
126 |
| - return getattr(obj, "__dataclass_fields__", None) is not None |
| 126 | +def isattrs(obj): |
| 127 | + return getattr(obj, "__attrs_attrs__", None) is not None |
127 | 128 |
|
128 |
| - def isattrs(obj): |
129 |
| - return getattr(obj, "__attrs_attrs__", None) is not None |
130 | 129 |
|
131 |
| - def isiterable(obj): |
132 |
| - try: |
133 |
| - iter(obj) |
134 |
| - return not istext(obj) |
135 |
| - except TypeError: |
136 |
| - return False |
| 130 | +def isiterable(obj): |
| 131 | + try: |
| 132 | + iter(obj) |
| 133 | + return not istext(obj) |
| 134 | + except TypeError: |
| 135 | + return False |
| 136 | + |
| 137 | + |
| 138 | +def assertrepr_compare(config, op, left, right): |
| 139 | + """Return specialised explanations for some operators/operands""" |
| 140 | + width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op |
| 141 | + left_repr = saferepr(left, maxsize=int(width // 2)) |
| 142 | + right_repr = saferepr(right, maxsize=width - len(left_repr)) |
| 143 | + |
| 144 | + summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr)) |
137 | 145 |
|
138 | 146 | verbose = config.getoption("verbose")
|
139 | 147 | explanation = None
|
@@ -162,6 +170,8 @@ def isiterable(obj):
|
162 | 170 | elif op == "not in":
|
163 | 171 | if istext(left) and istext(right):
|
164 | 172 | explanation = _notin_text(left, right, verbose)
|
| 173 | + except outcomes.Exit: |
| 174 | + raise |
165 | 175 | except Exception:
|
166 | 176 | explanation = [
|
167 | 177 | u"(pytest_assertion plugin: representation of details failed. "
|
|
0 commit comments