Merge pull request #1425 from nw0/ffi-5

ffi cleanup: methodobject to moduleobject
This commit is contained in:
David Hewitt 2021-02-14 07:48:01 +00:00 committed by GitHub
commit 28aff42e80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 91 additions and 9 deletions

View file

@ -5,6 +5,17 @@ PyO3 versions, please see the [migration guide](https://pyo3.rs/master/migration
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Add FFI definition `PyCFunction_CheckExact` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)
### Changed
- Deprecate FFI definition `PyCFunction_Call` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)
- Deprecate FFI definitions `PyModule_GetFilename`, `PyMethodDef_INIT`. [#1425](https://github.com/PyO3/pyo3/pull/1425)
### Fixed
- Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)
## [0.13.2] - 2021-02-12
### Packaging
- Lower minimum supported Rust version to 1.41. [#1421](https://github.com/PyO3/pyo3/pull/1421)

View file

@ -136,6 +136,7 @@ impl ModuleDef {
/// # Safety
/// `name` must be a null-terminated string.
pub const unsafe fn new(name: &'static str) -> Self {
#[allow(deprecated)]
let mut init = ffi::PyModuleDef_INIT;
init.m_name = name.as_ptr() as *const _;
ModuleDef(UnsafeCell::new(init))

View file

@ -1,4 +1,6 @@
use crate::ffi::object::{PyObject, PyTypeObject, Py_TYPE};
#[cfg(Py_3_9)]
use crate::ffi::PyObject_TypeCheck;
use std::mem;
use std::os::raw::{c_char, c_int};
@ -8,6 +10,19 @@ extern "C" {
pub static mut PyCFunction_Type: PyTypeObject;
}
#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCFunction_Type) as c_int
}
#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyCFunction_Type)
}
#[cfg(not(Py_3_9))]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCFunction_Type) as c_int
@ -38,11 +53,14 @@ pub type _PyCFunctionFastWithKeywords = unsafe extern "C" fn(
kwnames: *mut PyObject,
) -> *mut PyObject;
// skipped PyCMethod (since 3.9)
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_GetFunction")]
pub fn PyCFunction_GetFunction(f: *mut PyObject) -> Option<PyCFunction>;
pub fn PyCFunction_GetSelf(f: *mut PyObject) -> *mut PyObject;
pub fn PyCFunction_GetFlags(f: *mut PyObject) -> c_int;
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
pub fn PyCFunction_Call(
f: *mut PyObject,
args: *mut PyObject,
@ -59,6 +77,10 @@ pub struct PyMethodDef {
pub ml_doc: *const c_char,
}
/// Helper initial value of [`PyMethodDef`] for a Python class.
///
/// Not present in the Python C API.
#[deprecated(note = "not present in Python headers; to be removed")]
pub const PyMethodDef_INIT: PyMethodDef = PyMethodDef {
ml_name: std::ptr::null(),
ml_meth: None,
@ -73,17 +95,19 @@ impl Default for PyMethodDef {
}
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_New")]
pub fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
pub fn PyCFunction_NewEx(
ml: *mut PyMethodDef,
slf: *mut PyObject,
module: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCFunction_New")]
pub fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject;
}
// skipped non-limited / 3.9 PyCMethod_New
/* Flag passed to newmethodobject */
pub const METH_VARARGS: c_int = 0x0001;
pub const METH_KEYWORDS: c_int = 0x0002;
@ -109,6 +133,10 @@ be specified alone or with METH_KEYWORDS. */
#[cfg(all(Py_3_7, not(Py_LIMITED_API)))]
pub const METH_FASTCALL: c_int = 0x0080;
// skipped METH_STACKLESS
// skipped METH_METHOD
extern "C" {
#[cfg(not(Py_3_9))]
pub fn PyCFunction_ClearFreeList() -> c_int;
}

View file

@ -127,6 +127,10 @@ mod listobject;
mod longobject;
pub(crate) mod marshal;
mod memoryobject;
mod methodobject; // TODO: incomplete
mod modsupport; // TODO: incomplete
mod moduleobject; // TODO: incomplete
// skipped namespaceobject.h
// skipped odictobject.h
// skipped opcode.h
@ -174,8 +178,6 @@ mod unicodeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.
mod rangeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod tupleobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod odictobject; TODO new in 3.5
mod methodobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod moduleobject;
mod setobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod classobject; TODO excluded by PEP-384
mod pycapsule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
@ -191,7 +193,6 @@ mod pystate; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and
#[cfg(Py_LIMITED_API)]
mod pyarena {}
mod modsupport; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
#[cfg(not(Py_LIMITED_API))]
mod pyarena; // TODO: incomplete
mod pythonrun; // TODO some functions need to be moved to pylifecycle

View file

@ -28,12 +28,32 @@ extern "C" {
) -> 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")]
// #[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")]
// #[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 PyModule_AddObjectRef
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObject")]
pub fn PyModule_AddObject(
arg1: *mut PyObject,
@ -49,6 +69,9 @@ extern "C" {
arg2: *const c_char,
arg3: *const c_char,
) -> c_int;
// skipped non-limited / 3.9 PyModule_AddType
// skipped PyModule_AddIntMacro
// skipped PyModule_AddStringMacro
pub fn PyModule_SetDocString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
pub fn PyModule_AddFunctions(arg1: *mut PyObject, arg2: *mut PyMethodDef) -> c_int;
pub fn PyModule_ExecDef(module: *mut PyObject, def: *mut PyModuleDef) -> c_int;
@ -122,3 +145,5 @@ pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject
},
)
}
// skipped non-limited _Py_PackageContext

View file

@ -30,8 +30,12 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyModule_GetName")]
pub fn PyModule_GetName(arg1: *mut PyObject) -> *const c_char;
#[cfg(not(all(windows, PyPy)))]
#[deprecated(note = "Python 3.2")]
pub fn PyModule_GetFilename(arg1: *mut PyObject) -> *const c_char;
pub fn PyModule_GetFilenameObject(arg1: *mut PyObject) -> *mut PyObject;
// skipped non-limited _PyModule_Clear
// skipped non-limited _PyModule_ClearDict
// skipped non-limited _PyModuleSpec_IsInitializing
#[cfg_attr(PyPy, link_name = "PyPyModule_GetDef")]
pub fn PyModule_GetDef(arg1: *mut PyObject) -> *mut PyModuleDef;
#[cfg_attr(PyPy, link_name = "PyPyModule_GetState")]
@ -71,6 +75,8 @@ pub struct PyModuleDef_Slot {
pub const Py_mod_create: c_int = 1;
pub const Py_mod_exec: c_int = 2;
// skipped non-limited _Py_mod_LAST_SLOT
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyModuleDef {
@ -85,6 +91,10 @@ pub struct PyModuleDef {
pub m_free: Option<freefunc>,
}
/// Helper initial value of [`PyModuleDef`] for a Python class.
///
/// Not present in the Python C API.
#[deprecated(note = "not present in Python headers; to be removed")]
pub const PyModuleDef_INIT: PyModuleDef = PyModuleDef {
m_base: PyModuleDef_HEAD_INIT,
m_name: std::ptr::null(),

View file

@ -350,6 +350,7 @@ fn py_class_method_defs<T: PyMethods>() -> (
}
if !defs.is_empty() {
#[allow(deprecated)]
defs.push(ffi::PyMethodDef_INIT);
}

View file

@ -121,7 +121,12 @@ impl PyModule {
/// May fail if the module does not have a `__file__` attribute.
#[cfg(not(all(windows, PyPy)))]
pub fn filename(&self) -> PyResult<&str> {
unsafe { self.str_from_ptr(ffi::PyModule_GetFilename(self.as_ptr())) }
use crate::types::PyString;
unsafe {
self.py()
.from_owned_ptr_or_err::<PyString>(ffi::PyModule_GetFilenameObject(self.as_ptr()))?
.to_str()
}
}
/// Calls a function in the module.