• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""WSGI-related types for static type checking"""
2
3from collections.abc import Callable, Iterable, Iterator
4from types import TracebackType
5from typing import Any, Protocol, TypeAlias
6
7__all__ = [
8    "StartResponse",
9    "WSGIEnvironment",
10    "WSGIApplication",
11    "InputStream",
12    "ErrorStream",
13    "FileWrapper",
14]
15
16_ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType]
17_OptExcInfo: TypeAlias = _ExcInfo | tuple[None, None, None]
18
19class StartResponse(Protocol):
20    """start_response() callable as defined in PEP 3333"""
21    def __call__(
22        self,
23        status: str,
24        headers: list[tuple[str, str]],
25        exc_info: _OptExcInfo | None = ...,
26        /,
27    ) -> Callable[[bytes], object]: ...
28
29WSGIEnvironment: TypeAlias = dict[str, Any]
30WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse],
31    Iterable[bytes]]
32
33class InputStream(Protocol):
34    """WSGI input stream as defined in PEP 3333"""
35    def read(self, size: int = ..., /) -> bytes: ...
36    def readline(self, size: int = ..., /) -> bytes: ...
37    def readlines(self, hint: int = ..., /) -> list[bytes]: ...
38    def __iter__(self) -> Iterator[bytes]: ...
39
40class ErrorStream(Protocol):
41    """WSGI error stream as defined in PEP 3333"""
42    def flush(self) -> object: ...
43    def write(self, s: str, /) -> object: ...
44    def writelines(self, seq: list[str], /) -> object: ...
45
46class _Readable(Protocol):
47    def read(self, size: int = ..., /) -> bytes: ...
48    # Optional: def close(self) -> object: ...
49
50class FileWrapper(Protocol):
51    """WSGI file wrapper as defined in PEP 3333"""
52    def __call__(
53        self, file: _Readable, block_size: int = ..., /,
54    ) -> Iterable[bytes]: ...
55