-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
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
Compilation emits multiple warnings in the finally block #131927
Comments
I think the issue is that we compile the source twice, once we compile to an AST and second time from the AST to a code object. The warning comes from the AST optimizer so it is emitted both times: cpython/Lib/_pyrepl/console.py Lines 190 to 209 in 6aa88a2
A very simple fix for this would be to catch this warning on the second compilation, something like this: diff --git a/Lib/_pyrepl/console.py b/Lib/_pyrepl/console.py
index 8956fb1242..9d461980be 100644
--- a/Lib/_pyrepl/console.py
+++ b/Lib/_pyrepl/console.py
@@ -204,8 +204,26 @@ def runsource(self, source, filename="<input>", symbol="single"):
wrapper = ast.Interactive if stmt is last_stmt else ast.Module
the_symbol = symbol if stmt is last_stmt else "exec"
item = wrapper([stmt])
+ import warnings
try:
- code = self.compile.compiler(item, filename, the_symbol)
+ with warnings.catch_warnings(record=True) as caught_warnings:
+ # Enable all warnings
+ warnings.simplefilter("always")
+ code = self.compile.compiler(item, filename, the_symbol)
+ for warning in caught_warnings:
+ if issubclass(warning.category, SyntaxWarning) and "in a 'finally' block" in str(warning.message):
+ # Ignore this warning as it would've alread been raised
+ # when compiling the code above
+ pass
+ else:
+ # Re-emit other warnings
+ warnings.warn_explicit(
+ message=warning.message,
+ category=warning.category,
+ filename=warning.filename,
+ lineno=warning.lineno,
+ source=warning.source
+ )
linecache._register_code(code, source, filename)
except SyntaxError as e:
if e.args[0] == "'await' outside function": I can send a PR for this later today unless you were already working on it @sobolevn ? |
Cc: @iritkatriel |
Why does the repl need the ast? |
No, I don't plan to work on this issue, because I don't know how to solve it :) |
Looks like it's walking the AST and then constructing an AST for each statement on its own and executing that. Not sure why. I don't like the solution proposed above (suppressing the warnings) because I think we will add other syntax warnings to this stage later on (including moving some that are not in the compiler so that they show up in static analysis), and I don't want us to have to special case each one of them. Let's think of something else. |
Indeed, the solution I proposed is pretty brittle, especially if we're planning to add more warnings in the future. I'll see if I can come up with another solution. |
One thing we could do is to define a subclass of SyntaxWarning which is only raised from the (note that ast_opt is in the process of being renamed in #131830 (comment), so maybe wait till that's merged). |
That sounds like a good option! I'll wait for the other PR to land :) |
Actually, adding a new builtin warning type would need a PEP, and this is probably overkill for this problem. Maybe we can just mark the SyntaxWarning as "coming from ast_opt" in some way that the real can query? |
Or a way to turn off warnings coming from ast_opt? Though that also seems like overkill for such a niche use case. |
Possibly, particularly if we can add it as an internal option (i.e., not expose it via the documented API). |
Yet another option is to leave ast_opt alone, and handle this in the repl. So the repl would save the warnings from the ast construction and then filter out duplicated warnings from the compilation call. |
I like the last option the best since I'd also like to avoid touching ast_opt for this. |
We have the same issue in 3.12: >>> try:
... pass
... finally:
... assert(1, 'message')
...
<stdin>:4: SyntaxWarning: assertion is always true, perhaps remove parentheses?
<stdin>:4: SyntaxWarning: assertion is always true, perhaps remove parentheses? |
It has no relation to REPL, it can be reproduced with
|
Just adding a link here to my comment explaining why the warning is emitted more than once: #131993 (comment) The tl;dr is that |
That looks like a different issue related to assert. Try this:
|
There were at least three different bugs:
The PR fixed them all. Maybe backport it, as the first two issues are old? |
…the REPL (pythonGH-131993) (cherry picked from commit 3d08c8a) Co-authored-by: Tomas R. <[email protected]>
…the REPL (pythonGH-131993) (cherry picked from commit 3d08c8a) Co-authored-by: Tomas R. <[email protected]>
…the REPL (pythonGH-131993) (cherry picked from commit 3d08c8a) Co-authored-by: Tomas R. <[email protected]>
Bug report
This code produces two
SyntaxWarning
s in the new REPL:But, in our old REPL it produces just one:
Other
SyntaxWarning
s also do not show the same behavior in the new REPL. Example:So, looks like only PEP-765 is affected, only in the new REPL.
CC @ambv @iritkatriel
Linked PRs
The text was updated successfully, but these errors were encountered: