Skip to content

Commit 27d7e27

Browse files
committed
Define _PyLong_AsByteArray with_exceptions in 3.13+
1 parent ff6741a commit 27d7e27

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

include/pyo3/pyo3-ffi/src/cpython/longobject.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ extern "C" {
6161
is_signed: c_int,
6262
) -> *mut PyObject;
6363

64+
#[cfg(Py_3_13)]
65+
#[cfg_attr(PyPy, link_name = "_PyPyLong_AsByteArrayO")]
66+
pub fn _PyLong_AsByteArray(
67+
v: *mut PyLongObject,
68+
bytes: *mut c_uchar,
69+
n: size_t,
70+
little_endian: c_int,
71+
is_signed: c_int,
72+
with_exceptions: c_int,
73+
) -> c_int;
74+
75+
#[cfg(not(Py_3_13))]
6476
#[cfg_attr(PyPy, link_name = "_PyPyLong_AsByteArrayO")]
6577
pub fn _PyLong_AsByteArray(
6678
v: *mut PyLongObject,

src/serialize/per_type/int.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,39 @@ impl Serialize for IntSerializer {
4444
}
4545
} else {
4646
let mut buffer: [u8; 8] = [0; 8];
47+
48+
#[cfg(not(Py_3_13))]
49+
let ret = pyo3_ffi::_PyLong_AsByteArray(
50+
self.ptr.cast::<pyo3_ffi::PyLongObject>(),
51+
buffer.as_mut_ptr().cast::<core::ffi::c_uchar>(),
52+
8,
53+
1,
54+
is_signed,
55+
);
56+
#[cfg(Py_3_13)]
4757
let ret = pyo3_ffi::_PyLong_AsByteArray(
4858
self.ptr.cast::<pyo3_ffi::PyLongObject>(),
4959
buffer.as_mut_ptr().cast::<core::ffi::c_uchar>(),
5060
8,
5161
1,
5262
is_signed,
63+
0,
5364
);
5465
if unlikely!(ret == -1) {
66+
#[cfg(not(Py_3_13))]
5567
ffi!(PyErr_Clear());
5668
err!(SerializeError::Integer64Bits)
5769
}
5870
if is_signed == 0 {
59-
let val = core::mem::transmute::<[u8; 8], u64>(buffer);
71+
let val = u64::from_ne_bytes(buffer);
6072
if unlikely!(opt_enabled!(self.opts, STRICT_INTEGER))
6173
&& val > STRICT_INT_MAX as u64
6274
{
6375
err!(SerializeError::Integer53Bits)
6476
}
6577
serializer.serialize_u64(val)
6678
} else {
67-
let val = core::mem::transmute::<[u8; 8], i64>(buffer);
79+
let val = i64::from_ne_bytes(buffer);
6880
if unlikely!(opt_enabled!(self.opts, STRICT_INTEGER))
6981
&& !(STRICT_INT_MIN..=STRICT_INT_MAX).contains(&val)
7082
{

src/serialize/per_type/uuid.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,26 @@ impl UUID {
2222
// test_uuid_immutable, test_uuid_int
2323
let py_int = ffi!(PyObject_GetAttr(self.ptr, INT_ATTR_STR));
2424
ffi!(Py_DECREF(py_int));
25-
let buffer: [c_uchar; 16] = [0; 16];
25+
let mut buffer: [c_uchar; 16] = [0; 16];
2626
unsafe {
2727
// test_uuid_overflow
28+
#[cfg(not(Py_3_13))]
2829
pyo3_ffi::_PyLong_AsByteArray(
2930
py_int.cast::<pyo3_ffi::PyLongObject>(),
30-
buffer.as_ptr().cast_mut(),
31+
buffer.as_mut_ptr(),
3132
16,
3233
1, // little_endian
3334
0, // is_signed
34-
)
35+
);
36+
#[cfg(Py_3_13)]
37+
pyo3_ffi::_PyLong_AsByteArray(
38+
py_int.cast::<pyo3_ffi::PyLongObject>(),
39+
buffer.as_mut_ptr(),
40+
16,
41+
1, // little_endian
42+
0, // is_signed
43+
0,
44+
);
3545
};
3646
value = u128::from_le_bytes(buffer);
3747
}

0 commit comments

Comments
 (0)