@@ -193,7 +193,7 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
193
193
optional = [ ( globals, None ) , ( locals, Some ( vm. ctx. dict_type( ) ) ) ]
194
194
) ;
195
195
196
- check_but_allow_none ! ( vm, globals, vm . ctx . dict_type ( ) ) ;
196
+ let scope = make_scope ( vm, globals, locals ) ? ;
197
197
198
198
// Determine code object:
199
199
let code_obj = if objtype:: isinstance ( source, & vm. ctx . code_type ( ) ) {
@@ -213,8 +213,6 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
213
213
return Err ( vm. new_type_error ( "code argument must be str or code object" . to_string ( ) ) ) ;
214
214
} ;
215
215
216
- let scope = make_scope ( vm, globals, locals) ;
217
-
218
216
// Run the source:
219
217
vm. run_code_obj ( code_obj. clone ( ) , scope)
220
218
}
@@ -229,7 +227,7 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
229
227
optional = [ ( globals, None ) , ( locals, Some ( vm. ctx. dict_type( ) ) ) ]
230
228
) ;
231
229
232
- check_but_allow_none ! ( vm, globals, vm . ctx . dict_type ( ) ) ;
230
+ let scope = make_scope ( vm, globals, locals ) ? ;
233
231
234
232
// Determine code object:
235
233
let code_obj = if objtype:: isinstance ( source, & vm. ctx . str_type ( ) ) {
@@ -249,8 +247,6 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
249
247
return Err ( vm. new_type_error ( "source argument must be str or code object" . to_string ( ) ) ) ;
250
248
} ;
251
249
252
- let scope = make_scope ( vm, globals, locals) ;
253
-
254
250
// Run the code:
255
251
vm. run_code_obj ( code_obj, scope)
256
252
}
@@ -259,7 +255,29 @@ fn make_scope(
259
255
vm : & mut VirtualMachine ,
260
256
globals : Option < & PyObjectRef > ,
261
257
locals : Option < & PyObjectRef > ,
262
- ) -> ScopeRef {
258
+ ) -> PyResult < ScopeRef > {
259
+ let dict_type = vm. ctx . dict_type ( ) ;
260
+ let globals = match globals {
261
+ Some ( arg) => {
262
+ if arg. is ( & vm. get_none ( ) ) {
263
+ None
264
+ } else {
265
+ if vm. isinstance ( arg, & dict_type) ? {
266
+ Some ( arg)
267
+ } else {
268
+ let arg_typ = arg. typ ( ) ;
269
+ let actual_type = vm. to_pystr ( & arg_typ) ?;
270
+ let expected_type_name = vm. to_pystr ( & dict_type) ?;
271
+ return Err ( vm. new_type_error ( format ! (
272
+ "globals must be a {}, not {}" ,
273
+ expected_type_name, actual_type
274
+ ) ) ) ;
275
+ }
276
+ }
277
+ }
278
+ None => None ,
279
+ } ;
280
+
263
281
let current_scope = vm. current_scope ( ) ;
264
282
let parent = match globals {
265
283
Some ( dict) => Some ( Scope :: new ( dict. clone ( ) , Some ( vm. get_builtin_scope ( ) ) ) ) ,
@@ -270,7 +288,7 @@ fn make_scope(
270
288
None => current_scope. locals . clone ( ) ,
271
289
} ;
272
290
273
- Scope :: new ( locals, parent)
291
+ Ok ( Scope :: new ( locals, parent) )
274
292
}
275
293
276
294
fn builtin_format ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
0 commit comments