diff --git a/CHANGELOG.md b/CHANGELOG.md index 704d7fc2..f9f0371b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - `prepare_freethreaded_python` will no longer register an `atexit` handler to call `Py_Finalize`. [#1355](https://github.com/PyO3/pyo3/pull/1355) +- Mark FFI definitions `PyMarshal_WriteObjectToString`, `PyMarshal_ReadObjectFromString` as available in limited API. +- Mark FFI definitions `PyListObject` and those from `funcobject.h` as requiring non-limited API. +- Fix typo in FFI definition `PyFunction_Code` to `PyFunction_GetCode`. ### Fixed - Fix support for using `r#raw_idents` as argument names in pyfunctions. [#1383](https://github.com/PyO3/pyo3/pull/1383) diff --git a/src/ffi/cpython/listobject.rs b/src/ffi/cpython/listobject.rs new file mode 100644 index 00000000..e0f583ad --- /dev/null +++ b/src/ffi/cpython/listobject.rs @@ -0,0 +1,31 @@ +use crate::ffi::object::*; +use crate::ffi::pyport::Py_ssize_t; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PyListObject { + pub ob_base: PyVarObject, + pub ob_item: *mut *mut PyObject, + pub allocated: Py_ssize_t, +} + +// skipped _PyList_Extend +// skipped _PyList_DebugMallocStats +// skipped _PyList_CAST (used inline below) + +/// Macro, trading safety for speed +#[inline] +pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { + *(*(op as *mut PyListObject)).ob_item.offset(i as isize) +} + +/// Macro, *only* to be used to fill in brand new lists +#[inline] +pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { + *(*(op as *mut PyListObject)).ob_item.offset(i as isize) = v; +} + +#[inline] +pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { + Py_SIZE(op) +} diff --git a/src/ffi/cpython/mod.rs b/src/ffi/cpython/mod.rs index f376b939..0150f2a2 100644 --- a/src/ffi/cpython/mod.rs +++ b/src/ffi/cpython/mod.rs @@ -9,6 +9,9 @@ pub mod dictobject; // skipped fileobject.h pub mod frameobject; // skipped import.h +// skipped initconfig.h +// skipped interpreteridobject.h +pub mod listobject; pub use self::abstract_::*; #[cfg(not(PyPy))] @@ -18,3 +21,4 @@ pub use self::code::*; #[cfg(not(PyPy))] pub use self::dictobject::*; pub use self::frameobject::*; +pub use self::listobject::*; diff --git a/src/ffi/funcobject.rs b/src/ffi/funcobject.rs index e57a87a7..f5ec3d87 100644 --- a/src/ffi/funcobject.rs +++ b/src/ffi/funcobject.rs @@ -2,27 +2,27 @@ use std::os::raw::c_int; use crate::ffi::object::{PyObject, PyTypeObject, Py_TYPE}; +// skipped PyFunctionObject + #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { - #[cfg(not(Py_LIMITED_API))] #[cfg_attr(PyPy, link_name = "PyPyFunction_Type")] pub static mut PyFunction_Type: PyTypeObject; } -#[cfg(not(Py_LIMITED_API))] #[inline] pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { (Py_TYPE(op) == &mut PyFunction_Type) as c_int } extern "C" { + pub fn PyFunction_New(code: *mut PyObject, globals: *mut PyObject) -> *mut PyObject; pub fn PyFunction_NewWithQualName( code: *mut PyObject, globals: *mut PyObject, qualname: *mut PyObject, ) -> *mut PyObject; - pub fn PyFunction_New(code: *mut PyObject, globals: *mut PyObject) -> *mut PyObject; - pub fn PyFunction_Code(op: *mut PyObject) -> *mut PyObject; + pub fn PyFunction_GetCode(op: *mut PyObject) -> *mut PyObject; pub fn PyFunction_GetGlobals(op: *mut PyObject) -> *mut PyObject; pub fn PyFunction_GetModule(op: *mut PyObject) -> *mut PyObject; pub fn PyFunction_GetDefaults(op: *mut PyObject) -> *mut PyObject; @@ -34,3 +34,17 @@ extern "C" { pub fn PyFunction_GetAnnotations(op: *mut PyObject) -> *mut PyObject; pub fn PyFunction_SetAnnotations(op: *mut PyObject, annotations: *mut PyObject) -> c_int; } + +// skipped _PyFunction_Vectorcall +// skipped PyFunction_GET_CODE +// skipped PyFunction_GET_GLOBALS +// skipped PyFunction_GET_MODULE +// skipped PyFunction_GET_DEFAULTS +// skipped PyFunction_GET_KW_DEFAULTS +// skipped PyFunction_GET_CLOSURE +// skipped PyFunction_GET_ANNOTATIONS + +// skipped PyClassMethod_Type +// skipped PyStaticMethod_Type +// skipped PyClassMethod_New +// skipped PyStaticMethod_New diff --git a/src/ffi/listobject.rs b/src/ffi/listobject.rs index 2e14e206..cc9ca0de 100644 --- a/src/ffi/listobject.rs +++ b/src/ffi/listobject.rs @@ -2,14 +2,6 @@ use crate::ffi::object::*; use crate::ffi::pyport::Py_ssize_t; use std::os::raw::c_int; -#[repr(C)] -#[derive(Copy, Clone)] -pub struct PyListObject { - pub ob_base: PyVarObject, - pub ob_item: *mut *mut PyObject, - pub allocated: Py_ssize_t, -} - #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { #[cfg_attr(PyPy, link_name = "PyPyList_Type")] @@ -28,26 +20,6 @@ pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int { (Py_TYPE(op) == &mut PyList_Type) as c_int } -/// Macro, trading safety for speed -#[cfg(not(Py_LIMITED_API))] -#[inline] -pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - *(*(op as *mut PyListObject)).ob_item.offset(i as isize) -} - -#[cfg(not(Py_LIMITED_API))] -#[inline] -pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { - Py_SIZE(op) -} - -/// Macro, *only* to be used to fill in brand new lists -#[cfg(not(Py_LIMITED_API))] -#[inline] -pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - *(*(op as *mut PyListObject)).ob_item.offset(i as isize) = v; -} - extern "C" { #[cfg_attr(PyPy, link_name = "PyPyList_New")] pub fn PyList_New(size: Py_ssize_t) -> *mut PyObject; diff --git a/src/ffi/longobject.rs b/src/ffi/longobject.rs index 5d2e862b..09d995d4 100644 --- a/src/ffi/longobject.rs +++ b/src/ffi/longobject.rs @@ -5,11 +5,7 @@ use std::os::raw::{ c_char, c_double, c_int, c_long, c_longlong, c_uchar, c_ulong, c_ulonglong, c_void, }; -/// This is an opaque type in the python c api -#[repr(C)] -pub struct PyLongObject { - _unused: [u8; 0], -} +opaque_struct!(PyLongObject); #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { @@ -50,7 +46,24 @@ extern "C" { pub fn PyLong_AsUnsignedLong(arg1: *mut PyObject) -> c_ulong; #[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongMask")] pub fn PyLong_AsUnsignedLongMask(arg1: *mut PyObject) -> c_ulong; + // skipped non-limited _PyLong_AsInt pub fn PyLong_GetInfo() -> *mut PyObject; + // skipped PyLong_AS_LONG + + // skipped PyLong_FromPid + // skipped PyLong_AsPid + // skipped _Py_PARSE_INTPTR + // skipped _Py_PARSE_UINTPTR + + // skipped non-limited _PyLong_UnsignedShort_Converter + // skipped non-limited _PyLong_UnsignedInt_Converter + // skipped non-limited _PyLong_UnsignedLong_Converter + // skipped non-limited _PyLong_UnsignedLongLong_Converter + // skipped non-limited _PyLong_Size_t_Converter + + // skipped non-limited _PyLong_DigitValue + // skipped non-limited _PyLong_Frexp + #[cfg_attr(PyPy, link_name = "PyPyLong_AsDouble")] pub fn PyLong_AsDouble(arg1: *mut PyObject) -> c_double; #[cfg_attr(PyPy, link_name = "PyPyLong_FromVoidPtr")] @@ -75,15 +88,19 @@ extern "C" { arg2: *mut *mut c_char, arg3: c_int, ) -> *mut PyObject; - pub fn PyOS_strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong; - pub fn PyOS_strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long; } +// skipped non-limited PyLong_FromUnicodeObject +// skipped non-limited _PyLong_FromBytes #[cfg(not(Py_LIMITED_API))] extern "C" { + // skipped non-limited _PyLong_Sign + #[cfg(not(PyPy))] pub fn _PyLong_NumBits(obj: *mut PyObject) -> c_int; + // skipped _PyLong_DivmodNear + #[cfg_attr(PyPy, link_name = "_PyPyLong_FromByteArray")] pub fn _PyLong_FromByteArray( bytes: *const c_uchar, @@ -101,3 +118,17 @@ extern "C" { is_signed: c_int, ) -> c_int; } + +// skipped non-limited _PyLong_Format +// skipped non-limited _PyLong_FormatWriter +// skipped non-limited _PyLong_FormatBytesWriter +// skipped non-limited _PyLong_FormatAdvancedWriter + +extern "C" { + pub fn PyOS_strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong; + pub fn PyOS_strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long; +} + +// skipped non-limited _PyLong_GCD +// skipped non-limited _PyLong_Rshift +// skipped non-limited _PyLong_Lshift diff --git a/src/ffi/marshal.rs b/src/ffi/marshal.rs index 01494ce6..562f6f91 100644 --- a/src/ffi/marshal.rs +++ b/src/ffi/marshal.rs @@ -1,11 +1,19 @@ -use super::PyObject; +use super::{PyObject, Py_ssize_t}; use std::os::raw::{c_char, c_int}; -#[cfg(not(Py_LIMITED_API))] +// skipped Py_MARSHAL_VERSION +// skipped PyMarshal_WriteLongToFile +// skipped PyMarshal_WriteObjectToFile + extern "C" { #[cfg_attr(PyPy, link_name = "PyPyMarshal_WriteObjectToString")] pub fn PyMarshal_WriteObjectToString(object: *mut PyObject, version: c_int) -> *mut PyObject; + // skipped non-limited PyMarshal_ReadLongFromFile + // skipped non-limited PyMarshal_ReadShortFromFile + // skipped non-limited PyMarshal_ReadObjectFromFile + // skipped non-limited PyMarshal_ReadLastObjectFromFile + #[cfg_attr(PyPy, link_name = "PyPyMarshal_ReadObjectFromString")] - pub fn PyMarshal_ReadObjectFromString(data: *const c_char, len: isize) -> *mut PyObject; + pub fn PyMarshal_ReadObjectFromString(data: *const c_char, len: Py_ssize_t) -> *mut PyObject; } diff --git a/src/ffi/memoryobject.rs b/src/ffi/memoryobject.rs index 7351d9fe..8ca27d79 100644 --- a/src/ffi/memoryobject.rs +++ b/src/ffi/memoryobject.rs @@ -2,6 +2,8 @@ use crate::ffi::object::*; use crate::ffi::pyport::Py_ssize_t; use std::os::raw::{c_char, c_int}; +// skipped non-limited _PyManagedBuffer_Type + #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { #[cfg_attr(PyPy, link_name = "PyPyMemoryView_Type")] @@ -13,6 +15,9 @@ pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int { (Py_TYPE(op) == &mut PyMemoryView_Type) as c_int } +// skipped non-limited PyMemoryView_GET_BUFFER +// skipped non-limited PyMemeryView_GET_BASE + extern "C" { #[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromObject")] pub fn PyMemoryView_FromObject(base: *mut PyObject) -> *mut PyObject; @@ -22,9 +27,15 @@ extern "C" { size: Py_ssize_t, flags: c_int, ) -> *mut PyObject; + // skipped non-limited PyMemoryView_FromBuffer pub fn PyMemoryView_GetContiguous( base: *mut PyObject, buffertype: c_int, order: c_char, ) -> *mut PyObject; } + +// skipped remainder of file with comment: +/* The structs are declared here so that macros can work, but they shouldn't +be considered public. Don't access their fields directly, use the macros +and functions instead! */ diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 0d55a607..855b1e2a 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -30,6 +30,7 @@ pub use self::enumobject::*; pub use self::eval::*; pub use self::fileobject::*; pub use self::floatobject::*; +#[cfg(not(Py_LIMITED_API))] pub use self::funcobject::*; #[cfg(not(Py_LIMITED_API))] pub use self::genobject::*; @@ -111,6 +112,8 @@ mod fileobject; // TODO: incomplete mod floatobject; // TODO supports PEP-384 only // skipped empty frameobject.h +#[cfg(not(Py_LIMITED_API))] +pub(crate) mod funcobject; // skipped genericaliasobject.h #[cfg(not(Py_LIMITED_API))] mod genobject; // TODO: incomplete @@ -119,9 +122,11 @@ mod import; // TODO: incomplete // skipped interpreteridobject.h mod intrcheck; // TODO supports PEP-384 only mod iterobject; -mod listobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 - +mod listobject; // skipped longintrepr.h +mod longobject; +pub(crate) mod marshal; +mod memoryobject; // skipped namespaceobject.h // skipped odictobject.h // skipped opcode.h @@ -164,17 +169,14 @@ mod pyhash; mod pymem; mod typeslots; -mod longobject; mod unicodeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 // mod longintrepr; TODO excluded by PEP-384 -mod memoryobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 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 funcobject; TODO excluded by PEP-384 // mod classobject; TODO excluded by PEP-384 mod pycapsule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 mod sliceobject; @@ -209,9 +211,5 @@ mod pystrtod; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and // Additional headers that are not exported by Python.h pub mod structmember; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 -pub(crate) mod marshal; - -pub(crate) mod funcobject; - #[cfg(not(Py_LIMITED_API))] mod cpython;