Skip to content

Commit 0f8445e

Browse files
authored
defer to PyO3 i64 extraction to avoid implicit integer casts (#1288)
1 parent 8f5f91a commit 0f8445e

File tree

2 files changed

+13
-23
lines changed

2 files changed

+13
-23
lines changed

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,9 @@ testpaths = 'tests'
7373
log_format = '%(name)s %(levelname)s: %(message)s'
7474
filterwarnings = [
7575
'error',
76-
# Work around https://github.com/pytest-dev/pytest/issues/10977 for Python 3.12
77-
'ignore:(ast\.Str|ast\.NameConstant|ast\.Num|Attribute s) is deprecated and will be removed.*:DeprecationWarning:',
78-
# issue with pytz - https://github.com/stub42/pytz/issues/105 for Python 3.12
79-
'ignore:datetime\.utcfromtimestamp\(\) is deprecated.*:DeprecationWarning:',
76+
# Python 3.9 and below allowed truncation of float to integers in some
77+
# cases, by not making this an error we can test for this behaviour
78+
'ignore:(.+)Implicit conversion to integers using __int__ is deprecated',
8079
]
8180
timeout = 30
8281
xfail_strict = true

src/tools.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::borrow::Cow;
33
use pyo3::exceptions::PyKeyError;
44
use pyo3::prelude::*;
55
use pyo3::types::{PyDict, PyString};
6-
use pyo3::{ffi, intern, FromPyObject};
6+
use pyo3::{intern, FromPyObject};
77

88
use jiter::{cached_py_string, pystring_fast_new, StringCacheMode};
99

@@ -124,26 +124,17 @@ pub fn safe_repr<'py>(v: &Bound<'py, PyAny>) -> ReprOutput<'py> {
124124
}
125125
}
126126

127-
/// Extract an i64 from a python object more quickly, see
128-
/// https://github.com/PyO3/pyo3/pull/3742#discussion_r1451763928
129-
#[cfg(not(any(target_pointer_width = "32", windows, PyPy)))]
130-
pub fn extract_i64(obj: &Bound<'_, PyAny>) -> Option<i64> {
131-
let val = unsafe { ffi::PyLong_AsLong(obj.as_ptr()) };
132-
if val == -1 && PyErr::occurred(obj.py()) {
133-
unsafe { ffi::PyErr_Clear() };
134-
None
135-
} else {
136-
Some(val)
137-
}
138-
}
139-
140-
#[cfg(any(target_pointer_width = "32", windows, PyPy))]
141127
pub fn extract_i64(v: &Bound<'_, PyAny>) -> Option<i64> {
142-
if v.is_instance_of::<pyo3::types::PyInt>() {
143-
v.extract().ok()
144-
} else {
145-
None
128+
#[cfg(PyPy)]
129+
if !v.is_instance_of::<pyo3::types::PyInt>() {
130+
// PyPy used __int__ to cast floats to ints after CPython removed it,
131+
// see https://github.com/pypy/pypy/issues/4949
132+
//
133+
// Can remove this after PyPy 7.3.17 is released
134+
return None;
146135
}
136+
137+
v.extract().ok()
147138
}
148139

149140
pub(crate) fn new_py_string<'py>(py: Python<'py>, s: &str, cache_str: StringCacheMode) -> Bound<'py, PyString> {

0 commit comments

Comments
 (0)