From 6fbf085b9955b071cdbb4cee8ac1f8ae2aa87bd5 Mon Sep 17 00:00:00 2001 From: Vytautas Liuolia Date: Sat, 2 Nov 2024 16:14:12 +0100 Subject: [PATCH] docs(typing): restructure typing docs into a separate chapter --- docs/api/index.rst | 1 + docs/api/typing.rst | 75 +++++++++++++++++++++++++++++++++++++++++++++ docs/api/util.rst | 6 ---- 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 docs/api/typing.rst diff --git a/docs/api/index.rst b/docs/api/index.rst index fdeaadfe3..80ca97517 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -20,3 +20,4 @@ Framework Reference inspect util testing + typing diff --git a/docs/api/typing.rst b/docs/api/typing.rst new file mode 100644 index 000000000..5d2e5e872 --- /dev/null +++ b/docs/api/typing.rst @@ -0,0 +1,75 @@ +Typing Support +============== + +Type checking support was introduced in version 4.0. While most of the library is +now typed, further type annotations may be added throughout the 4.x release cycle. +To improve them, we may introduce changes to the typing that do not affect +runtime behavior, but may surface new or different errors with type checkers. + +.. role:: python(code) + :language: python + +.. note:: + All undocumented type aliases coming from ``falcon._typing`` are considered + private to the framework itself, and not meant for annotating applications + using Falcon. To that end, it is advisable to only use classes from the + public interface, and public aliases from :mod:`falcon.typing`, e.g.: + + .. code-block:: python + + class MyResource: + def on_get(self, req: falcon.Request, resp: falcon.Response) -> None: + resp.media = {'message': 'Hello, World!'} + + If you still decide to reuse the private aliases anyway, they should + preferably be imported inside :python:`if TYPE_CHECKING:` blocks in order + to avoid possible runtime errors after an update. + Also, make sure to :ref:`let us know ` which essential aliases are + missing from the public interface! + + +Known limitations +----------------- + +Falcon's emphasis on flexibility and performance presents certain +challenges when it comes to adding type annotations to the existing code base. +One notable limitation involves using custom :class:`~falcon.Request` and/or +:class:`~falcon.Response` types in callbacks that are passed back +to the framework, such as when adding an +:meth:`error handler `. + +For instance, the following application might unexpectedly not pass type +checking: + +.. code-block:: python + + from typing import Any + + from falcon import App, HTTPInternalServerError, Request, Response + + + class MyRequest(Request): + ... + + + def handle_os_error(req: MyRequest, resp: Response, ex: Exception, + params: dict[str, Any]) -> None: + raise HTTPInternalServerError(title='OS error!') from ex + + + app = App(request_type=MyRequest) + app.add_error_handler(OSError, handle_os_error) + +(Please also see the following GitHub issue: +`#2372 `__.) + +.. important:: + This is only a typing limitation that has no effect outside of type + checking -- the above ``app`` will run just fine! + + +Public type aliases +------------------- + +.. automodule:: falcon.typing + :members: diff --git a/docs/api/util.rst b/docs/api/util.rst index 254b4cb60..93fa163a4 100644 --- a/docs/api/util.rst +++ b/docs/api/util.rst @@ -89,9 +89,3 @@ Other .. autoclass:: falcon.ETag :members: - -Type Aliases ------------- - -.. automodule:: falcon.typing - :members: