Uh oh!
There was an error while loading. Please reload this page.
bpo-40334: Support type comments - #19780
Conversation
This does not yet support the "long form" for arguments with type comments. We also totally skip `# type: ignore` comments, and there is no support for func_type_input yet.
This involved a complete refactor of the part of the grammar used to recognise formal parameters in function definitions. I renamed many of the rules involved. The rewrite always includes the comma following a parameter in that argument, so that we can also include the type comment, if any (which follows the comma). The final parameter may not be followed by a comma, so we allow the comma to be omitted, but only if a close parenthesis follows instead (preceded by the type comment, if any). Some additional complications are needed because the code generator doesn't actually support alternatives that may be empty. PS. I didn't refactor the corresponding rules for lambdas, since they don't have type comments.
gvanrossum
commented
Apr 29, 2020
Wait, I forgot to un-skip the test for long-form arguments and it segfaults. On it. |
gvanrossum
commented
Apr 29, 2020
Hm... when parsing something as simple as it seems the end column number for |
gvanrossum
commented
Apr 29, 2020
Dang I already have conflicts. Looking... |
lysnikolaou
left a comment
There was a problem hiding this comment.
Thanks for doing this! Apart from all the TYPE_COMMENTS work, I strongly feel that the arguments improvements made a significant difference in readability.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
lysnikolaou
commented
Apr 29, 2020
It seems there's a failure in |
gvanrossum
commented
Apr 29, 2020
The test_type_comments failure is new, looking now. |
gvanrossum
left a comment
There was a problem hiding this comment.
All your other suggestions will appear in the next commit.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| return a; | ||
| } | ||
| PyObject *tco = _PyPegen_new_type_comment(p, tc); | ||
| PyObject *tco = NEW_TYPE_COMMENT(tc); |
There was a problem hiding this comment.
Doesn't NEW_TYPE_COMMENT expect tc to be a Token *, i.e. that tc->bytes is a bytes object? I feel that NEW_TYPE_COMMENT would better be off as an inline function.
lysnikolaou
commented
Apr 29, 2020
Also, all the calls to |
| /* Constructs a NameDefaultPair */ | ||
| NameDefaultPair * | ||
| _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value) | ||
| _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, char *tc) |
| } | ||
| arg_ty | ||
| _PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, char *tc) |
To recap, because it might not be clear what my latest reviews are suggesting. I think that the following are needed:
I'd also make |
gvanrossum
commented
Apr 30, 2020
Got it. I'm putting the CHECK_CALL_NULL_ALLOWED call inside NEW_TYPE_COMMENT -- does that make sense? I don't see that pattern used elsewhere. |
| if (tc == NULL) { | ||
| return NULL; | ||
| } | ||
| return CHECK_CALL_NULL_ALLOWED(p, _PyPegen_new_type_comment(p, PyBytes_AsString(tc->bytes))); |
There was a problem hiding this comment.
This will segfault if PyBytes_AsString fails. I think the best way to do it is assign it to a variable beforehand and check for NULL, but that means the the CHECK_NULL_ALLOWED call cannot be inside NEW_TYPE_COMMENT or it has to be called multiple times, once for each time a function is called that could potentially return NULL, which isn't much more beautiful than having it in the grammar IMHO. What do you think?
| returnCHECK_CALL_NULL_ALLOWED(p, _PyPegen_new_type_comment(p,PyBytes_AsString(tc->bytes))); | |
| char*bytes=PyBytes_AsString(tc->bytes); | |
| if (!bytes) { | |
| returnNULL; | |
| } | |
| return_PyPegen_new_type_comment(p, bytes); |
There was a problem hiding this comment.
Okay, I will try again. I really don't want to litter the grammar with CHECK_CALL_NULL_ALLOWED(NEW_TYPE_COMMENT(p, tc)) so I am changing NEW_TYPE_COMMENT to set p->error_indicator on every error exit.
lysnikolaou
left a comment
There was a problem hiding this comment.
One last thing and it's good to go.
| # type_expressions allow */** but ignore them | ||
| type_expressions[asdl_seq*]: | ||
| | a=','.expression+ ',' '*' b=expression ',' '**' c=expression { | ||
| _PyPegen_seq_append_to_end(p, _PyPegen_seq_append_to_end(p, a, b), c) } |
There was a problem hiding this comment.
| _PyPegen_seq_append_to_end(p, _PyPegen_seq_append_to_end(p, a, b), c) } | |
| _PyPegen_seq_append_to_end(p, CHECK(_PyPegen_seq_append_to_end(p, a, b)), c) } |
gvanrossum
commented
Apr 30, 2020
@lysnikolaou Thank you so much for all your help on this one! It's been invaluable. |
Currently working on support for |
gvanrossum
commented
May 1, 2020
Oops. Fixing in #19828 |
hauntsaninja
commented
May 4, 2020
This doesn't seem to be able to handle function type comments where there aren't "normal" argument types preceding the *args and **kwargs types. I've opened #19894 with a fix, but it's my first time working with CPython's grammar, so apologies in advance for any crimes against parsers committed. |
This implements full support for
# type: <type>comments,# type: ignore <stuff>comments, and thefunc_typeparsing mode forast.parse()andcompile().Closeswe-like-parsers#95
https://bugs.python.org/issue40334