diff --git a/src/klein/test/typing_app.py b/src/klein/test/typing_app.py index 63879e9e6..5ba0ada8a 100644 --- a/src/klein/test/typing_app.py +++ b/src/klein/test/typing_app.py @@ -2,7 +2,11 @@ This file contains code that should validate with type checking if type hints are correct. -The code is not executed, it is here just to be checked by mypy. +The code is not executed. Instead, the code should simply validate when checked +with mypy, or fail and require a `type: ignore` comment. + +Because those comments produce an error if mypy thinks they are unnecessary, +they service to confirm that code that should fail to verify does so. """ from twisted.internet.defer import succeed @@ -11,11 +15,14 @@ from twisted.web.template import Element, Tag from klein import Klein, KleinRenderable +from klein._app import KleinSynchronousRenderable class Application: router = Klein() + # Ensure that various return object types for a route are valid. + @router.route("/object") def returnsObject(self, request: IRequest) -> KleinRenderable: return object() # type: ignore[return-value] @@ -44,6 +51,9 @@ def returnsTag(self, request: IRequest) -> KleinRenderable: def returnsNone(self, request: IRequest) -> KleinRenderable: return None + # Ensure that same return object types for a route are valid when wrapped + # in a Deferred object. + @router.route("/deferred-object") def returnsDeferredObject(self, request: IRequest) -> KleinRenderable: return succeed(object()) # type: ignore[arg-type] @@ -71,3 +81,48 @@ def returnsDeferredTag(self, request: IRequest) -> KleinRenderable: @router.route("/deferred-none") def returnsDeferredNone(self, request: IRequest) -> KleinRenderable: return succeed(None) + + # Ensure that same return object types for a route are valid in async + # methods. + + # @router.route("/async-object") + # async def asyncReturnsObject( + # self, request: IRequest + # ) -> KleinSynchronousRenderable: + # return object() # type: ignore[arg-type] + + @router.route("/async-str") + async def asyncReturnsStr( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return "" + + @router.route("/async-bytes") + async def asyncReturnsBytes( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return b"" + + @router.route("/async-iresource") + async def asyncReturnsIResource( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return Resource() + + @router.route("/async-irenderable") + async def asyncReturnsIRenderable( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return Element() + + @router.route("/async-tag") + async def asyncReturnsTag( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return Tag("") + + @router.route("/async-none") + async def asyncReturnsNone( + self, request: IRequest + ) -> KleinSynchronousRenderable: + return None