diff --git a/src/conversions/std/num.rs b/src/conversions/std/num.rs index c8757776264..e5c72b98ef0 100644 --- a/src/conversions/std/num.rs +++ b/src/conversions/std/num.rs @@ -50,16 +50,14 @@ macro_rules! extract_int { }; ($obj:ident, $error_val:expr, $pylong_as:expr, $force_index_call: literal) => { - // with python 3.9+ PyLong_AsLong takes care of calling PyNumber_Index itself - // hence no need for the slow `PyNumber_Index` path - // `PyLong_AsUnsignedLongLong` does not call `__index__`, hence the `force_index_call` argument - // 3.8 is a special case where `PyNumber_Index` is called but has slightly different semantics - // thus we use the conservative path for 3.8 + // In python 3.8+ `PyLong_AsLong` and friends takes care of calling `PyNumber_Index`, + // however 3.8 & 3.9 do lossy conversion of floats, hence we only use the + // simplest logic for 3.10+ where that was fixed - python/cpython#82180. + // `PyLong_AsUnsignedLongLong` does not call `PyNumber_Index`, hence the `force_index_call` argument // See https://github.com/PyO3/pyo3/pull/3742 for detials - if cfg!(Py_3_9) && !$force_index_call { + if cfg!(Py_3_10) && !$force_index_call { err_if_invalid_value($obj.py(), $error_val, unsafe { $pylong_as($obj.as_ptr()) }) } else if let Ok(long) = $obj.downcast::() { - // with 3.7 we have to do the `PyNumber_Index` check ourselves // fast path - checking for subclass of `int` just checks a bit in the type $object err_if_invalid_value($obj.py(), $error_val, unsafe { $pylong_as(long.as_ptr()) }) } else {