(self, exctype, value, tb, test)
| 208 | return ''.join(msgLines) |
| 209 | |
| 210 | def _clean_tracebacks(self, exctype, value, tb, test): |
| 211 | ret = None |
| 212 | first = True |
| 213 | excs = [(exctype, value, tb)] |
| 214 | seen = {id(value)} # Detect loops in chained exceptions. |
| 215 | while excs: |
| 216 | (exctype, value, tb) = excs.pop() |
| 217 | # Skip test runner traceback levels |
| 218 | while tb and self._is_relevant_tb_level(tb): |
| 219 | tb = tb.tb_next |
| 220 | |
| 221 | # Skip assert*() traceback levels |
| 222 | if exctype is test.failureException: |
| 223 | self._remove_unittest_tb_frames(tb) |
| 224 | |
| 225 | if first: |
| 226 | ret = tb |
| 227 | first = False |
| 228 | else: |
| 229 | value.__traceback__ = tb |
| 230 | |
| 231 | if value is not None: |
| 232 | for c in (value.__cause__, value.__context__): |
| 233 | if c is not None and id(c) not in seen: |
| 234 | excs.append((type(c), c, c.__traceback__)) |
| 235 | seen.add(id(c)) |
| 236 | return ret |
| 237 | |
| 238 | def _is_relevant_tb_level(self, tb): |
| 239 | return '__unittest' in tb.tb_frame.f_globals |
no test coverage detected