Skip to content

Commit 4931590

Browse files
committed
CPython compatibility misc
1 parent 3de9324 commit 4931590

7 files changed

Lines changed: 90 additions & 16 deletions

File tree

src/ffi/bytes.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

33
use core::ffi::c_char;
4-
use pyo3_ffi::{PyBytesObject, PyObject, PyVarObject, Py_ssize_t};
4+
use pyo3_ffi::{PyBytesObject, PyObject, Py_ssize_t};
5+
6+
use super::compat::Py_SIZE;
57

68
#[allow(non_snake_case)]
79
#[inline(always)]
@@ -12,5 +14,5 @@ pub(crate) unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char {
1214
#[allow(non_snake_case)]
1315
#[inline(always)]
1416
pub(crate) unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
15-
unsafe { (*op.cast::<PyVarObject>()).ob_size }
17+
unsafe { Py_SIZE(op.cast::<pyo3_ffi::PyVarObject>()) }
1618
}

src/ffi/compat.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,78 @@ pub(crate) unsafe fn _Py_IsImmortal(op: *mut pyo3_ffi::PyObject) -> core::ffi::c
5252
}
5353
}
5454

55+
#[cfg(CPython)]
56+
#[inline(always)]
57+
#[allow(non_snake_case)]
58+
pub(crate) unsafe fn Py_SIZE(op: *mut pyo3_ffi::PyVarObject) -> pyo3_ffi::Py_ssize_t {
59+
unsafe { (*op).ob_size }
60+
}
61+
62+
#[cfg(not(CPython))]
63+
#[inline(always)]
64+
#[allow(non_snake_case)]
65+
pub(crate) unsafe fn Py_SIZE(op: *mut pyo3_ffi::PyVarObject) -> pyo3_ffi::Py_ssize_t {
66+
unsafe { pyo3_ffi::Py_SIZE(op.cast::<pyo3_ffi::PyObject>()) }
67+
}
68+
69+
#[cfg(CPython)]
70+
#[inline(always)]
71+
#[allow(non_snake_case)]
72+
pub(crate) unsafe fn Py_SET_SIZE(op: *mut pyo3_ffi::PyVarObject, size: pyo3_ffi::Py_ssize_t) {
73+
unsafe { (*op).ob_size = size }
74+
}
75+
76+
#[cfg(not(CPython))]
77+
#[inline(always)]
78+
#[allow(non_snake_case)]
79+
pub(crate) unsafe fn Py_SET_SIZE(op: *mut pyo3_ffi::PyVarObject, size: pyo3_ffi::Py_ssize_t) {
80+
unimplemented!()
81+
}
82+
83+
#[cfg(CPython)]
84+
#[inline(always)]
85+
#[allow(non_snake_case)]
86+
pub(crate) unsafe fn PyTuple_GET_ITEM(
87+
op: *mut pyo3_ffi::PyObject,
88+
i: pyo3_ffi::Py_ssize_t,
89+
) -> *mut pyo3_ffi::PyObject {
90+
unsafe { pyo3_ffi::PyTuple_GET_ITEM(op, i) }
91+
}
92+
93+
#[cfg(not(CPython))]
94+
#[inline(always)]
95+
#[allow(non_snake_case)]
96+
pub(crate) unsafe fn PyTuple_GET_ITEM(
97+
op: *mut pyo3_ffi::PyObject,
98+
i: pyo3_ffi::Py_ssize_t,
99+
) -> *mut pyo3_ffi::PyObject {
100+
unsafe { pyo3_ffi::PyTuple_GetItem(op, i) }
101+
}
102+
103+
#[cfg(CPython)]
104+
#[inline(always)]
105+
#[allow(non_snake_case)]
106+
pub(crate) unsafe fn PyTuple_SET_ITEM(
107+
op: *mut pyo3_ffi::PyObject,
108+
i: pyo3_ffi::Py_ssize_t,
109+
v: *mut pyo3_ffi::PyObject,
110+
) {
111+
unsafe { pyo3_ffi::PyTuple_SET_ITEM(op, i, v) }
112+
}
113+
114+
#[cfg(not(CPython))]
115+
#[inline(always)]
116+
#[allow(non_snake_case)]
117+
pub(crate) unsafe fn PyTuple_SET_ITEM(
118+
op: *mut pyo3_ffi::PyObject,
119+
i: pyo3_ffi::Py_ssize_t,
120+
v: *mut pyo3_ffi::PyObject,
121+
) {
122+
unsafe {
123+
pyo3_ffi::PyTuple_SetItem(op, i, v);
124+
}
125+
}
126+
55127
unsafe extern "C" {
56128
pub fn _PyDict_Next(
57129
mp: *mut pyo3_ffi::PyObject,

src/ffi/fragment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub(crate) unsafe extern "C" fn orjson_fragment_tp_new(
7474
raise_args_exception();
7575
null_mut()
7676
} else {
77-
let contents = ffi!(PyTuple_GET_ITEM(args, 0));
77+
let contents = crate::ffi::PyTuple_GET_ITEM(args, 0);
7878
Py_INCREF(contents);
7979
let obj = Box::new(Fragment {
8080
#[cfg(Py_GIL_DISABLED)]

src/ffi/long.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub(crate) fn pylong_is_unsigned(ptr: *mut pyo3_ffi::PyObject) -> bool {
4646
#[cfg(not(Py_3_12))]
4747
#[inline(always)]
4848
pub(crate) fn pylong_is_unsigned(ptr: *mut pyo3_ffi::PyObject) -> bool {
49-
unsafe { (*ptr.cast::<pyo3_ffi::PyVarObject>()).ob_size > 0 }
49+
unsafe { super::compat::Py_SIZE(ptr.cast::<pyo3_ffi::PyVarObject>()) > 0 }
5050
}
5151

5252
#[cfg(all(Py_3_12, feature = "inline_int"))]
@@ -58,7 +58,7 @@ pub(crate) fn pylong_fits_in_i32(ptr: *mut pyo3_ffi::PyObject) -> bool {
5858
#[cfg(all(not(Py_3_12), feature = "inline_int"))]
5959
#[inline(always)]
6060
pub(crate) fn pylong_fits_in_i32(ptr: *mut pyo3_ffi::PyObject) -> bool {
61-
unsafe { isize::abs((*ptr.cast::<pyo3_ffi::PyVarObject>()).ob_size) == 1 }
61+
unsafe { isize::abs(super::compat::Py_SIZE(ptr.cast::<pyo3_ffi::PyVarObject>())) == 1 }
6262
}
6363

6464
#[cfg(all(Py_3_12, feature = "inline_int"))]
@@ -70,7 +70,7 @@ pub(crate) fn pylong_is_zero(ptr: *mut pyo3_ffi::PyObject) -> bool {
7070
#[cfg(all(not(Py_3_12), feature = "inline_int"))]
7171
#[inline(always)]
7272
pub(crate) fn pylong_is_zero(ptr: *mut pyo3_ffi::PyObject) -> bool {
73-
unsafe { (*ptr.cast::<pyo3_ffi::PyVarObject>()).ob_size == 0 }
73+
unsafe { super::compat::Py_SIZE(ptr.cast::<pyo3_ffi::PyVarObject>()) == 0 }
7474
}
7575

7676
#[cfg(all(Py_3_12, feature = "inline_int"))]
@@ -89,7 +89,7 @@ pub(crate) fn pylong_get_inline_value(ptr: *mut pyo3_ffi::PyObject) -> i64 {
8989
#[inline(always)]
9090
pub(crate) fn pylong_get_inline_value(ptr: *mut pyo3_ffi::PyObject) -> i64 {
9191
unsafe {
92-
(*ptr.cast::<pyo3_ffi::PyVarObject>()).ob_size as i64
93-
* i64::from((*ptr.cast::<PyLongObject>()).ob_digit)
92+
super::compat::Py_SIZE(ptr.cast::<pyo3_ffi::PyVarObject>()) as i64
93+
* i64::from(unsafe { (*ptr.cast::<PyLongObject>()).ob_digit })
9494
}
9595
}

src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ use core::ffi::{c_char, c_int, c_void};
8585
use pyo3_ffi::{
8686
PyCFunction_NewEx, PyErr_SetObject, PyLong_AsLong, PyLong_FromLongLong, PyMethodDef,
8787
PyMethodDefPointer, PyModuleDef, PyModuleDef_HEAD_INIT, PyModuleDef_Slot, PyObject,
88-
PyTuple_New, PyTuple_SET_ITEM, PyUnicode_FromStringAndSize, PyUnicode_InternFromString,
89-
PyVectorcall_NARGS, Py_DECREF, Py_SIZE, Py_ssize_t, METH_KEYWORDS, METH_O,
88+
PyTuple_New, PyUnicode_FromStringAndSize, PyUnicode_InternFromString, PyVectorcall_NARGS,
89+
Py_DECREF, Py_SIZE, Py_ssize_t, METH_KEYWORDS, METH_O,
9090
};
9191

9292
use crate::util::{isize_to_usize, usize_to_isize};
@@ -284,9 +284,9 @@ fn raise_loads_exception(err: deserialize::DeserializeError) -> *mut PyObject {
284284
PyUnicode_FromStringAndSize(msg.as_ptr().cast::<c_char>(), usize_to_isize(msg.len()));
285285
let args = PyTuple_New(3);
286286
let pos = PyLong_FromLongLong(err_pos);
287-
PyTuple_SET_ITEM(args, 0, err_msg);
288-
PyTuple_SET_ITEM(args, 1, doc);
289-
PyTuple_SET_ITEM(args, 2, pos);
287+
crate::ffi::PyTuple_SET_ITEM(args, 0, err_msg);
288+
crate::ffi::PyTuple_SET_ITEM(args, 1, doc);
289+
crate::ffi::PyTuple_SET_ITEM(args, 2, pos);
290290
PyErr_SetObject(typeref::JsonDecodeError, args);
291291
debug_assert!(ffi!(Py_REFCNT(args)) <= 2);
292292
Py_DECREF(args);
@@ -400,7 +400,7 @@ pub(crate) unsafe extern "C" fn dumps(
400400
}
401401
if unlikely!(!kwnames.is_null()) {
402402
for i in 0..=Py_SIZE(kwnames).saturating_sub(1) {
403-
let arg = ffi!(PyTuple_GET_ITEM(kwnames, i as Py_ssize_t));
403+
let arg = crate::ffi::PyTuple_GET_ITEM(kwnames, i as Py_ssize_t);
404404
if core::ptr::eq(arg, typeref::DEFAULT) {
405405
if unlikely!(num_args & 2 == 2) {
406406
return raise_dumps_exception_fixed(

src/serialize/per_type/numpy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ impl NumpyDatetimeUnit {
12461246
let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR));
12471247
let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR));
12481248
let el0 = ffi!(PyList_GET_ITEM(descr, 0));
1249-
let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1));
1249+
let descr_str = unsafe { crate::ffi::PyTuple_GET_ITEM(el0, 1) };
12501250
let uni = unsafe { PyStr::from_ptr_unchecked(descr_str).to_str().unwrap() };
12511251
if uni.len() < 5 {
12521252
return Self::NaT;

src/serialize/writer/byteswriter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl BytesWriter {
4040
self.len += 1;
4141
}
4242
core::ptr::write(self.buffer_ptr(), 0);
43-
(*self.bytes.cast::<PyVarObject>()).ob_size = usize_to_isize(self.len);
43+
crate::ffi::Py_SET_SIZE(self.bytes.cast::<PyVarObject>(), usize_to_isize(self.len));
4444
self.resize(self.len);
4545
self.bytes_ptr()
4646
}

0 commit comments

Comments
 (0)