(first_error: BaseException, second_error: BaseException | None = None)
| 244 | |
| 245 | |
| 246 | def _raise_chained_errors(first_error: BaseException, second_error: BaseException | None = None) -> NoReturn: |
| 247 | if second_error is None: |
| 248 | first_context = first_error.__context__ |
| 249 | try: |
| 250 | raise first_error # ruff:ignore[raise-within-try] # the handler restores caller-supplied context before propagation |
| 251 | except BaseException: |
| 252 | first_error.__context__ = first_context |
| 253 | raise |
| 254 | if (second_context := second_error.__context__) is not None and second_context is not first_error: |
| 255 | _detach_exception_context(second_context, first_error) |
| 256 | _append_exception_context(first_error, second_context) |
| 257 | first_context = first_error.__context__ |
| 258 | try: |
| 259 | raise first_error # ruff:ignore[raise-within-try] # the second raise needs this error as implicit context |
| 260 | except BaseException: # ruff:ignore[blind-except] # first_error may be a control-flow exception |
| 261 | first_error.__context__ = first_context |
| 262 | try: |
| 263 | raise second_error # ruff:ignore[raise-within-try] # the handler makes the chain interpreter-independent |
| 264 | except BaseException: |
| 265 | second_error.__context__ = first_error |
| 266 | first_error.__context__ = first_context |
| 267 | raise |
| 268 | |
| 269 | |
| 270 | def _detach_exception_context(error: BaseException, target: BaseException) -> None: |
no test coverage detected