@@ -438,6 +438,8 @@ enum DictIterImpl {
438438
439439impl DictIterImpl {
440440 #[ inline]
441+ /// Safety: the dict should be locked with a critical section on the free-threaded build
442+ /// and otherwise not shared between threads in code that releases the GIL.
441443 unsafe fn next_unchecked < ' py > (
442444 & mut self ,
443445 dict : & Bound < ' py , PyDict > ,
@@ -448,7 +450,7 @@ impl DictIterImpl {
448450 remaining,
449451 ppos,
450452 ..
451- } => crate :: sync :: with_critical_section ( dict , || {
453+ } => {
452454 let ma_used = dict_len ( dict) ;
453455
454456 // These checks are similar to what CPython does.
@@ -478,20 +480,20 @@ impl DictIterImpl {
478480 let mut key: * mut ffi:: PyObject = std:: ptr:: null_mut ( ) ;
479481 let mut value: * mut ffi:: PyObject = std:: ptr:: null_mut ( ) ;
480482
481- if ffi:: PyDict_Next ( dict. as_ptr ( ) , ppos, & mut key, & mut value) != 0 {
483+ if unsafe { ffi:: PyDict_Next ( dict. as_ptr ( ) , ppos, & mut key, & mut value) != 0 } {
482484 * remaining -= 1 ;
483485 let py = dict. py ( ) ;
484486 // Safety:
485487 // - PyDict_Next returns borrowed values
486488 // - we have already checked that `PyDict_Next` succeeded, so we can assume these to be non-null
487489 Some ( (
488- key. assume_borrowed_unchecked ( py) . to_owned ( ) ,
489- value. assume_borrowed_unchecked ( py) . to_owned ( ) ,
490+ unsafe { key. assume_borrowed_unchecked ( py) . to_owned ( ) } ,
491+ unsafe { value. assume_borrowed_unchecked ( py) . to_owned ( ) } ,
490492 ) )
491493 } else {
492494 None
493495 }
494- } ) ,
496+ }
495497 }
496498 }
497499
0 commit comments