Skip to content

Commit 962a535

Browse files
authored
sync abstract.h bindings to Python 3.14 (#5942)
* sync `abstract.h` bindings to Python 3.14 * fmt * newsfragment, remove some private symbols more aggressively * more newsfragment * remove x86 workarounds for removed private functions * fixup for PyPy, GraalPy * use checked_shl to calculate `PY_VECTORCALL_ARGUMENTS_OFFSET` * fix return type of `PyVectorcall_NARGS`
1 parent 4c8e805 commit 962a535

5 files changed

Lines changed: 134 additions & 178 deletions

File tree

newsfragments/5942.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add FFI definitions `PyObject_GetAIter`, `PyAIter_Check`, `PyMapping_HasKeyWithError`, `PyMapping_HasKeyStringWithError`, `PyMapping_GetOptionalItem`, `PyMapping_GetOptionalItemString`, `PySequence_ITEM`, `PySequence_Fast_GET_SIZE`, `PySequence_Fast_GET_ITEM`, and `PySequence_Fast_ITEMS`.

newsfragments/5942.removed.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove private FFI definitions `_PyStack_AsDict`, `_PyObject_CallNoArg`, `_PyObject_FastCall`, `_PyObject_FastCallTstate`. `_PyObject_VectorcallTstate`, `_PyObject_MakeTpCall`, `_Py_CheckFunctionResult`, `_PyObject_CallFunction_SizeT`, `_PyObject_CallMethod_SizeT`, and `_PySequence_IterSearch`.
2+
3+
Remove FFI definitions `PY_ITERSEARCH_COUNT`, `PY_ITERSEARCH_INDEX`, and `PY_ITERSEARCH_CONTAINS`.

pyo3-ffi/src/abstract_.rs

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,13 @@ extern_libpython! {
5454
...
5555
) -> *mut PyObject;
5656

57-
#[cfg(not(Py_3_13))]
57+
#[cfg(all(PyPy, not(Py_3_13)))] // called internally in PyUnicodeDecodeError_Create on PyPy
5858
#[cfg_attr(PyPy, link_name = "_PyPyObject_CallFunction_SizeT")]
59-
pub fn _PyObject_CallFunction_SizeT(
59+
pub(crate) fn _PyObject_CallFunction_SizeT(
6060
callable_object: *mut PyObject,
6161
format: *const c_char,
6262
...
6363
) -> *mut PyObject;
64-
#[cfg(not(Py_3_13))]
65-
#[cfg_attr(PyPy, link_name = "_PyPyObject_CallMethod_SizeT")]
66-
pub fn _PyObject_CallMethod_SizeT(
67-
o: *mut PyObject,
68-
method: *const c_char,
69-
format: *const c_char,
70-
...
71-
) -> *mut PyObject;
7264

7365
#[cfg_attr(PyPy, link_name = "PyPyObject_CallFunctionObjArgs")]
7466
pub fn PyObject_CallFunctionObjArgs(callable: *mut PyObject, ...) -> *mut PyObject;
@@ -78,10 +70,24 @@ extern_libpython! {
7870
method: *mut PyObject,
7971
...
8072
) -> *mut PyObject;
73+
74+
#[cfg(all(Py_3_12, Py_LIMITED_API))] // is an inline function in cpython/abstract.rs on version-specific ABI
75+
#[cfg_attr(PyPy, link_name = "PyPyVectorcall_NARGS")]
76+
pub fn PyVectorcall_NARGS(nargsf: size_t) -> Py_ssize_t;
77+
78+
#[cfg_attr(not(any(Py_3_12, PyPy)), link_name = "_PyVectorcall_Call")] // symbol made public in 3.12
79+
#[cfg_attr(PyPy, link_name = "PyPyVectorcall_Call")]
80+
pub fn PyVectorcall_Call(
81+
callable: *mut PyObject,
82+
tuple: *mut PyObject,
83+
dict: *mut PyObject,
84+
) -> *mut PyObject;
8185
}
86+
8287
#[cfg(any(Py_3_12, not(Py_LIMITED_API)))]
83-
pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t =
84-
1 << (8 * std::mem::size_of::<size_t>() as size_t - 1);
88+
pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = (1 as size_t)
89+
.checked_shl((8 * std::mem::size_of::<size_t>() - 1) as u32)
90+
.expect("size_t should fit the flag bits");
8591

8692
extern_libpython! {
8793
#[cfg_attr(PyPy, link_name = "PyPyObject_Vectorcall")]
@@ -104,14 +110,12 @@ extern_libpython! {
104110
pub fn PyObject_Type(o: *mut PyObject) -> *mut PyObject;
105111
#[cfg_attr(PyPy, link_name = "PyPyObject_Size")]
106112
pub fn PyObject_Size(o: *mut PyObject) -> Py_ssize_t;
107-
}
108113

109-
#[inline]
110-
pub unsafe fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t {
111-
PyObject_Size(o)
112-
}
114+
// PyObject_Length is a direct alias for PyObject_Size
115+
#[cfg_attr(not(PyPy), link_name = "PyObject_Size")]
116+
#[cfg_attr(PyPy, link_name = "PyPyObject_Size")]
117+
pub fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t;
113118

114-
extern_libpython! {
115119
#[cfg_attr(PyPy, link_name = "PyPyObject_GetItem")]
116120
pub fn PyObject_GetItem(o: *mut PyObject, key: *mut PyObject) -> *mut PyObject;
117121
#[cfg_attr(PyPy, link_name = "PyPyObject_SetItem")]
@@ -120,18 +124,20 @@ extern_libpython! {
120124
pub fn PyObject_DelItemString(o: *mut PyObject, key: *const c_char) -> c_int;
121125
#[cfg_attr(PyPy, link_name = "PyPyObject_DelItem")]
122126
pub fn PyObject_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int;
123-
}
124127

125-
extern_libpython! {
126128
#[cfg_attr(PyPy, link_name = "PyPyObject_Format")]
127129
pub fn PyObject_Format(obj: *mut PyObject, format_spec: *mut PyObject) -> *mut PyObject;
128130
#[cfg_attr(PyPy, link_name = "PyPyObject_GetIter")]
129131
pub fn PyObject_GetIter(arg1: *mut PyObject) -> *mut PyObject;
130-
}
132+
#[cfg(Py_3_10)]
133+
#[cfg_attr(PyPy, link_name = "PyPyObject_GetAIter")]
134+
pub fn PyObject_GetAIter(arg1: *mut PyObject) -> *mut PyObject;
131135

132-
extern_libpython! {
133136
#[cfg_attr(PyPy, link_name = "PyPyIter_Check")]
134137
pub fn PyIter_Check(obj: *mut PyObject) -> c_int;
138+
#[cfg(Py_3_10)]
139+
#[cfg_attr(PyPy, link_name = "PyPyAIter_Check")]
140+
pub fn PyAIter_Check(obj: *mut PyObject) -> c_int;
135141

136142
#[cfg(Py_3_14)]
137143
#[cfg_attr(PyPy, link_name = "PyPyIter_NextItem")]
@@ -185,20 +191,8 @@ extern_libpython! {
185191
pub fn PyNumber_Xor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
186192
#[cfg_attr(PyPy, link_name = "PyPyNumber_Or")]
187193
pub fn PyNumber_Or(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
188-
}
189-
190-
// Defined as this macro in Python limited API, but relies on
191-
// non-limited PyTypeObject. Don't expose this since it cannot be used.
192-
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
193-
#[inline]
194-
pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int {
195-
let tp_as_number = (*Py_TYPE(o)).tp_as_number;
196-
(!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int
197-
}
198194

199-
extern_libpython! {
200-
#[cfg(any(Py_LIMITED_API, PyPy))]
201-
#[link_name = "PyPyIndex_Check"]
195+
#[cfg_attr(PyPy, link_name = "PyPyIndex_Check")]
202196
pub fn PyIndex_Check(o: *mut PyObject) -> c_int;
203197

204198
#[cfg_attr(PyPy, link_name = "PyPyNumber_Index")]
@@ -246,18 +240,11 @@ extern_libpython! {
246240
#[cfg_attr(PyPy, link_name = "PyPySequence_Size")]
247241
pub fn PySequence_Size(o: *mut PyObject) -> Py_ssize_t;
248242

249-
#[cfg(PyPy)]
250-
#[link_name = "PyPySequence_Length"]
243+
// PySequence_Length is a direct alias for PySequence_Size
244+
#[cfg_attr(not(PyPy), link_name = "PySequence_Size")]
245+
#[cfg_attr(PyPy, link_name = "PyPySequence_Size")]
251246
pub fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t;
252-
}
253247

254-
#[inline]
255-
#[cfg(not(PyPy))]
256-
pub unsafe fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t {
257-
PySequence_Size(o)
258-
}
259-
260-
extern_libpython! {
261248
#[cfg_attr(PyPy, link_name = "PyPySequence_Concat")]
262249
pub fn PySequence_Concat(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
263250
#[cfg_attr(PyPy, link_name = "PyPySequence_Repeat")]
@@ -285,20 +272,15 @@ extern_libpython! {
285272
pub fn PySequence_List(o: *mut PyObject) -> *mut PyObject;
286273
#[cfg_attr(PyPy, link_name = "PyPySequence_Fast")]
287274
pub fn PySequence_Fast(o: *mut PyObject, m: *const c_char) -> *mut PyObject;
288-
// skipped PySequence_Fast_GET_SIZE
289-
// skipped PySequence_Fast_GET_ITEM
290-
// skipped PySequence_Fast_GET_ITEMS
291275
pub fn PySequence_Count(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t;
292276
#[cfg_attr(PyPy, link_name = "PyPySequence_Contains")]
293277
pub fn PySequence_Contains(seq: *mut PyObject, ob: *mut PyObject) -> c_int;
294-
}
295278

296-
#[inline]
297-
pub unsafe fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int {
298-
PySequence_Contains(o, value)
299-
}
279+
// PySequence_In is a direct alias for PySequence_Contains
280+
#[cfg_attr(not(PyPy), link_name = "PySequence_Contains")]
281+
#[cfg_attr(PyPy, link_name = "PyPySequence_Contains")]
282+
pub fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int;
300283

301-
extern_libpython! {
302284
#[cfg_attr(PyPy, link_name = "PyPySequence_Index")]
303285
pub fn PySequence_Index(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t;
304286
#[cfg_attr(PyPy, link_name = "PyPySequence_InPlaceConcat")]
@@ -310,17 +292,12 @@ extern_libpython! {
310292
#[cfg_attr(PyPy, link_name = "PyPyMapping_Size")]
311293
pub fn PyMapping_Size(o: *mut PyObject) -> Py_ssize_t;
312294

313-
#[cfg(PyPy)]
314-
#[link_name = "PyPyMapping_Length"]
295+
// PyMapping_Length is a direct alias for PyMapping_Size
296+
#[cfg_attr(not(PyPy), link_name = "PyMapping_Size")]
297+
#[cfg_attr(PyPy, link_name = "PyPyMapping_Size")]
315298
pub fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t;
316299
}
317300

318-
#[inline]
319-
#[cfg(not(PyPy))]
320-
pub unsafe fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t {
321-
PyMapping_Size(o)
322-
}
323-
324301
#[inline]
325302
pub unsafe fn PyMapping_DelItemString(o: *mut PyObject, key: *mut c_char) -> c_int {
326303
PyObject_DelItemString(o, key)
@@ -336,6 +313,12 @@ extern_libpython! {
336313
pub fn PyMapping_HasKeyString(o: *mut PyObject, key: *const c_char) -> c_int;
337314
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKey")]
338315
pub fn PyMapping_HasKey(o: *mut PyObject, key: *mut PyObject) -> c_int;
316+
#[cfg(Py_3_13)]
317+
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyWithError")]
318+
pub fn PyMapping_HasKeyWithError(o: *mut PyObject, key: *mut PyObject) -> c_int;
319+
#[cfg(Py_3_13)]
320+
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyStringWithError")]
321+
pub fn PyMapping_HasKeyStringWithError(o: *mut PyObject, key: *const c_char) -> c_int;
339322
#[cfg_attr(PyPy, link_name = "PyPyMapping_Keys")]
340323
pub fn PyMapping_Keys(o: *mut PyObject) -> *mut PyObject;
341324
#[cfg_attr(PyPy, link_name = "PyPyMapping_Values")]
@@ -344,6 +327,20 @@ extern_libpython! {
344327
pub fn PyMapping_Items(o: *mut PyObject) -> *mut PyObject;
345328
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetItemString")]
346329
pub fn PyMapping_GetItemString(o: *mut PyObject, key: *const c_char) -> *mut PyObject;
330+
#[cfg(Py_3_13)]
331+
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItem")]
332+
pub fn PyMapping_GetOptionalItem(
333+
o: *mut PyObject,
334+
key: *mut PyObject,
335+
result: *mut *mut PyObject,
336+
) -> c_int;
337+
#[cfg(Py_3_13)]
338+
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItemString")]
339+
pub fn PyMapping_GetOptionalItemString(
340+
o: *mut PyObject,
341+
key: *const c_char,
342+
result: *mut *mut PyObject,
343+
) -> c_int;
347344
#[cfg_attr(PyPy, link_name = "PyPyMapping_SetItemString")]
348345
pub fn PyMapping_SetItemString(
349346
o: *mut PyObject,

0 commit comments

Comments
 (0)