@@ -460,11 +460,12 @@ impl Frame {
460460 let code = & * * self . code ;
461461 // SAFETY: Called before generator resume; no concurrent access.
462462 let fastlocals = unsafe { self . fastlocals . borrow_mut ( ) } ;
463+ let locals_map = self . locals . mapping ( vm) ;
463464 for ( i, & varname) in code. varnames . iter ( ) . enumerate ( ) {
464465 if i >= fastlocals. len ( ) {
465466 break ;
466467 }
467- match self . locals . mapping ( vm ) . subscript ( varname, vm) {
468+ match locals_map . subscript ( varname, vm) {
468469 Ok ( value) => fastlocals[ i] = Some ( value) ,
469470 Err ( e) if e. fast_isinstance ( vm. ctx . exceptions . key_error ) => { }
470471 Err ( e) => return Err ( e) ,
@@ -483,12 +484,13 @@ impl Frame {
483484 let code = & * * self . code ;
484485 let map = & code. varnames ;
485486 let j = core:: cmp:: min ( map. len ( ) , code. varnames . len ( ) ) ;
487+ let locals_map = locals. mapping ( vm) ;
486488 if !code. varnames . is_empty ( ) {
487489 // SAFETY: Either _guard holds the state mutex (frame not executing),
488490 // or we're in a trace callback on the same thread that holds it.
489491 let fastlocals = unsafe { self . fastlocals . borrow ( ) } ;
490492 for ( & k, v) in zip ( & map[ ..j] , fastlocals) {
491- match locals . mapping ( vm ) . ass_subscript ( k, v. clone ( ) , vm) {
493+ match locals_map . ass_subscript ( k, v. clone ( ) , vm) {
492494 Ok ( ( ) ) => { }
493495 Err ( e) if e. fast_isinstance ( vm. ctx . exceptions . key_error ) => { }
494496 Err ( e) => return Err ( e) ,
@@ -498,7 +500,7 @@ impl Frame {
498500 if !code. cellvars . is_empty ( ) || !code. freevars . is_empty ( ) {
499501 for ( i, & k) in code. cellvars . iter ( ) . enumerate ( ) {
500502 let cell_value = self . get_cell_contents ( i) ;
501- match locals . mapping ( vm ) . ass_subscript ( k, cell_value, vm) {
503+ match locals_map . ass_subscript ( k, cell_value, vm) {
502504 Ok ( ( ) ) => { }
503505 Err ( e) if e. fast_isinstance ( vm. ctx . exceptions . key_error ) => { }
504506 Err ( e) => return Err ( e) ,
@@ -507,7 +509,7 @@ impl Frame {
507509 if code. flags . contains ( bytecode:: CodeFlags :: OPTIMIZED ) {
508510 for ( i, & k) in code. freevars . iter ( ) . enumerate ( ) {
509511 let cell_value = self . get_cell_contents ( code. cellvars . len ( ) + i) ;
510- match locals . mapping ( vm ) . ass_subscript ( k, cell_value, vm) {
512+ match locals_map . ass_subscript ( k, cell_value, vm) {
511513 Ok ( ( ) ) => { }
512514 Err ( e) if e. fast_isinstance ( vm. ctx . exceptions . key_error ) => { }
513515 Err ( e) => return Err ( e) ,
@@ -4324,18 +4326,16 @@ impl ExecutingFrame<'_> {
43244326 #[ cold]
43254327 fn setup_annotations ( & mut self , vm : & VirtualMachine ) -> FrameResult {
43264328 let __annotations__ = identifier ! ( vm, __annotations__) ;
4329+ let locals_obj = self . locals . as_object ( vm) ;
43274330 // Try using locals as dict first, if not, fallback to generic method.
4328- let has_annotations = match self . locals . into_object ( vm) . downcast_exact :: < PyDict > ( vm) {
4329- Ok ( d) => d. contains_key ( __annotations__, vm) ,
4330- Err ( o) => {
4331- let needle = __annotations__. as_object ( ) ;
4332- self . _in ( vm, needle, & o) ?
4333- }
4334- } ;
4331+ let has_annotations =
4332+ if let Some ( d) = locals_obj. downcast_ref_if_exact :: < PyDict > ( vm) {
4333+ d. contains_key ( __annotations__, vm)
4334+ } else {
4335+ self . _in ( vm, __annotations__. as_object ( ) , locals_obj) ?
4336+ } ;
43354337 if !has_annotations {
4336- self . locals
4337- . as_object ( vm)
4338- . set_item ( __annotations__, vm. ctx . new_dict ( ) . into ( ) , vm) ?;
4338+ locals_obj. set_item ( __annotations__, vm. ctx . new_dict ( ) . into ( ) , vm) ?;
43394339 }
43404340 Ok ( None )
43414341 }
0 commit comments