Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffi: update modsupport.rs for Python 3.13 #4420

Merged
merged 1 commit into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/4420.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correct FFI definition `PyArg_ParseTupleAndKeywords` to take `*const *const c_char` instead of `*mut *mut c_char` on Python 3.13 and up.
1 change: 1 addition & 0 deletions newsfragments/4420.removed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove FFI definition of private variable `_Py_PackageContext`.
39 changes: 8 additions & 31 deletions pyo3-ffi/src/modsupport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ extern "C" {
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *const c_char,
arg4: *mut *mut c_char,
#[cfg(not(Py_3_13))] arg4: *mut *mut c_char,
#[cfg(Py_3_13)] arg4: *const *const c_char,
...
) -> c_int;

// skipped PyArg_VaParse
// skipped PyArg_VaParseTupleAndKeywords

pub fn PyArg_ValidateKeywordArguments(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyArg_UnpackTuple")]
pub fn PyArg_UnpackTuple(
Expand All @@ -26,32 +31,10 @@ extern "C" {
arg4: Py_ssize_t,
...
) -> c_int;

#[cfg_attr(PyPy, link_name = "PyPy_BuildValue")]
pub fn Py_BuildValue(arg1: *const c_char, ...) -> *mut PyObject;
// #[cfg_attr(PyPy, link_name = "_PyPy_BuildValue_SizeT")]
//pub fn _Py_BuildValue_SizeT(arg1: *const c_char, ...)
// -> *mut PyObject;
// #[cfg_attr(PyPy, link_name = "PyPy_VaBuildValue")]

// skipped non-limited _PyArg_UnpackStack
// skipped non-limited _PyArg_NoKeywords
// skipped non-limited _PyArg_NoKwnames
// skipped non-limited _PyArg_NoPositional
// skipped non-limited _PyArg_BadArgument
// skipped non-limited _PyArg_CheckPositional

//pub fn Py_VaBuildValue(arg1: *const c_char, arg2: va_list)
// -> *mut PyObject;

// skipped non-limited _Py_VaBuildStack
// skipped non-limited _PyArg_Parser

// skipped non-limited _PyArg_ParseTupleAndKeywordsFast
// skipped non-limited _PyArg_ParseStack
// skipped non-limited _PyArg_ParseStackAndKeywords
// skipped non-limited _PyArg_VaParseTupleAndKeywordsFast
// skipped non-limited _PyArg_UnpackKeywords
// skipped non-limited _PyArg_Fini
// skipped Py_VaBuildValue

#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObjectRef")]
Expand Down Expand Up @@ -159,9 +142,3 @@ pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject
},
)
}

#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut _Py_PackageContext: *const c_char;
}
41 changes: 25 additions & 16 deletions tests/test_pyfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,7 @@ fn test_pycfunction_new() {
#[test]
fn test_pycfunction_new_with_keywords() {
use pyo3::ffi;
use std::ffi::CString;
use std::os::raw::{c_char, c_long};
use std::os::raw::c_long;
use std::ptr;

Python::with_gil(|py| {
Expand All @@ -375,28 +374,38 @@ fn test_pycfunction_new_with_keywords() {
) -> *mut ffi::PyObject {
let mut foo: c_long = 0;
let mut bar: c_long = 0;
let foo_ptr: *mut c_long = &mut foo;
let bar_ptr: *mut c_long = &mut bar;

let foo_name = CString::new("foo").unwrap();
let foo_name_raw: *mut c_char = foo_name.into_raw();
let kw_bar_name = CString::new("kw_bar").unwrap();
let kw_bar_name_raw: *mut c_char = kw_bar_name.into_raw();
#[cfg(not(Py_3_13))]
let foo_name = std::ffi::CString::new("foo").unwrap();
#[cfg(not(Py_3_13))]
let kw_bar_name = std::ffi::CString::new("kw_bar").unwrap();
#[cfg(not(Py_3_13))]
let mut args_names = [foo_name.into_raw(), kw_bar_name.into_raw(), ptr::null_mut()];

let mut arglist = vec![foo_name_raw, kw_bar_name_raw, ptr::null_mut()];
let arglist_ptr: *mut *mut c_char = arglist.as_mut_ptr();

let arg_pattern: *const c_char = CString::new("l|l").unwrap().into_raw();
#[cfg(Py_3_13)]
let args_names = [
c_str!("foo").as_ptr(),
c_str!("kw_bar").as_ptr(),
ptr::null_mut(),
];

ffi::PyArg_ParseTupleAndKeywords(
args,
kwds,
arg_pattern,
arglist_ptr,
foo_ptr,
bar_ptr,
c_str!("l|l").as_ptr(),
#[cfg(Py_3_13)]
args_names.as_ptr(),
#[cfg(not(Py_3_13))]
args_names.as_mut_ptr(),
&mut foo,
&mut bar,
);

#[cfg(not(Py_3_13))]
drop(std::ffi::CString::from_raw(args_names[0]));
#[cfg(not(Py_3_13))]
drop(std::ffi::CString::from_raw(args_names[1]));

ffi::PyLong_FromLong(foo * bar)
}

Expand Down
Loading