-
Notifications
You must be signed in to change notification settings - Fork 1
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
capture more errors in fstring replacement field #67
capture more errors in fstring replacement field #67
Conversation
this reopens #66. It has 3 main features: Correct Placeit outputs the exact place of the first error thanks to the newly introduced File "<stdin>", line 1
f"{123:{234 +}}"
^
old: SyntaxError: f-string: expecting '}'
File "<stdin>", line 1
f"{123:{234 +}}"
^
new: SyntaxError: f-string: expecting '=', or '!', or ':', or '}' This is because the parser needs to look ahead, so Capture All Kinds of ErrorsActually we can prove this rule will capture nearly all possible kinds of failure in Friendlier MessageSometimes you are expecting more than File "<string>", line 1
f'{"s"!r{":10"}}'
^
old: SyntaxError: f-string: expecting '}'
File "<string>", line 1
f'{"s"!r{":10"}}'
^
new: SyntaxError: f-string: expecting ':' or '}' |
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.
Generally looks great! Only on comment we could discuss.
I will add a commit to fix the test case once the grammar in this pr is formalized and approved, |
The grammar changes make sense to me, but for this PR to get landed we need to fix the new failing tests for sure |
During the testing with flag
I think these updates of tokens should cause at least a modification of I am wondering if we can utilize what we have in the c module. Since now the f-string supports recursion, making MWE import tokenize
from io import BytesIO
f1 = BytesIO(b"f'{0}'")
f2 = BytesIO(b"f'{0\n}'")
print(*tokenize.tokenize(f1.readline), sep="\n")
print("-" * 80)
print(*tokenize.tokenize(f2.readline), sep="\n")
Also, a case f1 = BytesIO(b"f'{f\"{0}\"}'")
f2 = BytesIO(b"f'{f'{0}'}'")
print(*tokenize.tokenize(f1.readline), sep="\n")
print("-" * 80)
print(*tokenize.tokenize(f2.readline), sep="\n")
|
We might need to reach to the maintainer of |
One possible solution is to use the c_tokenizer with python#27924 With c_tokenizer,
|
@sunmy2019 Thanks for raising this! @mgmacias95 is already workin on rewriting the |
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 typo nit (probably my fault, sorry).
Grammar/python.gram
Outdated
| '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '!'") } | ||
| '{' a=':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before ':'") } | ||
| '{' a='}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '}'") } | ||
| '{' a='lambda' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: lambda expression are not allowed without parentheses") } |
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.
| '{' a='lambda' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: lambda expression are not allowed without parentheses") } | |
| '{' a='lambda' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: lambda expressions are not allowed without parentheses") } |
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.
Yeah, but one thing to notice, this won't capture all forbidden usage of lambda, such as f"{1, lambda x:x}"
I got a new idea to capture all possible errors, maybe you can check the following commit?
@lysnikolaou Hi, check my latest commit 91faa31 that handles File "<stdin>", line 1
f"{lambda x:x}"
^^^^^^^^^
SyntaxError: f-string: lambda expressions are not allowed without parentheses |
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.
Looks great!
Oh I am gonna revert that, since I found some corner cases. |
Oh, no need to revert. I discovered that, this case f"{1,lambda x:{123}}" it compiles. It matches the rule of It is not relavent to my change, so I don't need to revert. And with my change, we can inform user when to add parens. To correct this behavior, we can insert an empty |
Mergin this for the time being as this is a great improvement and is getting quite large already. Thanks a lot for the fantastic work @sunmy2019 🚀 |
Does this mean what I think it means? 🎉 |
We should have a passing test suite now! |
Almost! We have still a failure in the buildbots: https://buildbot.python.org/all/#/builders/802/builds/760 I also pushed a fix for python#102856 (comment) But we are super super super close!!! |
This PR aims to capture all possible partial failures in
fstring_replacement_field
.It breaks some tests, mostly due to change of the error message.
RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN
was introduced to help user to locate the exact failure location.