@@ -358,11 +358,16 @@ mod fast_128bit_int_conversion {
358358 use super :: * ;
359359
360360 #[ cfg( Py_3_14 ) ]
361- const PY_LONG_DIGIT_BITS : usize = 30 ;
361+ const PYLONG_BITS_IN_DIGIT : usize = 30 ;
362362
363363 #[ cfg( Py_3_14 ) ]
364- fn get_bits_per_digit ( ) -> usize {
365- unsafe { ( * ffi:: PyLong_GetNativeLayout ( ) ) . bits_per_digit as usize }
364+ fn is_30bit_layout ( ) -> bool {
365+ static DIGITS : std:: sync:: OnceLock < bool > = std:: sync:: OnceLock :: new ( ) ;
366+
367+ * DIGITS . get_or_init ( || {
368+ let layout = unsafe { & * ffi:: PyLong_GetNativeLayout ( ) } ;
369+ layout. bits_per_digit == PYLONG_BITS_IN_DIGIT
370+ } )
366371 }
367372
368373 // for 128bit Integers
@@ -379,8 +384,8 @@ mod fast_128bit_int_conversion {
379384 fn into_pyobject( self , py: Python <' py>) -> Result <Self :: Output , Self :: Error > {
380385 #[ cfg( Py_3_14 ) ]
381386 {
382- if get_bits_per_digit ( ) == PY_LONG_DIGIT_BITS {
383- const DIGIT_MASK : u32 = ( 1 << PY_LONG_DIGIT_BITS ) - 1 ;
387+ if !is_30bit_layout ( ) {
388+ const DIGIT_MASK : u32 = ( 1 << PYLONG_BITS_IN_DIGIT ) - 1 ;
384389
385390 let value = self as u128 ;
386391 let negative = $is_signed && ( self as i128 ) < 0 ;
@@ -393,7 +398,7 @@ mod fast_128bit_int_conversion {
393398 let n_digits = if bits == 0 {
394399 1
395400 } else {
396- bits. div_ceil( PY_LONG_DIGIT_BITS )
401+ bits. div_ceil( PYLONG_BITS_IN_DIGIT )
397402 } ;
398403 let mut ptr = std:: ptr:: null_mut( ) ;
399404 let long_writer = unsafe {
@@ -410,7 +415,7 @@ mod fast_128bit_int_conversion {
410415 let mut rest = abs;
411416 for i in 0 ..n_digits {
412417 unsafe { digits. add( i) . write( rest as u32 & DIGIT_MASK ) } ;
413- rest >>= PY_LONG_DIGIT_BITS ;
418+ rest >>= PYLONG_BITS_IN_DIGIT ;
414419 }
415420 return unsafe {
416421 ffi:: PyLongWriter_Finish ( long_writer)
@@ -456,7 +461,7 @@ mod fast_128bit_int_conversion {
456461 let num = nb_index( & ob) ?;
457462 #[ cfg( Py_3_14 ) ]
458463 {
459- if get_bits_per_digit ( ) == PY_LONG_DIGIT_BITS {
464+ if !is_30bit_layout ( ) {
460465 let mut long_export = MaybeUninit :: <ffi:: PyLongExport >:: uninit( ) ;
461466 unsafe {
462467 crate :: err:: error_on_minusone(
@@ -492,7 +497,7 @@ mod fast_128bit_int_conversion {
492497 if i == 4 && digit >> 8 != 0 {
493498 overflowed = true ;
494499 }
495- abs |= digit << ( i * PY_LONG_DIGIT_BITS ) ;
500+ abs |= digit << ( i * PYLONG_BITS_IN_DIGIT ) ;
496501 }
497502 unsafe { ffi:: PyLong_FreeExport ( long_export. as_mut_ptr( ) ) } ;
498503 if overflowed {
0 commit comments