Skip to content
Open
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/5711.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add FFI definitions `PyThreadState_GetInterpreter` on Python 3.9+, `PyThreadState_GetID` on Python 3.9+, `PyThreadState_GetUnchecked` (on Python 3.13+), and `compat::PyThreadState_GetUnchecked`.
1 change: 1 addition & 0 deletions newsfragments/5711.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correct FFI definition for `PyThreadState_GetFrame` to mark it available with abi3 in 3.10+.
1 change: 1 addition & 0 deletions newsfragments/5711.removed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove private FFI definitions `_PyFrameEvalFunction`, `_PyInterpreterState_GetEvalFrameFunc` and `_PyInterpreterState_SetEvalFrameFunc`.
4 changes: 0 additions & 4 deletions pyo3-ffi/src/code.rs

This file was deleted.

11 changes: 11 additions & 0 deletions pyo3-ffi/src/compat/py_3_13.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,14 @@ compat_function!(
result
}
);

#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(Py_3_13);

#[inline]
pub unsafe fn PyThreadState_GetUnchecked(
) -> *mut crate::PyThreadState {
create::_PyThreadState_UncheckedGet()
}
);
9 changes: 2 additions & 7 deletions pyo3-ffi/src/cpython/code.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;

#[cfg(not(GraalPy))]
use crate::PyCodeObject;
#[cfg(not(GraalPy))]
use std::ffi::c_char;
use std::ffi::{c_int, c_void};
Expand Down Expand Up @@ -32,13 +34,6 @@ use std::ptr::addr_of_mut;

// skipped private _PyExecutorArray

opaque_struct!(
#[doc = "A Python code object.\n"]
#[doc = "\n"]
#[doc = "`pyo3-ffi` does not expose the contents of this struct, as it has no stability guarantees."]
pub PyCodeObject
);

/* Masks for co_flags */
pub const CO_OPTIMIZED: c_int = 0x0001;
pub const CO_NEWLOCALS: c_int = 0x0002;
Expand Down
6 changes: 3 additions & 3 deletions pyo3-ffi/src/cpython/frameobject.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#[cfg(not(GraalPy))]
use crate::cpython::code::PyCodeObject;
#[cfg(not(GraalPy))]
use crate::object::*;
#[cfg(not(GraalPy))]
use crate::pystate::PyThreadState;
use crate::PyCodeObject;
use crate::PyFrameObject;
#[cfg(not(GraalPy))]
use crate::PyThreadState;
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
use std::ffi::c_char;
use std::ffi::c_int;
Expand Down
80 changes: 24 additions & 56 deletions pyo3-ffi/src/cpython/pystate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ use crate::PyThreadState;
use crate::{PyFrameObject, PyInterpreterState, PyObject};
use std::ffi::c_int;

// skipped _PyInterpreterState_RequiresIDRef
// skipped _PyInterpreterState_RequireIDRef

// skipped _PyInterpreterState_GetMainModule
// skipped private _PyInterpreterState_RequiresIDRef
// skipped private _PyInterpreterState_RequireIDRef

pub type Py_tracefunc = unsafe extern "C" fn(
obj: *mut PyObject,
Expand All @@ -24,11 +22,11 @@ pub const PyTrace_C_EXCEPTION: c_int = 5;
pub const PyTrace_C_RETURN: c_int = 6;
pub const PyTrace_OPCODE: c_int = 7;

// skipped PyTraceInfo
// skipped CFrame
// skipped private _Py_MAX_SCRIPT_PATH_SIZE
// skipped private _PyRemoteDebuggerSupport

/// Private structure used inline in `PyGenObject`
#[cfg(not(PyPy))]
#[cfg(not(any(PyPy, Py_3_14)))]
#[repr(C)]
#[derive(Clone, Copy)]
pub(crate) struct _PyErr_StackItem {
Expand All @@ -40,20 +38,28 @@ pub(crate) struct _PyErr_StackItem {
previous_item: *mut _PyErr_StackItem,
}

// skipped _PyStackChunk
// skipped _ts (aka PyThreadState)
// skipped private _PyStackChunk

// skipped private _PY_DATA_STACK_CHUNK_SIZE
// skipped private _ts (aka PyThreadState)

extern "C" {
// skipped _PyThreadState_Prealloc
// skipped _PyThreadState_UncheckedGet
// skipped _PyThreadState_GetDict
#[cfg(Py_3_13)]
pub fn PyThreadState_GetUnchecked() -> *mut PyThreadState;

#[cfg(not(Py_3_13))]
pub(crate) fn _PyThreadState_UncheckedGet() -> *mut PyThreadState;

// skipped PyThreadState_EnterTracing
// skipped PyThreadState_LeaveTracing

#[cfg_attr(PyPy, link_name = "PyPyGILState_Check")]
pub fn PyGILState_Check() -> c_int;

// skipped _PyGILState_GetInterpreterStateUnsafe
// skipped _PyThread_CurrentFrames
// skipped _PyThread_CurrentExceptions
// skipped private _PyThread_CurrentFrames

// skipped PyUnstable_ThreadState_SetStackProtection
// skipped PyUnstable_ThreadState_ResetStackProtection

#[cfg(not(PyPy))]
pub fn PyInterpreterState_Main() -> *mut PyInterpreterState;
Expand All @@ -70,44 +76,6 @@ extern "C" {
pub fn PyThreadState_DeleteCurrent();
}

#[cfg(all(Py_3_9, not(any(Py_3_11, PyPy))))]
pub type _PyFrameEvalFunction = extern "C" fn(
*mut crate::PyThreadState,
*mut crate::PyFrameObject,
c_int,
) -> *mut crate::object::PyObject;

#[cfg(all(Py_3_11, not(PyPy)))]
pub type _PyFrameEvalFunction = extern "C" fn(
*mut crate::PyThreadState,
*mut crate::_PyInterpreterFrame,
c_int,
) -> *mut crate::object::PyObject;

#[cfg(all(Py_3_9, not(PyPy)))]
extern "C" {
/// Get the frame evaluation function.
pub fn _PyInterpreterState_GetEvalFrameFunc(
interp: *mut PyInterpreterState,
) -> _PyFrameEvalFunction;

///Set the frame evaluation function.
pub fn _PyInterpreterState_SetEvalFrameFunc(
interp: *mut PyInterpreterState,
eval_frame: _PyFrameEvalFunction,
);
}

// skipped _PyInterpreterState_GetConfig
// skipped _PyInterpreterState_GetConfigCopy
// skipped _PyInterpreterState_SetConfig
// skipped _Py_GetConfig

// skipped _PyCrossInterpreterData
// skipped _PyObject_GetCrossInterpreterData
// skipped _PyCrossInterpreterData_NewObject
// skipped _PyCrossInterpreterData_Release
// skipped _PyObject_CheckCrossInterpreterData
// skipped crossinterpdatafunc
// skipped _PyCrossInterpreterData_RegisterClass
// skipped _PyCrossInterpreterData_Lookup
// skipped private _PyFrameEvalFunction
// skipped private _PyInterpreterState_GetEvalFrameFunc
// skipped private _PyInterpreterState_SetEvalFrameFunc
4 changes: 0 additions & 4 deletions pyo3-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,6 @@ pub use self::boolobject::*;
pub use self::bytearrayobject::*;
pub use self::bytesobject::*;
pub use self::ceval::*;
#[cfg(Py_LIMITED_API)]
pub use self::code::*;
pub use self::codecs::*;
pub use self::compile::*;
pub use self::complexobject::*;
Expand Down Expand Up @@ -455,8 +453,6 @@ mod bytesobject;
// skipped cellobject.h
mod ceval;
// skipped classobject.h
#[cfg(Py_LIMITED_API)]
mod code;
mod codecs;
mod compile;
mod complexobject;
Expand Down
20 changes: 9 additions & 11 deletions pyo3-ffi/src/pystate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::moduleobject::PyModuleDef;
use crate::object::PyObject;
use crate::pytypedefs::{PyInterpreterState, PyThreadState};
use std::ffi::c_int;

#[cfg(all(Py_3_10, not(PyPy), not(Py_LIMITED_API)))]
Expand All @@ -10,9 +11,6 @@ use std::ffi::c_long;

pub const MAX_CO_EXTRA_USERS: c_int = 255;

opaque_struct!(pub PyThreadState);
opaque_struct!(pub PyInterpreterState);

extern "C" {
#[cfg(not(PyPy))]
pub fn PyInterpreterState_New() -> *mut PyInterpreterState;
Expand All @@ -32,7 +30,6 @@ extern "C" {

#[cfg_attr(PyPy, link_name = "PyPyState_AddModule")]
pub fn PyState_AddModule(arg1: *mut PyObject, arg2: *mut PyModuleDef) -> c_int;

#[cfg_attr(PyPy, link_name = "PyPyState_RemoveModule")]
pub fn PyState_RemoveModule(arg1: *mut PyModuleDef) -> c_int;

Expand Down Expand Up @@ -62,15 +59,16 @@ extern "C" {
pub fn PyThreadState_GetDict() -> *mut PyObject;
#[cfg(not(PyPy))]
pub fn PyThreadState_SetAsyncExc(arg1: c_long, arg2: *mut PyObject) -> c_int;
}

// skipped non-limited / 3.9 PyThreadState_GetInterpreter
// skipped non-limited / 3.9 PyThreadState_GetID

extern "C" {
// PyThreadState_GetFrame
#[cfg(all(Py_3_10, not(PyPy), not(Py_LIMITED_API)))]
#[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))]
#[cfg(not(PyPy))]
pub fn PyThreadState_GetInterpreter(arg1: *mut PyThreadState) -> *mut PyInterpreterState;
#[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))]
#[cfg(not(PyPy))]
pub fn PyThreadState_GetFrame(arg1: *mut PyThreadState) -> *mut PyFrameObject;
#[cfg(any(all(Py_3_9, not(Py_LIMITED_API)), Py_3_10))]
#[cfg(not(PyPy))]
pub fn PyThreadState_GetID(arg1: *mut PyThreadState) -> i64;
}

#[repr(C)]
Expand Down
17 changes: 15 additions & 2 deletions pyo3-ffi/src/pytypedefs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
// TODO: Created this file as part of fixing pyframe.rs and cpython/pyframe.rs
// TODO: Finish defining or moving declarations now in Include/pytypedefs.h
// NB: unlike C, we do not need to forward declare structs in Rust.
// So we only define opaque structs for those which do not have public structure.

// PyModuleDef
// PyModuleDef_Slot
// PyMethodDef
// PyGetSetDef
// PyMemberDef

// PyObject
// PyLongObject
// PyTypeObject
opaque_struct!(pub PyCodeObject);
opaque_struct!(pub PyFrameObject);

opaque_struct!(pub PyThreadState);
opaque_struct!(pub PyInterpreterState);
Loading