summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Rittau <srittau@rittau.biz>2022-04-16 17:37:58 (GMT)
committerGitHub <noreply@github.com>2022-04-16 17:37:58 (GMT)
commit0ddc63b240340a952692b11dfe0810973393ed11 (patch)
treeca8613b1571d8ac427cd265b0533072ada253a97
parent1adc837bf1d88a110e1d9e3021abc92b7e7dfa8e (diff)
downloadcpython-0ddc63b240340a952692b11dfe0810973393ed11.zip
cpython-0ddc63b240340a952692b11dfe0810973393ed11.tar.gz
cpython-0ddc63b240340a952692b11dfe0810973393ed11.tar.bz2
gh-86178: Add wsgiref.types (GH-32335)
-rw-r--r--Doc/library/wsgiref.rst68
-rw-r--r--Doc/whatsnew/3.11.rst4
-rw-r--r--Lib/wsgiref/__init__.py2
-rw-r--r--Lib/wsgiref/types.py54
-rw-r--r--Misc/NEWS.d/next/Library/2022-04-05-17-18-13.bpo-42012.zMocQz.rst2
5 files changed, 123 insertions, 7 deletions
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index e924448..0ca7b00 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -23,6 +23,7 @@ an existing framework.
be used to add WSGI support to a web server or framework. It provides utilities
for manipulating WSGI environment variables and response headers, base classes
for implementing WSGI servers, a demo HTTP server that serves WSGI applications,
+types for static type checking,
and a validation tool that checks WSGI servers and applications for conformance
to the WSGI specification (:pep:`3333`).
@@ -43,7 +44,9 @@ This module provides a variety of utility functions for working with WSGI
environments. A WSGI environment is a dictionary containing HTTP request
variables as described in :pep:`3333`. All of the functions taking an *environ*
parameter expect a WSGI-compliant dictionary to be supplied; please see
-:pep:`3333` for a detailed specification.
+:pep:`3333` for a detailed specification and
+:data:`~wsgiref.types.WSGIEnvironment` for a type alias that can be used
+in type annotations.
.. function:: guess_scheme(environ)
@@ -150,7 +153,9 @@ also provides these miscellaneous utilities:
.. class:: FileWrapper(filelike, blksize=8192)
- A wrapper to convert a file-like object to an :term:`iterator`. The resulting objects
+ A concrete implementation of the :class:`wsgiref.types.FileWrapper`
+ protocol used to convert a file-like object to an :term:`iterator`.
+ The resulting objects
are :term:`iterable`\ s. As the object is iterated over, the
optional *blksize* parameter will be repeatedly passed to the *filelike*
object's :meth:`read` method to obtain bytestrings to yield. When :meth:`read`
@@ -349,7 +354,8 @@ request. (E.g., using the :func:`shift_path_info` function from
.. method:: WSGIRequestHandler.get_environ()
- Returns a dictionary containing the WSGI environment for a request. The default
+ Return a :data:`~wsgiref.types.WSGIEnvironment` dictionary for a
+ request. The default
implementation copies the contents of the :class:`WSGIServer` object's
:attr:`base_environ` dictionary attribute and then adds various headers derived
from the HTTP request. Each call to this method should return a new dictionary
@@ -558,13 +564,15 @@ input, output, and error streams.
.. method:: BaseHandler.get_stdin()
- Return an input stream object suitable for use as the ``wsgi.input`` of the
+ Return an object compatible with :class:`~wsgiref.types.InputStream`
+ suitable for use as the ``wsgi.input`` of the
request currently being processed.
.. method:: BaseHandler.get_stderr()
- Return an output stream object suitable for use as the ``wsgi.errors`` of the
+ Return an object compatible with :class:`~wsgiref.types.ErrorStream`
+ suitable for use as the ``wsgi.errors`` of the
request currently being processed.
@@ -703,8 +711,9 @@ input, output, and error streams.
.. attribute:: BaseHandler.wsgi_file_wrapper
- A ``wsgi.file_wrapper`` factory, or ``None``. The default value of this
- attribute is the :class:`wsgiref.util.FileWrapper` class.
+ A ``wsgi.file_wrapper`` factory, compatible with
+ :class:`wsgiref.types.FileWrapper`, or ``None``. The default value
+ of this attribute is the :class:`wsgiref.util.FileWrapper` class.
.. method:: BaseHandler.sendfile()
@@ -754,6 +763,51 @@ input, output, and error streams.
.. versionadded:: 3.2
+:mod:`wsgiref.types` -- WSGI types for static type checking
+-----------------------------------------------------------
+
+.. module:: wsgiref.types
+ :synopsis: WSGI types for static type checking
+
+
+This module provides various types for static type checking as described
+in :pep:`3333`.
+
+.. versionadded:: 3.11
+
+
+.. class:: StartResponse()
+
+ A :class:`typing.Protocol` describing `start_response()
+ <https://peps.python.org/pep-3333/#the-start-response-callable>`_
+ callables (:pep:`3333`).
+
+.. data:: WSGIEnvironment
+
+ A type alias describing a WSGI environment dictionary.
+
+.. data:: WSGIApplication
+
+ A type alias describing a WSGI application callable.
+
+.. class:: InputStream()
+
+ A :class:`typing.Protocol` describing a `WSGI Input Stream
+ <https://peps.python.org/pep-3333/#input-and-error-streams>`_.
+
+.. class:: ErrorStream()
+
+ A :class:`typing.Protocol` describing a `WSGI Error Stream
+ <https://peps.python.org/pep-3333/#input-and-error-streams>`_.
+
+.. class:: FileWrapper()
+
+ A :class:`typing.Protocol` describing a `file wrapper
+ <https://peps.python.org/pep-3333/#optional-platform-specific-file-handling>`_.
+ See :class:`wsgiref.util.FileWrapper` for a concrete implementation of this
+ protocol.
+
+
Examples
--------
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index b5b2a76..19e3d2f 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -233,6 +233,10 @@ New Modules
* A new module, :mod:`tomllib`, was added for parsing TOML.
(Contributed by Taneli Hukkinen in :issue:`40059`.)
+* :mod:`wsgiref.types`, containing WSGI-specific types for static type
+ checking, was added.
+ (Contributed by Sebastian Rittau in :issue:`42012`.)
+
Improved Modules
================
diff --git a/Lib/wsgiref/__init__.py b/Lib/wsgiref/__init__.py
index 1efbba0..59ee48f 100644
--- a/Lib/wsgiref/__init__.py
+++ b/Lib/wsgiref/__init__.py
@@ -13,6 +13,8 @@ Current Contents:
* validate -- validation wrapper that sits between an app and a server
to detect errors in either
+* types -- collection of WSGI-related types for static type checking
+
To-Do:
* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard)
diff --git a/Lib/wsgiref/types.py b/Lib/wsgiref/types.py
new file mode 100644
index 0000000..4a519e5
--- /dev/null
+++ b/Lib/wsgiref/types.py
@@ -0,0 +1,54 @@
+"""WSGI-related types for static type checking"""
+
+from collections.abc import Callable, Iterable
+from types import TracebackType
+from typing import Any, Protocol, TypeAlias
+
+__all__ = [
+ "StartResponse",
+ "WSGIEnvironment",
+ "WSGIApplication",
+ "InputStream",
+ "ErrorStream",
+ "FileWrapper",
+]
+
+_ExcInfo = tuple[type[BaseException], BaseException, TracebackType]
+_OptExcInfo = _ExcInfo | tuple[None, None, None]
+
+class StartResponse(Protocol):
+ """start_response() callable as defined in PEP 3333"""
+ def __call__(
+ self,
+ status: str,
+ headers: list[tuple[str, str]],
+ exc_info: _OptExcInfo | None = ...,
+ /,
+ ) -> Callable[[bytes], object]: ...
+
+WSGIEnvironment: TypeAlias = dict[str, Any]
+WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse],
+ Iterable[bytes]]
+
+class InputStream(Protocol):
+ """WSGI input stream as defined in PEP 3333"""
+ def read(self, size: int = ..., /) -> bytes: ...
+ def readline(self, size: int = ..., /) -> bytes: ...
+ def readlines(self, hint: int = ..., /) -> list[bytes]: ...
+ def __iter__(self) -> Iterable[bytes]: ...
+
+class ErrorStream(Protocol):
+ """WSGI error stream as defined in PEP 3333"""
+ def flush(self) -> object: ...
+ def write(self, s: str, /) -> object: ...
+ def writelines(self, seq: list[str], /) -> object: ...
+
+class _Readable(Protocol):
+ def read(self, size: int = ..., /) -> bytes: ...
+ # Optional: def close(self) -> object: ...
+
+class FileWrapper(Protocol):
+ """WSGI file wrapper as defined in PEP 3333"""
+ def __call__(
+ self, file: _Readable, block_size: int = ..., /,
+ ) -> Iterable[bytes]: ...
diff --git a/Misc/NEWS.d/next/Library/2022-04-05-17-18-13.bpo-42012.zMocQz.rst b/Misc/NEWS.d/next/Library/2022-04-05-17-18-13.bpo-42012.zMocQz.rst
new file mode 100644
index 0000000..ba84041
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-04-05-17-18-13.bpo-42012.zMocQz.rst
@@ -0,0 +1,2 @@
+Add :mod:`wsgiref.types`, containing WSGI-specific types for static type
+checking.