5757//! [scalars-datetime64]: https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.datetime64
5858//! [scalars-timedelta64]: https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.timedelta64
5959
60- use std:: cell:: UnsafeCell ;
60+ use std:: cell:: RefCell ;
6161use std:: collections:: hash_map:: Entry ;
6262use std:: fmt;
6363use std:: hash:: Hash ;
6464use std:: marker:: PhantomData ;
6565
66- use pyo3:: { Py , Python } ;
66+ use pyo3:: { sync :: GILProtected , Py , Python } ;
6767use rustc_hash:: FxHashMap ;
6868
6969use crate :: dtype:: { Element , PyArrayDescr } ;
@@ -206,32 +206,25 @@ impl<U: Unit> fmt::Debug for Timedelta<U> {
206206
207207struct TypeDescriptors {
208208 npy_type : NPY_TYPES ,
209- dtypes : UnsafeCell < Option < FxHashMap < NPY_DATETIMEUNIT , Py < PyArrayDescr > > > > ,
209+ #[ allow( clippy:: type_complexity) ]
210+ dtypes : GILProtected < RefCell < Option < FxHashMap < NPY_DATETIMEUNIT , Py < PyArrayDescr > > > > > ,
210211}
211212
212- unsafe impl Sync for TypeDescriptors { }
213-
214213impl TypeDescriptors {
215214 /// `npy_type` must be either `NPY_DATETIME` or `NPY_TIMEDELTA`.
216215 const unsafe fn new ( npy_type : NPY_TYPES ) -> Self {
217216 Self {
218217 npy_type,
219- dtypes : UnsafeCell :: new ( None ) ,
218+ dtypes : GILProtected :: new ( RefCell :: new ( None ) ) ,
220219 }
221220 }
222221
223- #[ allow( clippy:: mut_from_ref) ]
224- unsafe fn get ( & self ) -> & mut FxHashMap < NPY_DATETIMEUNIT , Py < PyArrayDescr > > {
225- ( * self . dtypes . get ( ) ) . get_or_insert_with ( Default :: default)
226- }
227-
228222 #[ allow( clippy:: wrong_self_convention) ]
229223 fn from_unit < ' py > ( & ' py self , py : Python < ' py > , unit : NPY_DATETIMEUNIT ) -> & ' py PyArrayDescr {
230- // SAFETY: We hold the GIL and we do not call into user code which might re-enter.
231- let dtypes = unsafe { self . get ( ) } ;
224+ let mut dtypes = self . dtypes . get ( py) . borrow_mut ( ) ;
232225
233- match dtypes. entry ( unit) {
234- Entry :: Occupied ( entry) => entry. into_mut ( ) . as_ref ( py) ,
226+ match dtypes. get_or_insert_with ( Default :: default ) . entry ( unit) {
227+ Entry :: Occupied ( entry) => entry. into_mut ( ) . clone ( ) . into_ref ( py) ,
235228 Entry :: Vacant ( entry) => {
236229 let dtype = PyArrayDescr :: new_from_npy_type ( py, self . npy_type ) ;
237230
@@ -244,7 +237,7 @@ impl TypeDescriptors {
244237 metadata. meta . num = 1 ;
245238 }
246239
247- entry. insert ( dtype. into ( ) ) . as_ref ( py)
240+ entry. insert ( dtype. into ( ) ) . clone ( ) . into_ref ( py)
248241 }
249242 }
250243 }
0 commit comments