Merge pull request #3336 from davidhewitt/3.12-ffi

Update some FFI definitions for Python 3.12
This commit is contained in:
David Hewitt 2023-08-11 12:47:57 +00:00 committed by GitHub
commit ba72f58502
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 139 additions and 74 deletions

View file

@ -0,0 +1 @@
Add FFI symbol `Py_GETENV`.

View file

@ -0,0 +1 @@
Deprecate FFI definitions which are deprecated in Python 3.12.

View file

@ -152,6 +152,10 @@ pub fn for_all_fields(input: proc_macro::TokenStream) -> proc_macro::TokenStream
// PyObject since 3.12 implements ob_refcnt as a union; bindgen creates // PyObject since 3.12 implements ob_refcnt as a union; bindgen creates
// an anonymous name for the field // an anonymous name for the field
Ident::new("__bindgen_anon_1", Span::call_site()) Ident::new("__bindgen_anon_1", Span::call_site())
} else if struct_name == "PyMemberDef" && field_name == "type_code" {
// the field name in the C API is `type`, but that's a keyword in Rust
// so PyO3 picked type_code, bindgen picked type_
Ident::new("type_", Span::call_site())
} else { } else {
field_ident.clone() field_ident.clone()
}; };

View file

@ -1,3 +1,4 @@
#include "Python.h" #include "Python.h"
#include "datetime.h" #include "datetime.h"
#include "frameobject.h" #include "frameobject.h"
#include "structmember.h"

View file

@ -1,7 +1,6 @@
use crate::object;
#[cfg(Py_3_8)] #[cfg(Py_3_8)]
use crate::vectorcallfunc; use crate::vectorcallfunc;
use crate::{PyObject, Py_ssize_t}; use crate::{object, PyGetSetDef, PyMemberDef, PyMethodDef, PyObject, Py_ssize_t};
use std::mem; use std::mem;
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void}; use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
@ -247,9 +246,9 @@ pub struct PyTypeObject {
pub tp_weaklistoffset: Py_ssize_t, pub tp_weaklistoffset: Py_ssize_t,
pub tp_iter: Option<object::getiterfunc>, pub tp_iter: Option<object::getiterfunc>,
pub tp_iternext: Option<object::iternextfunc>, pub tp_iternext: Option<object::iternextfunc>,
pub tp_methods: *mut crate::methodobject::PyMethodDef, pub tp_methods: *mut PyMethodDef,
pub tp_members: *mut crate::structmember::PyMemberDef, pub tp_members: *mut PyMemberDef,
pub tp_getset: *mut crate::descrobject::PyGetSetDef, pub tp_getset: *mut PyGetSetDef,
pub tp_base: *mut PyTypeObject, pub tp_base: *mut PyTypeObject,
pub tp_dict: *mut object::PyObject, pub tp_dict: *mut object::PyObject,
pub tp_descr_get: Option<object::descrgetfunc>, pub tp_descr_get: Option<object::descrgetfunc>,
@ -327,12 +326,10 @@ impl Default for PyHeapTypeObject {
} }
#[inline] #[inline]
pub unsafe fn PyHeapType_GET_MEMBERS( pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef {
etype: *mut PyHeapTypeObject,
) -> *mut crate::structmember::PyMemberDef {
let py_type = object::Py_TYPE(etype as *mut object::PyObject); let py_type = object::Py_TYPE(etype as *mut object::PyObject);
let ptr = etype.offset((*py_type).tp_basicsize); let ptr = etype.offset((*py_type).tp_basicsize);
ptr as *mut crate::structmember::PyMemberDef ptr as *mut PyMemberDef
} }
// skipped _PyType_Name // skipped _PyType_Name

View file

@ -1,37 +1,72 @@
use std::os::raw::c_int; use std::os::raw::{c_char, c_int};
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" { extern "C" {
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_DebugFlag")] #[cfg_attr(PyPy, link_name = "PyPy_DebugFlag")]
pub static mut Py_DebugFlag: c_int; pub static mut Py_DebugFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_VerboseFlag")] #[cfg_attr(PyPy, link_name = "PyPy_VerboseFlag")]
pub static mut Py_VerboseFlag: c_int; pub static mut Py_VerboseFlag: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_QuietFlag: c_int; pub static mut Py_QuietFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_InteractiveFlag")] #[cfg_attr(PyPy, link_name = "PyPy_InteractiveFlag")]
pub static mut Py_InteractiveFlag: c_int; pub static mut Py_InteractiveFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_InspectFlag")] #[cfg_attr(PyPy, link_name = "PyPy_InspectFlag")]
pub static mut Py_InspectFlag: c_int; pub static mut Py_InspectFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_OptimizeFlag")] #[cfg_attr(PyPy, link_name = "PyPy_OptimizeFlag")]
pub static mut Py_OptimizeFlag: c_int; pub static mut Py_OptimizeFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_NoSiteFlag")] #[cfg_attr(PyPy, link_name = "PyPy_NoSiteFlag")]
pub static mut Py_NoSiteFlag: c_int; pub static mut Py_NoSiteFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_BytesWarningFlag")] #[cfg_attr(PyPy, link_name = "PyPy_BytesWarningFlag")]
pub static mut Py_BytesWarningFlag: c_int; pub static mut Py_BytesWarningFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_UseClassExceptionsFlag")] #[cfg_attr(PyPy, link_name = "PyPy_UseClassExceptionsFlag")]
pub static mut Py_UseClassExceptionsFlag: c_int; pub static mut Py_UseClassExceptionsFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_FrozenFlag")] #[cfg_attr(PyPy, link_name = "PyPy_FrozenFlag")]
pub static mut Py_FrozenFlag: c_int; pub static mut Py_FrozenFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_IgnoreEnvironmentFlag")] #[cfg_attr(PyPy, link_name = "PyPy_IgnoreEnvironmentFlag")]
pub static mut Py_IgnoreEnvironmentFlag: c_int; pub static mut Py_IgnoreEnvironmentFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_DontWriteBytecodeFlag")] #[cfg_attr(PyPy, link_name = "PyPy_DontWriteBytecodeFlag")]
pub static mut Py_DontWriteBytecodeFlag: c_int; pub static mut Py_DontWriteBytecodeFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_NoUserSiteDirectory")] #[cfg_attr(PyPy, link_name = "PyPy_NoUserSiteDirectory")]
pub static mut Py_NoUserSiteDirectory: c_int; pub static mut Py_NoUserSiteDirectory: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_UnbufferedStdioFlag: c_int; pub static mut Py_UnbufferedStdioFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")] #[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")]
pub static mut Py_HashRandomizationFlag: c_int; pub static mut Py_HashRandomizationFlag: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_IsolatedFlag: c_int; pub static mut Py_IsolatedFlag: c_int;
#[cfg(windows)] #[cfg(windows)]
#[deprecated(note = "Python 3.12")]
pub static mut Py_LegacyWindowsFSEncodingFlag: c_int;
#[cfg(windows)]
#[deprecated(note = "Python 3.12")]
pub static mut Py_LegacyWindowsStdioFlag: c_int; pub static mut Py_LegacyWindowsStdioFlag: c_int;
} }
extern "C" {
#[cfg(Py_3_11)]
pub fn Py_GETENV(name: *const c_char) -> *mut c_char;
}
#[cfg(not(Py_3_11))]
#[inline(always)]
pub unsafe fn Py_GETENV(name: *const c_char) -> *mut c_char {
#[allow(deprecated)]
if Py_IgnoreEnvironmentFlag != 0 {
std::ptr::null_mut()
} else {
libc::getenv(name)
}
}

View file

@ -1,6 +1,6 @@
use crate::methodobject::PyMethodDef; use crate::methodobject::PyMethodDef;
use crate::object::{PyObject, PyTypeObject}; use crate::object::{PyObject, PyTypeObject};
use crate::structmember::PyMemberDef; use crate::Py_ssize_t;
use std::os::raw::{c_char, c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};
use std::ptr; use std::ptr;
@ -62,3 +62,62 @@ extern "C" {
pub fn PyDictProxy_New(arg1: *mut PyObject) -> *mut PyObject; pub fn PyDictProxy_New(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyWrapper_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject; pub fn PyWrapper_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
} }
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyMemberDef {
pub name: *const c_char,
pub type_code: c_int,
pub offset: Py_ssize_t,
pub flags: c_int,
pub doc: *const c_char,
}
impl Default for PyMemberDef {
fn default() -> PyMemberDef {
PyMemberDef {
name: ptr::null_mut(),
type_code: 0,
offset: 0,
flags: 0,
doc: ptr::null_mut(),
}
}
}
/* Types */
pub const Py_T_SHORT: c_int = 0;
pub const Py_T_INT: c_int = 1;
pub const Py_T_LONG: c_int = 2;
pub const Py_T_FLOAT: c_int = 3;
pub const Py_T_DOUBLE: c_int = 4;
pub const Py_T_STRING: c_int = 5;
#[deprecated(note = "Use Py_T_OBJECT_EX instead")]
pub const _Py_T_OBJECT: c_int = 6;
pub const Py_T_CHAR: c_int = 7;
pub const Py_T_BYTE: c_int = 8;
pub const Py_T_UBYTE: c_int = 9;
pub const Py_T_USHORT: c_int = 10;
pub const Py_T_UINT: c_int = 11;
pub const Py_T_ULONG: c_int = 12;
pub const Py_T_STRING_INPLACE: c_int = 13;
pub const Py_T_BOOL: c_int = 14;
pub const Py_T_OBJECT_EX: c_int = 16;
pub const Py_T_LONGLONG: c_int = 17;
pub const Py_T_ULONGLONG: c_int = 18;
pub const Py_T_PYSSIZET: c_int = 19;
#[deprecated(note = "Value is always none")]
pub const _Py_T_NONE: c_int = 20;
/* Flags */
pub const Py_READONLY: c_int = 1;
#[cfg(Py_3_10)]
pub const Py_AUDIT_READ: c_int = 2; // Added in 3.10, harmless no-op before that
#[deprecated]
pub const _Py_WRITE_RESTRICTED: c_int = 4; // Deprecated, no-op. Do not reuse the value.
pub const Py_RELATIVE_OFFSET: c_int = 8;
extern "C" {
pub fn PyMember_GetOne(addr: *const c_char, l: *mut PyMemberDef) -> *mut PyObject;
pub fn PyMember_SetOne(addr: *mut c_char, l: *mut PyMemberDef, value: *mut PyObject) -> c_int;
}

View file

@ -26,10 +26,13 @@ extern "C" {
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" { extern "C" {
#[deprecated(note = "Python 3.12")]
pub static mut Py_FileSystemDefaultEncoding: *const c_char; pub static mut Py_FileSystemDefaultEncoding: *const c_char;
#[deprecated(note = "Python 3.12")]
pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char; pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char;
#[deprecated(note = "Python 3.12")]
pub static mut Py_HasFileSystemDefaultEncoding: c_int; pub static mut Py_HasFileSystemDefaultEncoding: c_int;
// skipped Python 3.7 / ex-non-limited Py_UTF8Mode // skipped 3.12-deprecated Py_UTF8Mode
} }
// skipped _PyIsSelectable_fd // skipped _PyIsSelectable_fd

View file

@ -407,6 +407,7 @@ mod warnings;
mod weakrefobject; mod weakrefobject;
// Additional headers that are not exported by Python.h // Additional headers that are not exported by Python.h
#[deprecated(note = "Python 3.12")]
pub mod structmember; pub mod structmember;
// "Limited API" definitions matching Python's `include/cpython` directory. // "Limited API" definitions matching Python's `include/cpython` directory.

View file

@ -1,70 +1,33 @@
use crate::object::PyObject; use std::os::raw::c_int;
use crate::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int};
use std::ptr;
#[repr(C)] pub use crate::PyMemberDef;
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyMemberDef {
pub name: *const c_char,
pub type_code: c_int,
pub offset: Py_ssize_t,
pub flags: c_int,
pub doc: *const c_char,
}
impl Default for PyMemberDef { pub use crate::Py_T_BOOL as T_BOOL;
fn default() -> PyMemberDef { pub use crate::Py_T_BYTE as T_BYTE;
PyMemberDef { pub use crate::Py_T_CHAR as T_CHAR;
name: ptr::null_mut(), pub use crate::Py_T_DOUBLE as T_DOUBLE;
type_code: 0, pub use crate::Py_T_FLOAT as T_FLOAT;
offset: 0, pub use crate::Py_T_INT as T_INT;
flags: 0, pub use crate::Py_T_LONG as T_LONG;
doc: ptr::null_mut(), pub use crate::Py_T_LONGLONG as T_LONGLONG;
} pub use crate::Py_T_OBJECT_EX as T_OBJECT_EX;
} pub use crate::Py_T_SHORT as T_SHORT;
} pub use crate::Py_T_STRING as T_STRING;
pub use crate::Py_T_STRING_INPLACE as T_STRING_INPLACE;
pub use crate::Py_T_UBYTE as T_UBYTE;
pub use crate::Py_T_UINT as T_UINT;
pub use crate::Py_T_ULONG as T_ULONG;
pub use crate::Py_T_ULONGLONG as T_ULONGLONG;
pub use crate::Py_T_USHORT as T_USHORT;
#[allow(deprecated)]
pub use crate::_Py_T_OBJECT as T_OBJECT;
/* Types */ pub use crate::Py_T_PYSSIZET as T_PYSSIZET;
pub const T_SHORT: c_int = 0; #[allow(deprecated)]
pub const T_INT: c_int = 1; pub use crate::_Py_T_NONE as T_NONE;
pub const T_LONG: c_int = 2;
pub const T_FLOAT: c_int = 3;
pub const T_DOUBLE: c_int = 4;
pub const T_STRING: c_int = 5;
pub const T_OBJECT: c_int = 6;
/* XXX the ordering here is weird for binary compatibility */
pub const T_CHAR: c_int = 7; /* 1-character string */
pub const T_BYTE: c_int = 8; /* 8-bit signed int */
/* unsigned variants: */
pub const T_UBYTE: c_int = 9;
pub const T_USHORT: c_int = 10;
pub const T_UINT: c_int = 11;
pub const T_ULONG: c_int = 12;
/* Added by Jack: strings contained in the structure */
pub const T_STRING_INPLACE: c_int = 13;
/* Added by Lillo: bools contained in the structure (assumed char) */
pub const T_BOOL: c_int = 14;
pub const T_OBJECT_EX: c_int = 16; /* Like T_OBJECT, but raises AttributeError
when the value is NULL, instead of
converting to None. */
pub const T_LONGLONG: c_int = 17;
pub const T_ULONGLONG: c_int = 18;
pub const T_PYSSIZET: c_int = 19; /* Py_ssize_t */
pub const T_NONE: c_int = 20; /* Value is always None */
/* Flags */ /* Flags */
pub const READONLY: c_int = 1; pub use crate::Py_READONLY as READONLY;
pub const READ_RESTRICTED: c_int = 2; pub const READ_RESTRICTED: c_int = 2;
pub const PY_WRITE_RESTRICTED: c_int = 4; pub const PY_WRITE_RESTRICTED: c_int = 4;
pub const RESTRICTED: c_int = READ_RESTRICTED | PY_WRITE_RESTRICTED; pub const RESTRICTED: c_int = READ_RESTRICTED | PY_WRITE_RESTRICTED;
extern "C" {
pub fn PyMember_GetOne(addr: *const c_char, l: *mut PyMemberDef) -> *mut PyObject;
pub fn PyMember_SetOne(addr: *mut c_char, l: *mut PyMemberDef, value: *mut PyObject) -> c_int;
}