mirror of https://github.com/python/cpython
gh-86178: Add wsgiref.types (GH-32335)
This commit is contained in:
parent
1adc837bf1
commit
0ddc63b240
|
@ -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
|
||||
--------
|
||||
|
||||
|
|
|
@ -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
|
||||
================
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]: ...
|
|
@ -0,0 +1,2 @@
|
|||
Add :mod:`wsgiref.types`, containing WSGI-specific types for static type
|
||||
checking.
|
Loading…
Reference in New Issue