Skip to content
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

bpo-40334: Produce better error messages on invalid targets #20106

Merged
merged 24 commits into from
Jun 18, 2020

Conversation

lysnikolaou
Copy link
Contributor

@lysnikolaou lysnikolaou commented May 15, 2020

The following error messages get produced:

  • cannot delete ... for invalid del targets
  • cannot assign to ... for invalid targets in for and with
    statements

Additionally a few cuts were added in various places before the
invocation of the invalid_* rule, in order to speed things
up.

https://bugs.python.org/issue40334

The following error messages get produced:
- `cannot delete ...` for invalid `del` targets
- `... is an illegal 'for' target` for invalid targets in for
  statements
- `... is an illegal 'with' target` for invalid targets in
  with statements

Additionally a few `cut`s were added in various places before the
invocation of the `invalid_*` rule, in order to speed things
up.
Lib/test/test_syntax.py Outdated Show resolved Hide resolved
@lysnikolaou
Copy link
Contributor Author

Since the error messages will not change I removed the NEWS blurb and added the skip news label. Also updated the initial PR description.

Grammar/python.gram Outdated Show resolved Hide resolved
Parser/pegen/pegen.c Outdated Show resolved Hide resolved
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there!

Grammar/python.gram Outdated Show resolved Hide resolved
Grammar/python.gram Outdated Show resolved Hide resolved
@@ -2058,7 +2058,7 @@ _PyPegen_make_module(Parser *p, asdl_seq *a) {
// Error reporting helpers

expr_ty
_PyPegen_get_invalid_target(expr_ty e)
_PyPegen_get_invalid_target(expr_ty e, int del_targets)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please adopt a naming convention that makes it clear that this is effectively a bool? I was a bit baffled by this for a while. A venerable convention is to use names like is_foo or has_bar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, if is_del is okay, because the questions "What's del, the target, which target?" comes to mind. What do you think?

lysnikolaou and others added 3 commits May 16, 2020 12:55
Co-authored-by: Pablo Galindo <[email protected]>
Co-authored-by: Pablo Galindo <[email protected]>
Correctly identify invalid targets, when there are multiple context
managers in a with statement, avoid SEGFAULT in invalid for targets
and improve paremeter naming in _PyPegen_get_invalid_target.
Parser/pegen/pegen.h Outdated Show resolved Hide resolved
@pablogsal
Copy link
Member

I have updated the PR with the latest changes from #20003

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... I poked another hole here. :-(

>>> for i, (f, g()) in 10: pass
Assertion failed: (e != NULL && e->kind == Compare_kind), function _PyPegen_get_invalid_for_target, file Parser/pegen/pegen.c, line 2110.
Abort trap: 6

@gvanrossum
Copy link
Member

Simpler example that gets the same error:

>>> for f, g() in 10: pass

And this too:

>>> for f(), g in 10: pass

I recommend extreme caution here. If I can poke holes this quickly, I worry that we may be causing a regression if we rush this in before beta1. We obviously don't have the right testing strategy here.

There's nothing that says we have to get this level of detail right in beta1.

@lysnikolaou
Copy link
Contributor Author

Simpler example that gets the same error:

>>> for f, g() in 10: pass

And this too:

>>> for f(), g in 10: pass

I recommend extreme caution here. If I can poke holes this quickly, I worry that we may be causing a regression if we rush this in before beta1. We obviously don't have the right testing strategy here.

There's nothing that says we have to get this level of detail right in beta1.

I pushed a version that I think is pretty close, but I'm not 100% certain. I agree, that there's no rush to land this and that we should test a bit more.

@lysnikolaou
Copy link
Contributor Author

Could you explain this a bit more? I don't get it.

What I meant is that; since this PR already generates 'can't use starred expression here' error messages for some cases, it isn't fully compatible with the old parser. del *a, b was the example I tested both on the old parser and pegen (with this PR applied), and they give different results.

For starred expressions, the message differs from the old parser;

(new parser)
>>> del *a, b
SyntaxError: cannot delete starred
(old parser)
>>> del *a, b
SyntaxError: can't use starred expression here

I think I understand now.

Indeed the old parser used to produce can't use starred expression here and the error message has changed since then. But this PR does not change it, it actually just adopts the changed error message which was introduced in #19911.

Also, I can remember @pablogsal mentioning somewhere that changing just the message is okay in terms of backwards-compatibility.

@isidentical
Copy link
Sponsor Member

Indeed the old parser used to produce can't use starred expression here and the error message has changed since then. But this PR does not change it, it actually just adopts the changed error message which was introduced in #19911.

I see, didn't notice that. Sorry for distraction.

Also, I can remember @pablogsal mentioning somewhere that changing just the message is okay in terms of backwards-compatibility.

So, is this error will be kept (cannot delete starred) or would it be cool to have a patch that customizes errors for starred context (can't use starred expression here)?

@lysnikolaou
Copy link
Contributor Author

I like the cannot delete starred one better. When I see it, I immediately know without even looking at the line of the error that it's got to do with a del statement. On the contrary, can't use starred expression here does not give enough context, I feel. But really, I don't feel very strongly either way. What do the others think?

@gvanrossum
Copy link
Member

Same here.

Parser/pegen.h Outdated
FOR_TARGETS
} TARGETS_TYPE;
expr_ty _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type);
#define GET_INVALID_TARGET(e) _PyPegen_get_invalid_target(e, STAR_TARGETS)
Copy link
Member

@pablogsal pablogsal Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should surround _PyPegen_get_invalid_target in a CHECK to make sure this does not return NULL (and not crash in that case).

Copy link
Member

@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing it again I have played with it a bit more (before the CHECK commit) and I was not able to break it in any way so I think we can land it now so more people interact with it and it this way we could detect any non-trivial problems if they exist.

@lysnikolaou
Copy link
Contributor Author

FYI there is an unrelated CI failure on macOS in test_asyncio.

@pablogsal pablogsal merged commit 01ece63 into python:master Jun 18, 2020
@miss-islington
Copy link
Contributor

Thanks @lysnikolaou for the PR, and @pablogsal for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @lysnikolaou and @pablogsal, I could not cleanly backport this to 3.9 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 01ece63d42b830df106948db0aefa6c1ba24416a 3.9

@pablogsal
Copy link
Member

@lysnikolaou Could you do the manual backport?

@lysnikolaou
Copy link
Contributor Author

@lysnikolaou Could you do the manual backport?

Of course, on it.

@lysnikolaou lysnikolaou deleted the targets-errors branch June 18, 2020 23:12
lysnikolaou added a commit to lysnikolaou/cpython that referenced this pull request Jun 18, 2020
…-20106)

The following error messages get produced:
- `cannot delete ...` for invalid `del` targets
- `... is an illegal 'for' target` for invalid targets in for
  statements
- `... is an illegal 'with' target` for invalid targets in
  with statements

Additionally, a few `cut`s were added in various places before the
invocation of the `invalid_*` rule, in order to speed things
up.

Co-authored-by: Pablo Galindo <[email protected]>
(cherry picked from commit 01ece63)
@bedevere-bot
Copy link

GH-20973 is a backport of this pull request to the 3.9 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Jun 18, 2020
pablogsal pushed a commit that referenced this pull request Jun 19, 2020
…-20106) (GH-20973)

* bpo-40334: Produce better error messages on invalid targets (GH-20106)

The following error messages get produced:
- `cannot delete ...` for invalid `del` targets
- `... is an illegal 'for' target` for invalid targets in for
  statements
- `... is an illegal 'with' target` for invalid targets in
  with statements

Additionally, a few `cut`s were added in various places before the
invocation of the `invalid_*` rule, in order to speed things
up.

Co-authored-by: Pablo Galindo <[email protected]>
(cherry picked from commit 01ece63)
@stestagg
Copy link

FYI, appears to have caused a regression: https://bugs.python.org/issue41060.
This causes with a as b to crash the interpreter

fasih pushed a commit to fasih/cpython that referenced this pull request Jun 29, 2020
…-20106)

The following error messages get produced:
- `cannot delete ...` for invalid `del` targets
- `... is an illegal 'for' target` for invalid targets in for
  statements
- `... is an illegal 'with' target` for invalid targets in
  with statements

Additionally, a few `cut`s were added in various places before the
invocation of the `invalid_*` rule, in order to speed things
up.

Co-authored-by: Pablo Galindo <[email protected]>
arun-mani-j pushed a commit to arun-mani-j/cpython that referenced this pull request Jul 21, 2020
…-20106)

The following error messages get produced:
- `cannot delete ...` for invalid `del` targets
- `... is an illegal 'for' target` for invalid targets in for
  statements
- `... is an illegal 'with' target` for invalid targets in
  with statements

Additionally, a few `cut`s were added in various places before the
invocation of the `invalid_*` rule, in order to speed things
up.

Co-authored-by: Pablo Galindo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants