#1077: Keyword-only arguments (in python3) aren't fully supported by dispatching.
---------------------------+------------------------------------------------
Reporter: guest | Owner: fumanchu
Type: enhancement | Status: new
Priority: normal | Milestone:
Component: CherryPy code | Keywords:
---------------------------+------------------------------------------------
If keyword-only arguments are used in handlers:
{{{
class Root:
@cherrypy.expose
def resource(self, *, q=None):
return str(q)
}}}
then 404 dispatch errors result in another 500 error:
{{{
500 Internal Server Error
The server encountered an unexpected condition which prevented it from
fulfilling the request.
Traceback (most recent call last):
File "cherrypy/trunk/cherrypy/_cpdispatch.py", line 38, in __call__
test_callable_spec(self.callable, self.args, self.kwargs)
File "cherrypy/trunk/cherrypy/_cpdispatch.py", line 68, in
test_callable_spec
(args, varargs, varkw, defaults) = inspect.getargspec(callable)
File
"/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/inspect.py",
line 793, in getargspec
raise ValueError("Function has keyword-only arguments or annotations"
ValueError: Function has keyword-only arguments or annotations, use
getfullargspec() API which can support them
}}}
Here's a patch compatible with python2 and python3:
{{{
Index: cherrypy/_cpcompat.py
===================================================================
--- cherrypy/_cpcompat.py (revision 2829)
+++ cherrypy/_cpcompat.py (working copy)
@@ -304,3 +304,11 @@
# Python 2
def next(i):
return i.next()
+
+try:
+ from inspect import getfullargspec
+except ImportError:
+ from inspect import getargspec
+else:
+ def getargspec(callable):
+ return getfullargspec(callable)[:4]
Index: cherrypy/_cpdispatch.py
===================================================================
--- cherrypy/_cpdispatch.py (revision 2829)
+++ cherrypy/_cpdispatch.py (working copy)
@@ -18,7 +18,7 @@
classtype = type
import cherrypy
-from cherrypy._cpcompat import set
+from cherrypy._cpcompat import set, getargspec
class PageHandler(object):
@@ -65,10 +65,10 @@
show_mismatched_params = getattr(
cherrypy.serving.request, 'show_mismatched_params', False)
try:
- (args, varargs, varkw, defaults) = inspect.getargspec(callable)
+ (args, varargs, varkw, defaults) = getargspec(callable)
except TypeError:
if isinstance(callable, object) and hasattr(callable,
'__call__'):
- (args, varargs, varkw, defaults) =
inspect.getargspec(callable.__call__)
+ (args, varargs, varkw, defaults) =
getargspec(callable.__call__)
else:
# If it wasn't one of our own types, re-raise
# the original error
}}}
In addition to supporting the syntax, it's actually a nice feature to
require query args if desired. The way cherrypy dispatches right now,
users can incorrectly pass intended query args as path components.
--
Ticket URL: <
http://www.cherrypy.org/ticket/1077>
CherryPy <
http://www.cherrypy.org>
CherryPy - a pythonic, object-oriented HTTP framework