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: cleanup pystate #1787

Merged
merged 1 commit into from
Aug 13, 2021
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- Change `PyErr::fetch()` to return `Option<PyErr>`. [#1717](https://github.com/PyO3/pyo3/pull/1717)

### Fixed

- Restrict FFI definitions `PyGILState_Check` and `Py_tracefunc` to the unlimited API. [#1787](https://github.com/PyO3/pyo3/pull/1787)

## [0.14.2] - 2021-08-09

### Added
Expand Down
3 changes: 1 addition & 2 deletions src/ffi/cpython/ceval.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::ffi::object::{freefunc, PyObject};
use crate::ffi::pystate::Py_tracefunc;
use crate::ffi::{freefunc, PyObject, Py_tracefunc};
use std::os::raw::c_int;

extern "C" {
Expand Down
6 changes: 2 additions & 4 deletions src/ffi/cpython/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub(crate) mod abstract_;
// skipped bytearrayobject.h
#[cfg(not(PyPy))]
pub(crate) mod bytesobject;
#[cfg(not(PyPy))]
pub(crate) mod ceval;
pub(crate) mod code;
pub(crate) mod compile;
Expand All @@ -18,13 +19,12 @@ pub(crate) mod object;
pub(crate) mod pydebug;
#[cfg(all(Py_3_8, not(PyPy)))]
pub(crate) mod pylifecycle;

#[cfg(all(Py_3_8, not(PyPy)))]
pub(crate) mod pystate;

pub use self::abstract_::*;
#[cfg(not(PyPy))]
pub use self::bytesobject::*;
#[cfg(not(PyPy))]
pub use self::ceval::*;
pub use self::code::*;
pub use self::compile::*;
Expand All @@ -39,6 +39,4 @@ pub use self::object::*;
pub use self::pydebug::*;
#[cfg(all(Py_3_8, not(PyPy)))]
pub use self::pylifecycle::*;

#[cfg(all(Py_3_8, not(PyPy)))]
pub use self::pystate::*;
57 changes: 54 additions & 3 deletions src/ffi/cpython/pystate.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
use crate::ffi::pystate::{PyInterpreterState, PyThreadState};
#[cfg(not(PyPy))]
use crate::ffi::PyThreadState;
use crate::ffi::{PyFrameObject, PyInterpreterState, PyObject};
use std::os::raw::c_int;

// Py_tracefunc is defined in ffi::pystate
// skipped _PyInterpreterState_RequiresIDRef
// skipped _PyInterpreterState_RequireIDRef

// skipped _PyInterpreterState_GetMainModule

pub type Py_tracefunc = extern "C" fn(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions were in Include/pystate before 3.8. The problem with moving this here now is that the cpython/pystate module is gated behind Py_3_8, so this removes it from 3.6 and 3.7, which is why CI is now failing. (the same thing may be true for other things)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I'd rather have the ffi modules look as much like the Python headers as possible, to minimise confusion. So I'll remove that version gating and tweak things.

obj: *mut PyObject,
frame: *mut PyFrameObject,
what: c_int,
arg: *mut PyObject,
) -> c_int;

pub const PyTrace_CALL: c_int = 0;
pub const PyTrace_EXCEPTION: c_int = 1;
Expand All @@ -12,13 +24,38 @@ 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 _PyErr_StackItem
// skipped _PyStackChunk
// skipped _ts (aka PyThreadState)

extern "C" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cfgs in this entire block don't do anything because the entire module import is already gated with #[cfg(all(Py_3_8, not(PyPy)))] (https://github.com/PyO3/pyo3/blob/main/src/ffi/cpython/mod.rs#L43).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above will remove that gating and make the cfgs here meaningful.

// PyGILState_Check is defined in ffi::pystate
// skipped _PyThreadState_Prealloc
// skipped _PyThreadState_UncheckedGet
// skipped _PyThreadState_GetDict

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

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

#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyInterpreterState_Main() -> *mut PyInterpreterState;
#[cfg_attr(PyPy, link_name = "_PyPyInterpreterState_Head")]
pub fn PyInterpreterState_Head() -> *mut PyInterpreterState;
#[cfg_attr(PyPy, link_name = "_PyPyInterpreterState_Next")]
pub fn PyInterpreterState_Next(interp: *mut PyInterpreterState) -> *mut PyInterpreterState;
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyInterpreterState_ThreadHead(interp: *mut PyInterpreterState) -> *mut PyThreadState;
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyThreadState_Next(tstate: *mut PyThreadState) -> *mut PyThreadState;
// skipped PyThreadState_DeleteCurrent
}

#[cfg(Py_3_9)]
Expand All @@ -44,3 +81,17 @@ extern "C" {
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
57 changes: 38 additions & 19 deletions src/ffi/pystate.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
#[cfg(not(PyPy))]
use crate::ffi::moduleobject::PyModuleDef;
use crate::ffi::object::PyObject;
use crate::ffi::PyFrameObject;
use std::os::raw::{c_int, c_long};
use std::os::raw::c_int;
#[cfg(not(PyPy))]
use std::os::raw::c_long;

pub const MAX_CO_EXTRA_USERS: c_int = 255;

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

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyThreadState {
pub ob_base: PyObject,
pub interp: *mut PyInterpreterState,
}

extern "C" {
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyInterpreterState_New() -> *mut PyInterpreterState;
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyInterpreterState_Clear(arg1: *mut PyInterpreterState);
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyInterpreterState_Delete(arg1: *mut PyInterpreterState);
//fn _PyState_AddModule(arg1: *mut PyObject,
// arg2: *mut PyModuleDef) -> c_int;

#[cfg(all(Py_3_9, not(PyPy)))]
#[cfg_attr(docsrs, doc(all(Py_3_9, not(PyPy))))]
pub fn PyInterpreterState_Get() -> *mut PyInterpreterState;

#[cfg(all(Py_3_8, not(PyPy)))]
#[cfg_attr(docsrs, doc(all(Py_3_8, not(PyPy))))]
pub fn PyInterpreterState_GetDict() -> *mut PyObject;

#[cfg(all(Py_3_7, not(PyPy)))]
#[cfg_attr(docsrs, doc(all(Py_3_7, not(PyPy))))]
pub fn PyInterpreterState_GetID() -> i64;

#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyState_AddModule(arg1: *mut PyObject, arg2: *mut PyModuleDef) -> c_int;
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyState_RemoveModule(arg1: *mut PyModuleDef) -> c_int;

#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyState_FindModule(arg1: *mut PyModuleDef) -> *mut PyObject;

#[cfg_attr(PyPy, link_name = "PyPyThreadState_New")]
pub fn PyThreadState_New(arg1: *mut PyInterpreterState) -> *mut PyThreadState;
//fn _PyThreadState_Prealloc(arg1: *mut PyInterpreterState)
Expand All @@ -39,6 +62,8 @@ extern "C" {
pub fn PyThreadState_Swap(arg1: *mut PyThreadState) -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyThreadState_GetDict")]
pub fn PyThreadState_GetDict() -> *mut PyObject;
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyThreadState_SetAsyncExc(arg1: c_long, arg2: *mut PyObject) -> c_int;
}

Expand All @@ -54,18 +79,12 @@ extern "C" {
pub fn PyGILState_Ensure() -> PyGILState_STATE;
#[cfg_attr(PyPy, link_name = "PyPyGILState_Release")]
pub fn PyGILState_Release(arg1: PyGILState_STATE);
#[cfg(not(PyPy))]
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
pub fn PyGILState_GetThisThreadState() -> *mut PyThreadState;
pub fn PyGILState_Check() -> c_int;
}

#[inline]
pub unsafe fn PyThreadState_GET() -> *mut PyThreadState {
PyThreadState_Get()
}

pub type Py_tracefunc = extern "C" fn(
obj: *mut PyObject,
frame: *mut PyFrameObject,
what: c_int,
arg: *mut PyObject,
) -> c_int;