Skip to content

Commit 720ea70

Browse files
authored
Merge pull request #21602 from github/tausbn/python-port-modification-of-locals
Python: Port ModificationOfLocals.ql
2 parents 36bbc8c + e368844 commit 720ea70

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

python/ql/src/Statements/ModificationOfLocals.ql

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
*/
1313

1414
import python
15-
private import LegacyPointsTo
15+
private import semmle.python.ApiGraphs
1616

17-
predicate originIsLocals(ControlFlowNodeWithPointsTo n) {
18-
n.pointsTo(_, _, Value::named("locals").getACall())
17+
predicate originIsLocals(ControlFlowNode n) {
18+
API::builtin("locals").getReturn().getAValueReachableFromSource().asCfgNode() = n
1919
}
2020

2121
predicate modification_of_locals(ControlFlowNode f) {
@@ -37,5 +37,8 @@ where
3737
// in module level scope `locals() == globals()`
3838
// see https://docs.python.org/3/library/functions.html#locals
3939
// FP report in https://github.com/github/codeql/issues/6674
40-
not a.getScope() instanceof ModuleScope
40+
not a.getScope() instanceof Module and
41+
// in class level scope `locals()` reflects the class namespace,
42+
// so modifications do take effect.
43+
not a.getScope() instanceof Class
4144
select a, "Modification of the locals() dictionary will have no effect on the local variables."

python/ql/test/query-tests/Statements/general/test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,9 @@ def assert_ok(seq):
174174
# False positive. ODASA-8042. Fixed in PR #2401.
175175
class false_positive:
176176
e = (x for x in [])
177+
178+
# In class-level scope `locals()` reflects the class namespace,
179+
# so modifications do take effect.
180+
class MyClass:
181+
locals()['x'] = 43 # OK
182+
y = x

0 commit comments

Comments
 (0)