| | from __future__ import annotations |
| |
|
| | import sys |
| | from collections.abc import Generator |
| | from textwrap import dedent |
| | from typing import Any |
| |
|
| | if sys.version_info < (3, 11): |
| | from exceptiongroup import BaseExceptionGroup |
| |
|
| |
|
| | class BrokenResourceError(Exception): |
| | """ |
| | Raised when trying to use a resource that has been rendered unusable due to external |
| | causes (e.g. a send stream whose peer has disconnected). |
| | """ |
| |
|
| |
|
| | class BrokenWorkerProcess(Exception): |
| | """ |
| | Raised by :meth:`~anyio.to_process.run_sync` if the worker process terminates abruptly or |
| | otherwise misbehaves. |
| | """ |
| |
|
| |
|
| | class BrokenWorkerInterpreter(Exception): |
| | """ |
| | Raised by :meth:`~anyio.to_interpreter.run_sync` if an unexpected exception is |
| | raised in the subinterpreter. |
| | """ |
| |
|
| | def __init__(self, excinfo: Any): |
| | |
| | msg = excinfo.formatted |
| | if not msg: |
| | if excinfo.type and excinfo.msg: |
| | msg = f"{excinfo.type.__name__}: {excinfo.msg}" |
| | else: |
| | msg = excinfo.type.__name__ or excinfo.msg |
| |
|
| | super().__init__(msg) |
| | self.excinfo = excinfo |
| |
|
| | def __str__(self) -> str: |
| | try: |
| | formatted = self.excinfo.errdisplay |
| | except Exception: |
| | return super().__str__() |
| | else: |
| | return dedent( |
| | f""" |
| | {super().__str__()} |
| | |
| | Uncaught in the interpreter: |
| | |
| | {formatted} |
| | """.strip() |
| | ) |
| |
|
| |
|
| | class BusyResourceError(Exception): |
| | """ |
| | Raised when two tasks are trying to read from or write to the same resource |
| | concurrently. |
| | """ |
| |
|
| | def __init__(self, action: str): |
| | super().__init__(f"Another task is already {action} this resource") |
| |
|
| |
|
| | class ClosedResourceError(Exception): |
| | """Raised when trying to use a resource that has been closed.""" |
| |
|
| |
|
| | class ConnectionFailed(OSError): |
| | """ |
| | Raised when a connection attempt fails. |
| | |
| | .. note:: This class inherits from :exc:`OSError` for backwards compatibility. |
| | """ |
| |
|
| |
|
| | def iterate_exceptions( |
| | exception: BaseException, |
| | ) -> Generator[BaseException, None, None]: |
| | if isinstance(exception, BaseExceptionGroup): |
| | for exc in exception.exceptions: |
| | yield from iterate_exceptions(exc) |
| | else: |
| | yield exception |
| |
|
| |
|
| | class DelimiterNotFound(Exception): |
| | """ |
| | Raised during |
| | :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the |
| | maximum number of bytes has been read without the delimiter being found. |
| | """ |
| |
|
| | def __init__(self, max_bytes: int) -> None: |
| | super().__init__( |
| | f"The delimiter was not found among the first {max_bytes} bytes" |
| | ) |
| |
|
| |
|
| | class EndOfStream(Exception): |
| | """ |
| | Raised when trying to read from a stream that has been closed from the other end. |
| | """ |
| |
|
| |
|
| | class IncompleteRead(Exception): |
| | """ |
| | Raised during |
| | :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or |
| | :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the |
| | connection is closed before the requested amount of bytes has been read. |
| | """ |
| |
|
| | def __init__(self) -> None: |
| | super().__init__( |
| | "The stream was closed before the read operation could be completed" |
| | ) |
| |
|
| |
|
| | class TypedAttributeLookupError(LookupError): |
| | """ |
| | Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute |
| | is not found and no default value has been given. |
| | """ |
| |
|
| |
|
| | class WouldBlock(Exception): |
| | """Raised by ``X_nowait`` functions if ``X()`` would block.""" |
| |
|
| |
|
| | class NoEventLoopError(RuntimeError): |
| | """ |
| | Raised by several functions that require an event loop to be running in the current |
| | thread when there is no running event loop. |
| | |
| | This is also raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync` |
| | if not calling from an AnyIO worker thread, and no ``token`` was passed. |
| | """ |
| |
|
| |
|
| | class RunFinishedError(RuntimeError): |
| | """ |
| | Raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync` if the event |
| | loop associated with the explicitly passed token has already finished. |
| | """ |
| |
|
| | def __init__(self) -> None: |
| | super().__init__( |
| | "The event loop associated with the given token has already finished" |
| | ) |
| |
|