You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
exec behaves differently in Python 2 and Python 3 inside function scope. In Python 2, a plain exec statement can write back into the enclosing function's local variables. In Python 3, exec() does not reliably write back to function locals unless an explicit locals mapping is provided.
Example:
In Python 2 def f(): b = 42 exec "b = 99" return b
return 99
In Python 3 def f(): b = 42 exec("b = 99") return b
return 42 as exec didn't update local b.
In order to allow exec to modify local b. A safer version will be def g(): b = 42 ns = {"b": b} exec("b = 99", globals(), ns) return ns["b"]
Thus, in order to warn about such scope issue. I mainly modified cevel.c that
Before exec runs, snapshot the current fast locals.
After exec, compare fast locals and record which local slots changed.
If one of those locals is later read (LOAD_FAST), emit the warning.
If it is overwritten or deleted before being read, clear the pending state and do not warn.
This mostly looks OK at a high-level (except the code around track_locals which needs explaining, because it's not obvious) and I have some low-level comments. I also don't know if CPython prefers explicitly saying if (x == NULL) or the terser (and valid, exactly equivalent) if (x). If the latter, the PR can be simplified further.
@ltratt Thank you for your comments, I have fixed the low levels issues. For the track_loclas, I renamed it track_exec_writeback as it is a variable to controls whether we snapshot and later compare fast locals around a plain exec, so we only record bindings that exec actually wrote back. I also added a short comment explaining that path.
For the case of if(x = null) vs if (x), for what I observed in cevel.c, it tend to use the if(x=null).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
exec behaves differently in Python 2 and Python 3 inside function scope. In Python 2, a plain exec statement can write back into the enclosing function's local variables. In Python 3, exec() does not reliably write back to function locals unless an explicit locals mapping is provided.
Example:
In Python 2
def f(): b = 42 exec "b = 99" return breturn 99
In Python 3
def f(): b = 42 exec("b = 99") return breturn 42 as exec didn't update local b.
In order to allow exec to modify local b. A safer version will be
def g(): b = 42 ns = {"b": b} exec("b = 99", globals(), ns) return ns["b"]Thus, in order to warn about such scope issue. I mainly modified cevel.c that