#938: Replace PageHandler with request.args/kwargs
---------------------------+----------------------------------------------- -
Reporter: fumanchu | Owner: fumanchu
Type: enhancement | Status: new
Priority: normal | Milestone: 3.2
Component: CherryPy code | Keywords:
---------------------------+----------------------------------------------- -
In `_cpdispatch.py`, the `PageHandler` class only really exists as a place
to put values which will be passed to the handler as `(*args, **kwargs)`.
The `LateParamPageHandler` just delays this lookup so that
`request.params` can be mutated before the handler call. That system was
designed to allow various dispatch schemes to vary more widely in their
implementation; for example, some dispatch schemes might choose to pass no
arguments to their controllers, some might choose to obtain those args
from other sources, etc.
Unfortunately, that system is too well-encapsulated, which introduces
several problems:
1. No static analysis of the graph of handler wrappers. If a "bare
handler" is wrapped, that information is hidden within each wrapper.
Multiple wrappers compounds the problem.
2. No exposure of args/kwargs. Logic like the test_callable_spec feature
must be built into each `PageHandler` scheme.
3. Returning handler output which needs to be interpolated into a
template must be implemented with decorators or a similar function-
wrapping technique.
Analysis of execution in server systems is more difficult than others
since servers are designed to not crash in the face of exceptions, and in
general have no command-line interface. In general, we should discourage
the wrapping of handler functions, instead preferring to place such logic
in hooks. I don't have a good solution at the moment for solving the
output problem, but we ''can'' tackle the input problem by dropping the
`PageHandler` system in favor of two new attributes: `request.args` and
`request.kwargs`. These would be passed to `request.handler` when it is
called. Placing them in a well-known location solves problem (2), above,
and helps reduce the number of wrappers in general, thereby mitigating
(1).
If we did that, then `test_callable_spec` could be moved to a Tool which
wraps request.handler, since both the args/kwargs would then be passed to
the wrapper, and the handler would be directly inspectable, not hidden
inside that which it wraps.
The downside: I can't think of a way to do this with a deprecation period.
Anyone's custom `PageHandler` classes would have to be changed to use the
new way. We could change `request.handler` to be a property which detected
when it was set to an instance of `PageHandler` and replace it with the
new way, so that might work for people who have custom Dispatchers but use
the existing `PageHandler` classes.
--
Ticket URL: <http://www.cherrypy.org/ticket/938>
CherryPy <http://www.cherrypy.org>
CherryPy - a pythonic, object-oriented HTTP framework