-
-
Notifications
You must be signed in to change notification settings - Fork 32k
bpo-35766: Merge typed_ast back into CPython #11645
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
Conversation
Demo: `compile(sample, "<sample>", "exec", PyCF_ONLY_AST|0x1000)` This will crash if type comments are present. It doesn't *work* yet -- type comments cause crashes in ast.c and type ignore comments aren't passed on to Module yet.
This works, it just needs tests
e1bf919
to
d273d67
Compare
I'll try to fix all failing tests before trying again. In my local branch I have test_ast and test_asdl_parser working; the rest is more mysterious (it seems bad indents are parsed differently somehow).
|
a40849b
to
36c212b
Compare
I may have to put this off for a while (certainly I won't get it into 3.8a1). The main problem at this point is the two failing tests,
reports SyntaxError instead of IndentationError at the start of line 2. The reason for that is this definition in Grammar:
Previously this was
and there is code in Python/pythonrun.c::err_input that depends on I haven't figured out how to fix this yet. |
This fixes if 1: foo() but does nothing about def f(): foo() The latter still reports 'SyntaxError: invalid syntax'. So this is not a real solution, just a stop-gap measure until I find a better solution.
Also: - remove redundant 'c' argument from new_type_comment() - double-check that TYPE_COMMENT in a suite is followed by NL
Sorry for the flood of comments. I believe I've done or responded to every code review comment. Hopefully tests will pass now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updates! This looks ready, I left a bunch of really minor comments.
while (*prefix && p < tok->cur) { | ||
if (*prefix == ' ') { | ||
while (*p == ' ' || *p == '\t') | ||
p++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what are the rules of single line bodies. I would prefer to have them always enclosed in curly braces {...}
. It looks like you mix both styles. I will label them so that you can deiced what to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a few more braces. I don't know what PEP 7 says, but the code here seems to mostly use the convention that a single break
or goto
or return
doesn't need to be surrounded by braces (except when part of an if-else if-etc. sequence where most other bodies braced). So I added braces to this specific case, but not around several of the others you flagged.
arr->size *= 2; | ||
arr->items = realloc(arr->items, arr->size * sizeof(*arr->items)); | ||
if (!arr->items) | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single line body.
Parser/tokenizer.c
Outdated
p += 6; | ||
while (is_type_ignore && p < tok->cur) { | ||
if (*p == '#') | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single line body.
num = NCH(ch); | ||
type_ignores = _Py_asdl_seq_new(num, arena); | ||
if (!type_ignores) | ||
goto out; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single line body.
for (i = 0; i < num; i++) { | ||
type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), arena); | ||
if (!ti) | ||
goto out; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single line body.
num = 0; | ||
for (i = 0; i < NCH(ch); i++) { | ||
if (TYPE(CHILD(ch, i)) == test) | ||
num++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more single line body. OK, there are probably too many of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one I fixed.
Python/ast.c
Outdated
|
||
if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) { | ||
ast_error(c, CHILD(n, i), | ||
"bare * has associated type comment"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like an inconsistent indent, should be two more spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, and fixed indents for all other ast_error calls. (I wonder if it used to have a shorter name?)
Python/ast.c
Outdated
@@ -3045,15 +3182,16 @@ ast_for_expr_stmt(struct compiling *c, const node *n) | |||
{ | |||
REQ(n, expr_stmt); | |||
/* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | | |||
('=' (yield_expr|testlist_star_expr))*) | |||
('=' (yield_expr|testlist_star_expr))* [TYPE_COMMENT]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment needs to be updated to match the grammar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Python/ast.c
Outdated
|
||
if (NCH(n) == 1) { | ||
if (num == 1 || (num == 2 && TYPE(CHILD(n, 1)) == TYPE_COMMENT)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me the (num == 2 && TYPE(CHILD(n, 1)) == TYPE_COMMENT)
condition can never be true now (with the updated grammar).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@ambv Should I just merge this, or do you want to review it? |
Unless you're in a hurry now, I'll review and stamp it tomorrow morning my time. Mostly to familiarize myself with the changes. |
That's fine! |
Unsure why the Appveyor build isn't running? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's merge this. It's a bit of a bigger change than promised but such is life 😉
I left one comment, @gvanrossum, that you might want to respond to.
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) | ||
{ | ||
mod_ty res; | ||
PyObject *req_type[3]; | ||
char *req_name[] = {"Module", "Expression", "Interactive"}; | ||
char *req_name[] = {"Module", "Expression", "Interactive", "FunctionType"}; | ||
int isinstance; | ||
|
||
req_type[0] = (PyObject*)Module_type; | ||
req_type[1] = (PyObject*)Expression_type; | ||
req_type[2] = (PyObject*)Interactive_type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we be also populating req_type[3]
here to FunctionType_type
? The assymetry looks brittle to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm... I misunderstood what this is for. Fortunately the code in builtin_compile_impl() prevents this to be reached with mode==3. I propose to just drop support for FunctionType here.
@ambv @gvanrossum I have detected some refleaks in the buildbots after this PR and I started https://bugs.python.org/issue35881 to track this problem. I already started debugging, but I would like so input in case you can see something obvious right away. |
pythonGH-11645 added the fourth option for `mode` argument; updating the comment accordingly.
This PR added a fourth option for |
This is mostly cribbed from python/cpython#11645, though it also adds a new error check to new_type_comment itself.
This is mostly cribbed from python/cpython#11645, though it also adds a new error check to new_type_comment itself.
[UPDATE: I've rewritten this comment to match the latest state of the PR.]
See the bpo issue for motivation. This is the minimal code I hope to merge into CPython. The PR here is complete except for docs. To test this, use
ast.parse(source, type_comments=True)
.(Speaking of backwards compatibility, my bpo issue suggests that I'd also like some features supporting older grammar versions. The only thing that I would really appreciate is being able to parse code that uses
async
orawait
as a non-keyword. But I could structure this as a follow-up PR, much smaller in size.)https://bugs.python.org/issue35766