From 51bf1a7e55a82300b8c6a28b55c431bc9f29795d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilfredo=20Sa=CC=81nchez?= Date: Tue, 23 May 2023 17:24:45 -0700 Subject: [PATCH 1/3] Add async methods --- src/klein/test/typing_app.py | 44 +++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/klein/test/typing_app.py b/src/klein/test/typing_app.py index 63879e9e6..634f7b3bc 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 @@ -16,6 +20,8 @@ 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 +50,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 +80,36 @@ 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) -> KleinRenderable: + return succeed(object()) # type: ignore[arg-type] + + @router.route("/async-str") + async def asyncReturnsStr(self, request: IRequest) -> KleinRenderable: + return succeed("") + + @router.route("/async-bytes") + async def asyncReturnsBytes(self, request: IRequest) -> KleinRenderable: + return succeed(b"") + + @router.route("/async-iresource") + async def asyncReturnsIResource(self, request: IRequest) -> KleinRenderable: + return succeed(Resource()) + + @router.route("/async-irenderable") + async def asyncReturnsIRenderable( + self, request: IRequest + ) -> KleinRenderable: + return succeed(Element()) + + @router.route("/async-tag") + async def asyncReturnsTag(self, request: IRequest) -> KleinRenderable: + return succeed(Tag("")) + + @router.route("/async-none") + async def asyncReturnsNone(self, request: IRequest) -> KleinRenderable: + return succeed(None) From 5e7ec8d8ee02b4cc315f98b719e7698a4b7b32f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilfredo=20Sa=CC=81nchez?= Date: Wed, 24 May 2023 12:49:30 -0700 Subject: [PATCH 2/3] Don't return deferred from async methods, cuz that's weird. --- src/klein/test/typing_app.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/klein/test/typing_app.py b/src/klein/test/typing_app.py index 634f7b3bc..3430ab500 100644 --- a/src/klein/test/typing_app.py +++ b/src/klein/test/typing_app.py @@ -86,30 +86,30 @@ def returnsDeferredNone(self, request: IRequest) -> KleinRenderable: @router.route("/async-object") async def asyncReturnsObject(self, request: IRequest) -> KleinRenderable: - return succeed(object()) # type: ignore[arg-type] + return object() # type: ignore[arg-type] @router.route("/async-str") async def asyncReturnsStr(self, request: IRequest) -> KleinRenderable: - return succeed("") + return "" @router.route("/async-bytes") async def asyncReturnsBytes(self, request: IRequest) -> KleinRenderable: - return succeed(b"") + return b"" @router.route("/async-iresource") async def asyncReturnsIResource(self, request: IRequest) -> KleinRenderable: - return succeed(Resource()) + return Resource() @router.route("/async-irenderable") async def asyncReturnsIRenderable( self, request: IRequest ) -> KleinRenderable: - return succeed(Element()) + return Element() @router.route("/async-tag") async def asyncReturnsTag(self, request: IRequest) -> KleinRenderable: - return succeed(Tag("")) + return Tag("") @router.route("/async-none") async def asyncReturnsNone(self, request: IRequest) -> KleinRenderable: - return succeed(None) + return None From 267bdd471df97dcc4f30cd38087cd0f2f128c673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilfredo=20Sa=CC=81nchez?= Date: Wed, 24 May 2023 13:01:01 -0700 Subject: [PATCH 3/3] Try using KleinSynchronousRenderable --- src/klein/test/typing_app.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/klein/test/typing_app.py b/src/klein/test/typing_app.py index 3430ab500..5ba0ada8a 100644 --- a/src/klein/test/typing_app.py +++ b/src/klein/test/typing_app.py @@ -15,6 +15,7 @@ from twisted.web.template import Element, Tag from klein import Klein, KleinRenderable +from klein._app import KleinSynchronousRenderable class Application: @@ -84,32 +85,44 @@ def returnsDeferredNone(self, request: IRequest) -> KleinRenderable: # Ensure that same return object types for a route are valid in async # methods. - @router.route("/async-object") - async def asyncReturnsObject(self, request: IRequest) -> KleinRenderable: - return object() # type: ignore[arg-type] + # @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) -> KleinRenderable: + async def asyncReturnsStr( + self, request: IRequest + ) -> KleinSynchronousRenderable: return "" @router.route("/async-bytes") - async def asyncReturnsBytes(self, request: IRequest) -> KleinRenderable: + async def asyncReturnsBytes( + self, request: IRequest + ) -> KleinSynchronousRenderable: return b"" @router.route("/async-iresource") - async def asyncReturnsIResource(self, request: IRequest) -> KleinRenderable: + async def asyncReturnsIResource( + self, request: IRequest + ) -> KleinSynchronousRenderable: return Resource() @router.route("/async-irenderable") async def asyncReturnsIRenderable( self, request: IRequest - ) -> KleinRenderable: + ) -> KleinSynchronousRenderable: return Element() @router.route("/async-tag") - async def asyncReturnsTag(self, request: IRequest) -> KleinRenderable: + async def asyncReturnsTag( + self, request: IRequest + ) -> KleinSynchronousRenderable: return Tag("") @router.route("/async-none") - async def asyncReturnsNone(self, request: IRequest) -> KleinRenderable: + async def asyncReturnsNone( + self, request: IRequest + ) -> KleinSynchronousRenderable: return None