(config: Config)
| 45 | |
| 46 | |
| 47 | def collect_unraisable(config: Config) -> None: |
| 48 | pop_unraisable = config.stash[unraisable_exceptions].pop |
| 49 | errors: list[pytest.PytestUnraisableExceptionWarning | RuntimeError] = [] |
| 50 | meta = None |
| 51 | hook_error = None |
| 52 | try: |
| 53 | while True: |
| 54 | try: |
| 55 | meta = pop_unraisable() |
| 56 | except IndexError: |
| 57 | break |
| 58 | |
| 59 | if isinstance(meta, BaseException): |
| 60 | hook_error = RuntimeError(class="st">"Failed to process unraisable exception") |
| 61 | hook_error.__cause__ = meta |
| 62 | errors.append(hook_error) |
| 63 | continue |
| 64 | |
| 65 | msg = meta.msg |
| 66 | try: |
| 67 | warnings.warn(pytest.PytestUnraisableExceptionWarning(msg)) |
| 68 | except pytest.PytestUnraisableExceptionWarning as e: |
| 69 | class="cm"># This except happens when the warning is treated as an error (e.g. `-Werror`). |
| 70 | if meta.exc_value is not None: |
| 71 | class="cm"># Exceptions have a better way to show the traceback, but |
| 72 | class="cm"># warnings do not, so hide the traceback from the msg and |
| 73 | class="cm"># set the cause so the traceback shows up in the right place. |
| 74 | e.args = (meta.cause_msg,) |
| 75 | e.__cause__ = meta.exc_value |
| 76 | errors.append(e) |
| 77 | |
| 78 | if len(errors) == 1: |
| 79 | raise errors[0] |
| 80 | if errors: |
| 81 | raise ExceptionGroup(class="st">"multiple unraisable exception warnings", errors) |
| 82 | finally: |
| 83 | del errors, meta, hook_error |
| 84 | |
| 85 | |
| 86 | def cleanup( |
no test coverage detected