File tree Expand file tree Collapse file tree
python/ql/test/query-tests/Statements/general Expand file tree Collapse file tree Original file line number Diff line number Diff line change 33| test.py:101:5:101:14 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
44| test.py:102:9:102:14 | Subscript | Modification of the locals() dictionary will have no effect on the local variables. |
55| test.py:103:5:103:13 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
6+ | test.py:206:5:206:11 | Subscript | Modification of the locals() dictionary will have no effect on the local variables. |
7+ | test.py:207:5:207:23 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
8+ | test.py:208:5:208:15 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
9+ | test.py:209:9:209:15 | Subscript | Modification of the locals() dictionary will have no effect on the local variables. |
10+ | test.py:210:5:210:14 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
11+ | test.py:228:9:228:24 | Subscript | Modification of the locals() dictionary will have no effect on the local variables. |
12+ | test.py:229:9:229:35 | Attribute() | Modification of the locals() dictionary will have no effect on the local variables. |
Original file line number Diff line number Diff line change @@ -196,3 +196,41 @@ class false_positive:
196196class MyClass :
197197 locals ()['x' ] = 43 # OK
198198 y = x
199+
200+
201+ # Once a `locals()` dictionary is passed out of the scope that created it, it is
202+ # just an ordinary mapping. Modifying it in a different scope is meaningful and
203+ # effective, so these modifications must NOT be flagged: the "no effect on local
204+ # variables" gotcha only applies within the scope that called `locals()`.
205+ def modify_passed_dict (ns ):
206+ ns ['k' ] = 1 # OK: `ns` is a parameter here, not this scope's locals()
207+ ns .update ({'j' : 2 }) # OK
208+ ns .pop ('k' ) # OK
209+ del ns ['j' ] # OK
210+ ns .clear () # OK
211+
212+
213+ def pass_locals_to_function ():
214+ y = 1
215+ modify_passed_dict (locals ())
216+ return y
217+
218+
219+ # The same situation, but where the `locals()` dictionary is laundered through an
220+ # instance attribute (as instance-attribute type tracking now models). These must
221+ # also not be flagged.
222+ class NamespaceHolder (object ):
223+
224+ def __init__ (self , ns ):
225+ self .ns = ns
226+
227+ def populate (self ):
228+ self .ns ['extra' ] = 1 # OK: different scope from the `locals()` call
229+ self .ns .update ({'more' : 2 }) # OK
230+
231+
232+ def launder_locals_through_instance ():
233+ x = 1
234+ holder = NamespaceHolder (locals ())
235+ holder .populate ()
236+ return x
You can’t perform that action at this time.
0 commit comments