Skip to content

Commit

Permalink
ffi: updates for Python 3.10
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Sep 26, 2021
1 parent da1efcd commit d8f6028
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Packaging

- Support Python 3.10. [#1889](https://github.com/PyO3/pyo3/pull/1889)

### Added

- Add `PyList::get_item_unchecked` and `PyTuple::get_item_unchecked` to get items without bounds checks. [#1733](https://github.com/PyO3/pyo3/pull/1733)
Expand Down
4 changes: 3 additions & 1 deletion src/ffi/abstract_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ extern "C" {

#[cfg_attr(PyPy, link_name = "PyPyIter_Next")]
pub fn PyIter_Next(arg1: *mut PyObject) -> *mut PyObject;
// skipped non-limited / 3.10 PyIter_Send
#[cfg(all(not(PyPy), Py_3_10))]
#[cfg_attr(docsrs, doc(cfg(all(not(PyPy), Py_3_10))))]
pub fn PyIter_Send(iter: *mut PyObject, arg: *mut PyObject, presult: *mut *mut PyObject);

#[cfg_attr(PyPy, link_name = "PyPyNumber_Check")]
pub fn PyNumber_Check(o: *mut PyObject) -> c_int;
Expand Down
10 changes: 10 additions & 0 deletions src/ffi/boolobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ pub unsafe fn Py_True() -> *mut PyObject {
&mut _Py_TrueStruct as *mut PyLongObject as *mut PyObject
}

#[inline]
pub unsafe fn Py_IsTrue(x: *mut PyObject) -> c_int {
Py_Is(x, Py_True())
}

#[inline]
pub unsafe fn Py_IsFalse(x: *mut PyObject) -> c_int {
Py_Is(x, Py_False())
}

// skipped Py_RETURN_TRUE
// skipped Py_RETURN_FALSE

Expand Down
4 changes: 3 additions & 1 deletion src/ffi/codecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::os::raw::{c_char, c_int};

extern "C" {
pub fn PyCodec_Register(search_function: *mut PyObject) -> c_int;
// skipped PyCodec_Unregister
#[cfg(Py_3_10)]
#[cfg(not(PyPy))]
pub fn PyCodec_Unregister(search_function: *mut PyObject) -> c_int;
// skipped non-limited _PyCodec_Lookup from Include/codecs.h
// skipped non-limited _PyCodec_Forget from Include/codecs.h
pub fn PyCodec_KnownEncoding(encoding: *const c_char) -> c_int;
Expand Down
8 changes: 0 additions & 8 deletions src/ffi/cpython/unicodeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,6 @@ extern "C" {
// skipped _PyUnicode_FormatAdvancedWriter

extern "C" {
#[cfg(Py_3_7)]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *const c_char;

#[cfg(not(Py_3_7))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *mut c_char;

// skipped _PyUnicode_AsStringAndSize

#[cfg(Py_3_7)]
Expand Down
8 changes: 7 additions & 1 deletion src/ffi/modsupport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ extern "C" {
// skipped non-limited _PyArg_UnpackKeywords
// skipped non-limited _PyArg_Fini

// skipped PyModule_AddObjectRef
#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn PyModule_AddObjectRef(
arg1: *mut PyObject,
arg2: *const c_char,
arg3: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObject")]
pub fn PyModule_AddObject(
arg1: *mut PyObject,
Expand Down
52 changes: 47 additions & 5 deletions src/ffi/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ pub struct PyVarObject {
// skipped _PyVarObject_CAST
// skipped _PyVarObject_CAST_CONST

#[inline]
pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int {
(x == y).into()
}

// skipped _Py_REFCNT: defined in Py_REFCNT

#[inline]
Expand Down Expand Up @@ -347,6 +352,14 @@ extern "C" {
// Flag bits for printing:
pub const Py_PRINT_RAW: c_int = 1; // No string quotes etc.

#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub const Py_TPFLAGS_DISALLOW_INSTANTIATION: c_ulong = (1 << 7);

#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub const Py_TPFLAGS_IMMUTABLETYPE: c_ulong = (1 << 8);

/// Set if the type object is dynamically allocated
pub const Py_TPFLAGS_HEAPTYPE: c_ulong = 1 << 9;

Expand Down Expand Up @@ -454,10 +467,28 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPy_DecRef")]
pub fn Py_DecRef(o: *mut PyObject);

// skipped Py_NewRef
// skipped Py_XNewRef
// skipped _Py_NewRef
// skipped _Py_XNewRef
#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject;
#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject;
}

// Technically these macros are only available in the C header from 3.10 and up, however their
// implementation works on all supported Python versions so we define these macros on all
// versions for simplicity.

#[inline]
pub unsafe fn _Py_NewRef(obj: *mut PyObject) -> *mut PyObject {
Py_INCREF(obj);
obj
}

#[inline]
pub unsafe fn _Py_XNewRef(obj: *mut PyObject) -> *mut PyObject {
Py_XINCREF(obj);
obj
}

#[cfg_attr(windows, link(name = "pythonXY"))]
Expand All @@ -471,6 +502,11 @@ pub unsafe fn Py_None() -> *mut PyObject {
&mut _Py_NoneStruct
}

#[inline]
pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int {
Py_Is(x, Py_None())
}

// skipped Py_RETURN_NONE

#[cfg_attr(windows, link(name = "pythonXY"))]
Expand All @@ -494,7 +530,13 @@ pub const Py_NE: c_int = 3;
pub const Py_GT: c_int = 4;
pub const Py_GE: c_int = 5;

// skipped non-limited / 3.10 PySendResult
#[cfg(Py_3_10)]
#[repr(C)]
pub enum PySendResult {
PYGEN_RETURN = 0,
PYGEN_ERROR = -1,
PYGEN_NEXT = 1,
}

// skipped Py_RETURN_RICHCOMPARE

Expand Down
8 changes: 8 additions & 0 deletions src/ffi/objimpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ extern "C" {
pub fn _PyObject_NewVar(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyVarObject;

pub fn PyGC_Collect() -> Py_ssize_t;

#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn PyGC_Enable() -> c_int;
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn PyGC_Disable() -> c_int;
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn PyGC_IsEnabled() -> c_int;
}

#[repr(C)]
Expand Down
7 changes: 5 additions & 2 deletions src/ffi/pyerrors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub unsafe fn PyUnicodeDecodeError_Create(
end: Py_ssize_t,
_reason: *const c_char,
) -> *mut PyObject {
return crate::ffi::PyObject_CallFunction(
crate::ffi::PyObject_CallFunction(
PyExc_UnicodeDecodeError,
std::ffi::CStr::from_bytes_with_nul(b"sy#nns\0")
.unwrap()
Expand All @@ -168,7 +168,7 @@ pub unsafe fn PyUnicodeDecodeError_Create(
length,
start,
end,
);
)
}

#[cfg_attr(windows, link(name = "pythonXY"))]
Expand Down Expand Up @@ -374,6 +374,9 @@ extern "C" {
pub fn PyErr_CheckSignals() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_SetInterrupt")]
pub fn PyErr_SetInterrupt();
#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub fn PyErr_SetInterruptEx(signum: c_int);
pub fn PyErr_SyntaxLocation(filename: *const c_char, lineno: c_int);
pub fn PyErr_SyntaxLocationEx(filename: *const c_char, lineno: c_int, col_offset: c_int);
pub fn PyErr_ProgramText(filename: *const c_char, lineno: c_int) -> *mut PyObject;
Expand Down
6 changes: 5 additions & 1 deletion src/ffi/setobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int {
|| PyType_IsSubtype(Py_TYPE(ob), &mut PyFrozenSet_Type) != 0) as c_int
}

// skipped PySet_CheckExact
#[cfg(Py_3_10)]
#[cfg_attr(docsrs, doc(cfg(Py_3_10)))]
pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int {
crate::ffi::Py_IS_TYPE(op, &mut PySet_Type)
}

extern "C" {
#[cfg(PyPy)]
Expand Down
8 changes: 8 additions & 0 deletions src/ffi/unicodeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ extern "C" {
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8String")]
pub fn PyUnicode_AsUTF8String(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(any(Py_3_10, all(Py_3_7, not(Py_LIMITED_API))))]
#[cfg_attr(docsrs, doc(cfg(any(Py_3_10, not(Py_LIMITED_API)))))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *const c_char;
#[cfg(not(any(Py_3_7, Py_LIMITED_API)))]
#[cfg_attr(docsrs, doc(cfg(any(Py_3_10, not(Py_LIMITED_API)))))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *mut c_char;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF32")]
pub fn PyUnicode_DecodeUTF32(
string: *const c_char,
Expand Down
4 changes: 2 additions & 2 deletions src/types/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ impl PyString {
pub fn to_str(&self) -> PyResult<&str> {
let utf8_slice = {
cfg_if::cfg_if! {
if #[cfg(not(Py_LIMITED_API))] {
// PyUnicode_AsUTF8AndSize only available on limited API.
if #[cfg(any(Py_3_10, not(Py_LIMITED_API)))] {
// PyUnicode_AsUTF8AndSize only available on limited API before 3.10.
let mut size: ffi::Py_ssize_t = 0;
let data = unsafe { ffi::PyUnicode_AsUTF8AndSize(self.as_ptr(), &mut size) };
if data.is_null() {
Expand Down

0 comments on commit d8f6028

Please sign in to comment.