@@ -117,15 +117,15 @@ def get_output(moddict, name):
117
117
newcode = code
118
118
def get_output (moddict , name ):
119
119
return moddict [name ]
120
- ns = ns or {}
120
+ newns = ns . copy () if ns else {}
121
121
try :
122
- exec (newcode , ns )
122
+ exec (newcode , newns )
123
123
except raises as e :
124
124
# We care about e.g. NameError vs UnboundLocalError
125
125
self .assertIs (type (e ), raises )
126
126
else :
127
127
for k , v in (outputs or {}).items ():
128
- self .assertEqual (get_output (ns , k ), v )
128
+ self .assertEqual (get_output (newns , k ), v )
129
129
130
130
def test_lambdas_with_iteration_var_as_default (self ):
131
131
code = """
@@ -180,6 +180,26 @@ def test_closure_can_jump_over_comp_scope(self):
180
180
z = [x() for x in items]
181
181
"""
182
182
outputs = {"z" : [2 , 2 , 2 , 2 , 2 ]}
183
+ self ._check_in_scopes (code , outputs , scopes = ["module" , "function" ])
184
+
185
+ def test_cell_inner_free_outer (self ):
186
+ code = """
187
+ def f():
188
+ return [lambda: x for x in (x, [1])[1]]
189
+ x = ...
190
+ y = [fn() for fn in f()]
191
+ """
192
+ outputs = {"y" : [1 ]}
193
+ self ._check_in_scopes (code , outputs , scopes = ["module" , "function" ])
194
+
195
+ def test_free_inner_cell_outer (self ):
196
+ code = """
197
+ g = 2
198
+ def f():
199
+ return g
200
+ y = [g for x in [1]]
201
+ """
202
+ outputs = {"y" : [2 ]}
183
203
self ._check_in_scopes (code , outputs )
184
204
185
205
def test_inner_cell_shadows_outer_redefined (self ):
@@ -203,6 +223,37 @@ def inner():
203
223
outputs = {"x" : - 1 }
204
224
self ._check_in_scopes (code , outputs , ns = {"g" : - 1 })
205
225
226
+ def test_explicit_global (self ):
227
+ code = """
228
+ global g
229
+ x = g
230
+ g = 2
231
+ items = [g for g in [1]]
232
+ y = g
233
+ """
234
+ outputs = {"x" : 1 , "y" : 2 , "items" : [1 ]}
235
+ self ._check_in_scopes (code , outputs , ns = {"g" : 1 })
236
+
237
+ def test_explicit_global_2 (self ):
238
+ code = """
239
+ global g
240
+ x = g
241
+ g = 2
242
+ items = [g for x in [1]]
243
+ y = g
244
+ """
245
+ outputs = {"x" : 1 , "y" : 2 , "items" : [2 ]}
246
+ self ._check_in_scopes (code , outputs , ns = {"g" : 1 })
247
+
248
+ def test_explicit_global_3 (self ):
249
+ code = """
250
+ global g
251
+ fns = [lambda: g for g in [2]]
252
+ items = [fn() for fn in fns]
253
+ """
254
+ outputs = {"items" : [2 ]}
255
+ self ._check_in_scopes (code , outputs , ns = {"g" : 1 })
256
+
206
257
def test_assignment_expression (self ):
207
258
code = """
208
259
x = -1
@@ -250,7 +301,7 @@ def g():
250
301
g()
251
302
"""
252
303
outputs = {"x" : 1 }
253
- self ._check_in_scopes (code , outputs )
304
+ self ._check_in_scopes (code , outputs , scopes = [ "module" , "function" ] )
254
305
255
306
def test_introspecting_frame_locals (self ):
256
307
code = """
0 commit comments