| 377 | |
| 378 | |
| 379 | def colorize_pytest_error(text): |
| 380 | error_prefix = "E " |
| 381 | blocks = [text] |
| 382 | |
| 383 | while True: |
| 384 | text = blocks.pop() |
| 385 | |
| 386 | err_start = text.find(error_prefix, 1) |
| 387 | if err_start == -1: |
| 388 | return ''.join(blocks + [text]) |
| 389 | |
| 390 | for pos in range(err_start + 1, len(text) - 1): |
| 391 | if text[pos] == '\n': |
| 392 | if not text[pos + 1 :].startswith(error_prefix): |
| 393 | err_end = pos + 1 |
| 394 | break |
| 395 | else: |
| 396 | err_end = len(text) |
| 397 | |
| 398 | bt, error, tail = text[:err_start], text[err_start:err_end], text[err_end:] |
| 399 | |
| 400 | filters = [ |
| 401 | # File path, line number and function name |
| 402 | ( |
| 403 | re.compile(r"^(.*?):(\d+): in (\S+)", flags=re.MULTILINE), |
| 404 | r"[[unimp]]\1[[rst]]:[[alt2]]\2[[rst]]: in [[alt1]]\3[[rst]]", |
| 405 | ), |
| 406 | ] |
| 407 | for regex, substitution in filters: |
| 408 | bt = regex.sub(substitution, bt) |
| 409 | |
| 410 | blocks.append(bt) |
| 411 | blocks.append('[[bad]]' + error) |
| 412 | blocks.append(tail) |