diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index d3ba459dd..eefc7b895 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -286,6 +286,7 @@ webbrowser: 2.7- winreg: 3.0- winsound: 2.7- wsgiref: 2.7- +wsgiref.types: 3.11- xdrlib: 2.7- xml: 2.7- xmlrpc: 3.0- diff --git a/stdlib/_typeshed/wsgi.pyi b/stdlib/_typeshed/wsgi.pyi index 9f036d8f2..107bcfb81 100644 --- a/stdlib/_typeshed/wsgi.pyi +++ b/stdlib/_typeshed/wsgi.pyi @@ -1,36 +1,43 @@ # Types to support PEP 3333 (WSGI) # +# Obsolete since Python 3.11: Use wsgiref.types instead. +# # See the README.md file in this directory for more information. +import sys from sys import _OptExcInfo from typing import Any, Callable, Iterable, Protocol from typing_extensions import TypeAlias -# stable -class StartResponse(Protocol): - def __call__( - self, status: str, headers: list[tuple[str, str]], exc_info: _OptExcInfo | None = ... - ) -> Callable[[bytes], Any]: ... - -WSGIEnvironment: TypeAlias = dict[str, Any] # stable -WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] # stable - -# WSGI input streams per PEP 3333, stable -class InputStream(Protocol): - def read(self, size: int = ...) -> bytes: ... - def readline(self, size: int = ...) -> bytes: ... - def readlines(self, hint: int = ...) -> list[bytes]: ... - def __iter__(self) -> Iterable[bytes]: ... - -# WSGI error streams per PEP 3333, stable -class ErrorStream(Protocol): - def flush(self) -> None: ... - def write(self, s: str) -> None: ... - def writelines(self, seq: list[str]) -> None: ... - class _Readable(Protocol): def read(self, size: int = ...) -> bytes: ... + # Optional: def close(self) -> object: ... -# Optional file wrapper in wsgi.file_wrapper -class FileWrapper(Protocol): - def __call__(self, file: _Readable, block_size: int = ...) -> Iterable[bytes]: ... +if sys.version_info >= (3, 11): + from wsgiref.types import * +else: + # stable + class StartResponse(Protocol): + def __call__( + self, __status: str, __headers: list[tuple[str, str]], __exc_info: _OptExcInfo | None = ... + ) -> Callable[[bytes], object]: ... + + WSGIEnvironment: TypeAlias = dict[str, Any] # stable + WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] # stable + + # WSGI input streams per PEP 3333, stable + class InputStream(Protocol): + def read(self, __size: int = ...) -> bytes: ... + def readline(self, __size: int = ...) -> bytes: ... + def readlines(self, __hint: int = ...) -> list[bytes]: ... + def __iter__(self) -> Iterable[bytes]: ... + + # WSGI error streams per PEP 3333, stable + class ErrorStream(Protocol): + def flush(self) -> object: ... + def write(self, __s: str) -> object: ... + def writelines(self, __seq: list[str]) -> object: ... + + # Optional file wrapper in wsgi.file_wrapper + class FileWrapper(Protocol): + def __call__(self, __file: _Readable, __block_size: int = ...) -> Iterable[bytes]: ... diff --git a/stdlib/wsgiref/handlers.pyi b/stdlib/wsgiref/handlers.pyi index 28a759b58..54e0cbc0d 100644 --- a/stdlib/wsgiref/handlers.pyi +++ b/stdlib/wsgiref/handlers.pyi @@ -1,10 +1,10 @@ +from _typeshed.wsgi import ErrorStream, InputStream, StartResponse, WSGIApplication, WSGIEnvironment from abc import abstractmethod from types import TracebackType from typing import IO, Callable, MutableMapping from typing_extensions import TypeAlias from .headers import Headers -from .types import ErrorStream, InputStream, StartResponse, WSGIApplication, WSGIEnvironment from .util import FileWrapper __all__ = ["BaseHandler", "SimpleHandler", "BaseCGIHandler", "CGIHandler", "IISCGIHandler", "read_environ"] diff --git a/stdlib/wsgiref/simple_server.pyi b/stdlib/wsgiref/simple_server.pyi index 389d30c22..1dc84e9fb 100644 --- a/stdlib/wsgiref/simple_server.pyi +++ b/stdlib/wsgiref/simple_server.pyi @@ -1,8 +1,8 @@ +from _typeshed.wsgi import ErrorStream, StartResponse, WSGIApplication, WSGIEnvironment from http.server import BaseHTTPRequestHandler, HTTPServer from typing import TypeVar, overload from .handlers import SimpleHandler -from .types import ErrorStream, StartResponse, WSGIApplication, WSGIEnvironment __all__ = ["WSGIServer", "WSGIRequestHandler", "demo_app", "make_server"] diff --git a/stdlib/wsgiref/types.pyi b/stdlib/wsgiref/types.pyi index c272ae67c..b8ece8d57 100644 --- a/stdlib/wsgiref/types.pyi +++ b/stdlib/wsgiref/types.pyi @@ -1,3 +1,32 @@ -# Obsolete, use _typeshed.wsgi directly. +from collections.abc import Callable, Iterable +from sys import _OptExcInfo +from typing import Any, Protocol +from typing_extensions import TypeAlias -from _typeshed.wsgi import * +__all__ = ["StartResponse", "WSGIEnvironment", "WSGIApplication", "InputStream", "ErrorStream", "FileWrapper"] + +class StartResponse(Protocol): + 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): + 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): + 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): + def __call__(self, __file: _Readable, __block_size: int = ...) -> Iterable[bytes]: ... diff --git a/stdlib/wsgiref/util.pyi b/stdlib/wsgiref/util.pyi index f2c3135df..f764ed5e3 100644 --- a/stdlib/wsgiref/util.pyi +++ b/stdlib/wsgiref/util.pyi @@ -1,8 +1,7 @@ import sys +from _typeshed.wsgi import WSGIEnvironment from typing import IO, Any, Callable -from .types import WSGIEnvironment - __all__ = ["FileWrapper", "guess_scheme", "application_uri", "request_uri", "shift_path_info", "setup_testing_defaults"] class FileWrapper: diff --git a/tests/stubtest_allowlists/py3_common.txt b/tests/stubtest_allowlists/py3_common.txt index bebd306bc..687aa32b5 100644 --- a/tests/stubtest_allowlists/py3_common.txt +++ b/tests/stubtest_allowlists/py3_common.txt @@ -240,7 +240,6 @@ weakref.ref.__call__ webbrowser.UnixBrowser.remote_action # always overridden in inheriting class webbrowser.UnixBrowser.remote_action_newtab # always overridden in inheriting class webbrowser.UnixBrowser.remote_action_newwin # always overridden in inheriting class -wsgiref.types # Doesn't exist, see comments in file xml.parsers.expat.expat_CAPI # ==========