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
TypeError when using Cython #453
Comments
Bottle passes route wildcards as keyword arguments. Cython seems to be incompatible to Python in this regard as it does not allow to address positional arguments by name. You can work around this by changing the function signature to |
This is actually an incorrect assertion, and there is a quite simply fix. By default, Cython compiles functions with 0 or 1 arguments, as special PyCFunction METH_O or METH_NOARGS. This functions do not accept keyword arguments. You can tell Cython to disable this optimization by changing the always_allow_keywords compiler directive to True (you can do it per function, per file or globally, check cython's documentation on how to do it). This issue happens actually in all web frameworks who use tricks like this. |
It's not a trick, its how Python is supposed to work.
See https://docs.python.org/2/reference/expressions.html#calls (same for 3.x) If Cython optimizes some functions in a way that they no longer accept keyword arguments, then it behaves differently than CPython or the official Python documentation and is in fact incompatible to standard Python. Thats not surprising, tough. Cython does not claim to be a full Python implementation. |
First, let me say that the reason I've commented here, is when I googled this issue (happened to me with another web framework) , this was the first hit. Second, CPython itself does this trick a lot in the name of optimization as well (which is why Cython allows itself to do it as well). Your statement is wrong, your are quoting the Python Language Reference, but CPython has another side to it, the Python C API Reference which allows you to do wonderful and weird things in the name of speed and C interoperability. You can read about METH_O and PyCFunction there: >>> sum([1,2])
3
>>> sum(**{'x': [1, 2]})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() takes no keyword arguments Why is this ? Because lots of builtin functions are defined as METH_O PyCFunction: in 2.7, METH_O functions cannot be passed keyword arguments by the CPython interpreter itself: Cython is all about compiling code to Python C API, and by default gives you the METH_O optimization. As I've written before, it also allows you (by a flag) to easily disable that optimization: You would be hard pressed (asides from compiler bugs) to find python code which does not compile under Cython: |
We are going off-topic now, but the original issue is resolved and closed, so why not. https://docs.python.org/2/reference/expressions.html#calls As you can see, the Some third party CPython modules may also violate this rule, because the C-API does not prevent it. But only because you can do something with an implementation dependent C-API, it is not automatically part of the language specification. The Python language is defined by the language reference, not by the capabilities of the CPython C-API. My statements are: 1) Cython in its default configuration violates this specific part of the Python language specification. 2) Bottle is not relying on undefined behavior or implementation details, and is fully compatible with conforming implementations of the python language. This issue is not a bug in Bottle. I'll say it again: This is totally fine. Cython does not claim to be 100% compatible (yet). It's a behavior-changing optimization that can be disabled. Nothing wrong with that. I just find it inappropriate to blame library authors for using well documented language features, just because Cython stumbles over them. This discussion should happen in a Cython mailing-list or issue thread, not here. |
Hi , i am using Cython to write my bottle based application .
inside my application i serve static files like this :
@controller.route('/Apps/filepath:path')
def server_static(filepath):
return static_file(filepath,root='%s/Apps' %myPath)
When i run this code as Python code , static files being served as intended ,
but when i compile my project to Cython code , and try to access a static file
i get following error :
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 763, in _handle
return route.call(*_args)
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 1572, in wrapper
rv = callback(_a, **ka)
TypeError: server_static() takes no keyword arguments
Note : i am compiling only my modules to Cython , Bottle module is not touched .
Also everything else works as it should .. only accessing static files rises the exception.
Python 2.7 Linux , Bottle 11.4 , Cython 0.16
The text was updated successfully, but these errors were encountered: