diff --git a/src/klein/_resource.py b/src/klein/_resource.py index e0917788..53c77fc4 100644 --- a/src/klein/_resource.py +++ b/src/klein/_resource.py @@ -23,7 +23,6 @@ from ._app import ( ErrorMethods, Klein, - KleinRenderable, KleinRouteHandler, RouteMetadata, ) @@ -160,8 +159,27 @@ def __ne__(self, other: object) -> bool: return NotImplemented return not result - def render(self, request: IRequest) -> KleinRenderable: - # Stuff we need to know for the mapper. + def render(self, request: IRequest) -> int | bytes: + """ + Render the request based on the underlying L{Klein} application, in a + multi-step process: + + 1. convert twisted input request information into something legible + to werkzeug + + 2. bind that info (URL, method, query args, etc) into a request + mapper, and look up a werkzeug endpoint (i.e.: klein + C{@route}-decorated method) to invoke + + 3. invoke that endpoint, getting something renderable + + 4. render that thing + + 5. handle any errors in lookup or rendering with declared error + handlers + + 6. render the thing that the error handler returned + """ try: ( url_scheme, @@ -232,8 +250,9 @@ def _execute() -> Deferred: def process(r: object) -> Any: """ Recursively go through r and any child Resources until something - returns an IRenderable, then render it and let the result of that - bubble back up. + returns something renderable (L{IResource}, L{IRenderable}, + L{bytes}, L{str}, or L{Iterable} of same), then render it and let + the result of that bubble back up. """ # isinstance() is faster than providedBy(), so this speeds up the # very common case of returning pre-rendered results, at the cost @@ -280,6 +299,7 @@ def processing_failed( he = failure.value assert isinstance(he, HTTPException) request.setResponseCode(he.code) + resp = he.get_response({}) for header, value in resp.headers: @@ -334,4 +354,4 @@ def write_response( d.addCallback(write_response) d.addErrback(log.err, _why="Unhandled Error writing response") - return server.NOT_DONE_YET # type: ignore[return-value] + return server.NOT_DONE_YET diff --git a/src/klein/test/test_resource.py b/src/klein/test/test_resource.py index 1070f545..33f1a622 100644 --- a/src/klein/test/test_resource.py +++ b/src/klein/test/test_resource.py @@ -135,7 +135,7 @@ def getWrittenData(self) -> bytes: def _render( - resource: KleinResource, request: IRequest, notifyFinish: bool = True + resource: KleinResource, request: Request, notifyFinish: bool = True ) -> Deferred: result = resource.render(request) @@ -144,10 +144,10 @@ def _render( request.finish() return succeed(None) - if result is not NOT_DONE_YET: # type: ignore[comparison-overlap] + if result is not NOT_DONE_YET: raise AssertionError("unreachable") # pragma: no cover - if request.finished or not notifyFinish: # type: ignore[unreachable] + if request.finished or not notifyFinish: return succeed(None) return request.notifyFinish()