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
Bad error message 'bool()() takes no keyword arguments' #74777
Comments
Very recent "regression". Issue found because of a pet project trying to parse error messages using regexps : more on SylvainDe/DidYouMean-Python#31 . On recent Cron builds on Jenkins, running the following code bool(this_doesnt_exist=2) fails with the following error message
instead of the expected error message
Having a quick look at the recent commits, I suspect with no guarantee whatsoever the issue got introduced with 5eb788b / http://bugs.python.org/issue30534 . I haven't tried to reproduce the issue locally yet and add the findinds if any later on. |
Reproduced locally using unit tests: + def test_varargs0_kw(self): giving: Traceback (most recent call last):
File "/home/josay/Geekage/PythonRgr/cpython/Lib/test/test_call.py", line 136, in test_varargs0_kw
self.assertRaisesRegex(TypeError, msg, bool, x=2)
AssertionError: "bool\(\) takes no keyword arguments" does not match "bool()() takes no keyword arguments" |
The issue seems to be in: int
_PyArg_NoKeywords(const char *funcname, PyObject *kwargs) I'm happy to submit a PR if needed. |
Thank you for catching this bug SylvainDe. This is a regression caused by bpo-30534. I added "()" after the function name for unifying with other error messages but missed that _PyArg_NoKeywords() often is called with argument containing "()", e.g. _PyArg_NoKeywords("bool()", kwds). There are two ways to solve this issue:
I don't know what the way is better. |
As I was trying to test coverage for a few places where the same error was built, I have discovered another issue where the error message is very misleading: AssertionError: "^index\(\) takes no keyword arguments$" does not match "index() takes at least 1 argument (0 given)" Should I open another ticket to track this ? Anyway, so far, I have reached the following conclusion regarding the test coverage: Objects/call.c:551: "%.200s() takes no keyword arguments" => TESTED Objects/call.c:690: "%.200s() takes no keyword arguments" => Not tested Objects/call.c:737: PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments" => Not tested Python/getargs.c:2508: PyErr_Format(PyExc_TypeError, "%.200s takes no keyword arguments" => TESTED (Now) Python/getargs.c:2525: PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments" => Not tested Any suggestion regarding how to test what is not tested is more than welcome. |
Sorry, SylvainDe, but by the time you expose your desire to work on this issue, I already had written two alternate patches. I needed only a time for deciding what of them is the more appropriate solution. PR 1996 implements the first way. It removes explicit "()" from arguments passed to _PyArg_NoKeywords(). Fixed 23 functions and methods. |
Hi serhiy.storchaka, this is fine by me! I've added a corresponding comment with questions/suggestions on the Github PR. Do you reckon I should open another ticket for the issue mentionned in my previous message ? I'm happy to take care of it :) |
If you know how to write tests for these cases a patch is welcome. But this may be not easy. |
Would it be possible to add an assertion to _PyArg_NoKeywords() to prevent regressions? Fail if funcname contains "(" or ")". For example: /* funcname must not contain ( or ), since "()" suffix is added in the error message */ |
It would be possible to make _PyArg_NoKeywords() adding "()" only if the passed argument don't contain them. But since this is a private API, it was easier to just remove "()" from arguments. In any case most uses of _PyArg_NoKeywords() are generated by Argument Clinic and they don't pass "()" in the argument. |
Oh no, I don't expect anything smart :-) Just an assertion to catch obvious mistakes when the function is called manually (not using Argument Clinic). |
If add an assertion, the user code could provoke a crash by creating an exception type with a name containing "()": type('E()', (BaseException,), {}). Thus this should be a runtime check that raises an exception. What the type of an exception should be raised? |
Right. Do we have such code currently? If not, we can remove the assertion later if we want to use such error message.
Sorry, I don't understand. funcname is not always a constant string like "func"? Well, it was just an idea. Ignore it if you see practical issues. |
We don't have such code currently. The function name containing "()" looks silly. But funcname is not always a constant string, you can set it to arbitrary string when create a BaseException subclass. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: