Format: text/x-python
⬇ Download File (3.4 KB)
   1  from __future__ import annotations
   2  
   3  import sys
   4  from collections.abc import Generator
   5  from textwrap import dedent
   6  from typing import Any
   7  
   8  if sys.version_info < (3, 11):
   9      from exceptiongroup import BaseExceptionGroup
  10  
  11  
  12  class BrokenResourceError(Exception):
  13      """
  14      Raised when trying to use a resource that has been rendered unusable due to external
  15      causes (e.g. a send stream whose peer has disconnected).
  16      """
  17  
  18  
  19  class BrokenWorkerProcess(Exception):
  20      """
  21      Raised by :meth:`~anyio.to_process.run_sync` if the worker process terminates abruptly or
  22      otherwise misbehaves.
  23      """
  24  
  25  
  26  class BrokenWorkerIntepreter(Exception):
  27      """
  28      Raised by :meth:`~anyio.to_interpreter.run_sync` if an unexpected exception is
  29      raised in the subinterpreter.
  30      """
  31  
  32      def __init__(self, excinfo: Any):
  33          # This was adapted from concurrent.futures.interpreter.ExecutionFailed
  34          msg = excinfo.formatted
  35          if not msg:
  36              if excinfo.type and excinfo.msg:
  37                  msg = f"{excinfo.type.__name__}: {excinfo.msg}"
  38              else:
  39                  msg = excinfo.type.__name__ or excinfo.msg
  40  
  41          super().__init__(msg)
  42          self.excinfo = excinfo
  43  
  44      def __str__(self) -> str:
  45          try:
  46              formatted = self.excinfo.errdisplay
  47          except Exception:
  48              return super().__str__()
  49          else:
  50              return dedent(
  51                  f"""
  52                  {super().__str__()}
  53  
  54                  Uncaught in the interpreter:
  55  
  56                  {formatted}
  57                  """.strip()
  58              )
  59  
  60  
  61  class BusyResourceError(Exception):
  62      """
  63      Raised when two tasks are trying to read from or write to the same resource
  64      concurrently.
  65      """
  66  
  67      def __init__(self, action: str):
  68          super().__init__(f"Another task is already {action} this resource")
  69  
  70  
  71  class ClosedResourceError(Exception):
  72      """Raised when trying to use a resource that has been closed."""
  73  
  74  
  75  class DelimiterNotFound(Exception):
  76      """
  77      Raised during
  78      :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
  79      maximum number of bytes has been read without the delimiter being found.
  80      """
  81  
  82      def __init__(self, max_bytes: int) -> None:
  83          super().__init__(
  84              f"The delimiter was not found among the first {max_bytes} bytes"
  85          )
  86  
  87  
  88  class EndOfStream(Exception):
  89      """
  90      Raised when trying to read from a stream that has been closed from the other end.
  91      """
  92  
  93  
  94  class IncompleteRead(Exception):
  95      """
  96      Raised during
  97      :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or
  98      :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
  99      connection is closed before the requested amount of bytes has been read.
 100      """
 101  
 102      def __init__(self) -> None:
 103          super().__init__(
 104              "The stream was closed before the read operation could be completed"
 105          )
 106  
 107  
 108  class TypedAttributeLookupError(LookupError):
 109      """
 110      Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute
 111      is not found and no default value has been given.
 112      """
 113  
 114  
 115  class WouldBlock(Exception):
 116      """Raised by ``X_nowait`` functions if ``X()`` would block."""
 117  
 118  
 119  def iterate_exceptions(
 120      exception: BaseException,
 121  ) -> Generator[BaseException, None, None]:
 122      if isinstance(exception, BaseExceptionGroup):
 123          for exc in exception.exceptions:
 124              yield from iterate_exceptions(exc)
 125      else:
 126          yield exception
 127