diff --git a/falcon/stream.py b/falcon/stream.py index d76a8b06d..c300ee98a 100644 --- a/falcon/stream.py +++ b/falcon/stream.py @@ -14,11 +14,17 @@ """WSGI BoundedStream class.""" +from __future__ import annotations + import io +from typing import BinaryIO, Callable, List, Optional, TypeVar, Union __all__ = ['BoundedStream'] +Result = TypeVar('Result', bound=Union[bytes, List[bytes]]) + + class BoundedStream(io.IOBase): """Wrap *wsgi.input* streams to make them more robust. @@ -45,21 +51,21 @@ class BoundedStream(io.IOBase): """ - def __init__(self, stream, stream_len): + def __init__(self, stream: BinaryIO, stream_len: int) -> None: self.stream = stream self.stream_len = stream_len self._bytes_remaining = self.stream_len - def __iter__(self): + def __iter__(self) -> BoundedStream: return self - def __next__(self): + def __next__(self) -> bytes: return next(self.stream) next = __next__ - def _read(self, size, target): + def _read(self, size: Optional[int], target: Callable[[int], Result]) -> Result: """Proxy reads to the underlying stream. Args: @@ -85,19 +91,19 @@ def _read(self, size, target): self._bytes_remaining -= size return target(size) - def readable(self): + def readable(self) -> bool: """Return ``True`` always.""" return True - def seekable(self): + def seekable(self) -> bool: """Return ``False`` always.""" return False - def writable(self): + def writable(self) -> bool: """Return ``False`` always.""" return False - def read(self, size=None): + def read(self, size: Optional[int] = None) -> bytes: """Read from the stream. Args: @@ -111,7 +117,7 @@ def read(self, size=None): return self._read(size, self.stream.read) - def readline(self, limit=None): + def readline(self, limit: Optional[int] = None) -> bytes: """Read a line from the stream. Args: @@ -125,7 +131,7 @@ def readline(self, limit=None): return self._read(limit, self.stream.readline) - def readlines(self, hint=None): + def readlines(self, hint: Optional[int] = None) -> List[bytes]: """Read lines from the stream. Args: @@ -139,12 +145,12 @@ def readlines(self, hint=None): return self._read(hint, self.stream.readlines) - def write(self, data): + def write(self, data: bytes) -> None: """Raise IOError always; writing is not supported.""" raise IOError('Stream is not writeable') - def exhaust(self, chunk_size=64 * 1024): + def exhaust(self, chunk_size: int = 64 * 1024) -> None: """Exhaust the stream. This consumes all the data left until the limit is reached. @@ -159,7 +165,7 @@ def exhaust(self, chunk_size=64 * 1024): break @property - def eof(self): + def eof(self) -> bool: return self._bytes_remaining <= 0 is_exhausted = eof diff --git a/pyproject.toml b/pyproject.toml index b386f7a2f..f3d986b06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ [tool.mypy] exclude = "falcon/bench/|falcon/cmd/" - [[tool.mypy.overrides]] module = [ "cbor2", @@ -34,6 +33,12 @@ ] ignore_missing_imports = true + [[tool.mypy.overrides]] + module = [ + "falcon.stream" + ] + disallow_untyped_defs = true + [tool.towncrier] package = "falcon" package_dir = ""