Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typing for async route methods #614

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 56 additions & 1 deletion src/klein/test/typing_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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