From 274df72988bd31138e52c28dc3aba5b4ed51aeba Mon Sep 17 00:00:00 2001 From: Jonas Pleyer Date: Thu, 13 Mar 2025 18:48:49 +0100 Subject: [PATCH 01/13] mark unsafe function calls with keyword --- pyo3-ffi/src/abstract_.rs | 22 +-- pyo3-ffi/src/boolobject.rs | 6 +- pyo3-ffi/src/bytearrayobject.rs | 4 +- pyo3-ffi/src/bytesobject.rs | 4 +- pyo3-ffi/src/complexobject.rs | 4 +- pyo3-ffi/src/context.rs | 6 +- pyo3-ffi/src/cpython/abstract_.rs | 98 +++++----- pyo3-ffi/src/cpython/code.rs | 2 +- pyo3-ffi/src/cpython/floatobject.rs | 4 +- pyo3-ffi/src/cpython/frameobject.rs | 2 +- pyo3-ffi/src/cpython/funcobject.rs | 2 +- pyo3-ffi/src/cpython/genobject.rs | 8 +- pyo3-ffi/src/cpython/listobject.rs | 8 +- pyo3-ffi/src/cpython/methodobject.rs | 46 +++-- pyo3-ffi/src/cpython/objimpl.rs | 20 +- pyo3-ffi/src/cpython/pythonrun.rs | 4 +- pyo3-ffi/src/cpython/tupleobject.rs | 6 +- pyo3-ffi/src/cpython/unicodeobject.rs | 104 +++++----- pyo3-ffi/src/datetime.rs | 83 ++++---- pyo3-ffi/src/dictobject.rs | 12 +- pyo3-ffi/src/floatobject.rs | 4 +- pyo3-ffi/src/import.rs | 2 +- pyo3-ffi/src/iterobject.rs | 4 +- pyo3-ffi/src/listobject.rs | 4 +- pyo3-ffi/src/longobject.rs | 4 +- pyo3-ffi/src/memoryobject.rs | 2 +- pyo3-ffi/src/methodobject.rs | 8 +- pyo3-ffi/src/modsupport.rs | 38 ++-- pyo3-ffi/src/moduleobject.rs | 4 +- pyo3-ffi/src/object.rs | 60 +++--- pyo3-ffi/src/objimpl.rs | 2 +- pyo3-ffi/src/pycapsule.rs | 2 +- pyo3-ffi/src/pyerrors.rs | 12 +- pyo3-ffi/src/pystate.rs | 8 +- pyo3-ffi/src/rangeobject.rs | 2 +- pyo3-ffi/src/setobject.rs | 38 ++-- pyo3-ffi/src/sliceobject.rs | 16 +- pyo3-ffi/src/structseq.rs | 4 +- pyo3-ffi/src/traceback.rs | 2 +- pyo3-ffi/src/tupleobject.rs | 4 +- pyo3-ffi/src/unicodeobject.rs | 4 +- pyo3-ffi/src/weakrefobject.rs | 12 +- src/err/err_state.rs | 8 +- src/ffi_ptr_ext.rs | 16 +- src/gil.rs | 32 ++-- src/impl_/extract_argument.rs | 31 +-- src/impl_/pyclass.rs | 262 ++++++++++++++------------ src/impl_/pyclass_init.rs | 19 +- src/impl_/pymethods.rs | 60 +++--- src/impl_/trampoline.rs | 30 +-- src/instance.rs | 61 +++--- src/internal/get_slot.rs | 22 ++- src/marker.rs | 2 +- src/py_result_ext.rs | 2 +- src/pycell/impl_.rs | 26 +-- src/pyclass/create_type_object.rs | 102 +++++----- src/pyclass_init.rs | 32 ++-- src/types/any.rs | 4 +- src/types/bytearray.rs | 8 +- src/types/bytes.rs | 10 +- src/types/capsule.rs | 20 +- src/types/datetime.rs | 4 +- src/types/function.rs | 34 ++-- src/types/list.rs | 8 +- src/types/mappingproxy.rs | 2 +- src/types/string.rs | 40 ++-- src/types/tuple.rs | 10 +- src/types/typeobject.rs | 8 +- src/types/weakref/anyref.rs | 2 +- 69 files changed, 844 insertions(+), 692 deletions(-) diff --git a/pyo3-ffi/src/abstract_.rs b/pyo3-ffi/src/abstract_.rs index a79ec43f271..90105e85921 100644 --- a/pyo3-ffi/src/abstract_.rs +++ b/pyo3-ffi/src/abstract_.rs @@ -10,7 +10,7 @@ use std::os::raw::{c_char, c_int}; not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int { - PyObject_SetAttrString(o, attr_name, std::ptr::null_mut()) + unsafe { PyObject_SetAttrString(o, attr_name, std::ptr::null_mut()) } } #[inline] @@ -19,7 +19,7 @@ pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int { - PyObject_SetAttr(o, attr_name, std::ptr::null_mut()) + unsafe { PyObject_SetAttr(o, attr_name, std::ptr::null_mut()) } } extern "C" { @@ -83,7 +83,7 @@ extern "C" { pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = 1 << (8 * std::mem::size_of::() as size_t - 1); -extern "C" { +unsafe extern "C" { #[cfg_attr(PyPy, link_name = "PyPyObject_Vectorcall")] #[cfg(any(Py_3_12, all(Py_3_11, not(Py_LIMITED_API))))] pub fn PyObject_Vectorcall( @@ -108,7 +108,7 @@ extern "C" { #[inline] pub unsafe fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t { - PyObject_Size(o) + unsafe { PyObject_Size(o) } } extern "C" { @@ -137,7 +137,7 @@ extern "C" { #[cfg(not(any(Py_3_8, PyPy)))] #[inline] pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int { - crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), c_str!("__next__").as_ptr()) + unsafe { crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), c_str!("__next__").as_ptr()) } } extern "C" { @@ -202,7 +202,7 @@ extern "C" { #[inline] pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int { let tp_as_number = (*Py_TYPE(o)).tp_as_number; - (!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int + unsafe { (!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int } } extern "C" { @@ -263,7 +263,7 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t { - PySequence_Size(o) + unsafe { PySequence_Size(o) } } extern "C" { @@ -304,7 +304,7 @@ extern "C" { #[inline] pub unsafe fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int { - PySequence_Contains(o, value) + unsafe { PySequence_Contains(o, value) } } extern "C" { @@ -327,17 +327,17 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t { - PyMapping_Size(o) + unsafe { PyMapping_Size(o) } } #[inline] pub unsafe fn PyMapping_DelItemString(o: *mut PyObject, key: *mut c_char) -> c_int { - PyObject_DelItemString(o, key) + unsafe { PyObject_DelItemString(o, key) } } #[inline] pub unsafe fn PyMapping_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int { - PyObject_DelItem(o, key) + unsafe { PyObject_DelItem(o, key) } } extern "C" { diff --git a/pyo3-ffi/src/boolobject.rs b/pyo3-ffi/src/boolobject.rs index eec9da707a1..71efcd52db3 100644 --- a/pyo3-ffi/src/boolobject.rs +++ b/pyo3-ffi/src/boolobject.rs @@ -6,7 +6,7 @@ use std::ptr::addr_of_mut; #[inline] pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyBool_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyBool_Type)) as c_int } } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -42,12 +42,12 @@ pub unsafe fn Py_True() -> *mut PyObject { #[inline] pub unsafe fn Py_IsTrue(x: *mut PyObject) -> c_int { - Py_Is(x, Py_True()) + unsafe { Py_Is(x, Py_True()) } } #[inline] pub unsafe fn Py_IsFalse(x: *mut PyObject) -> c_int { - Py_Is(x, Py_False()) + unsafe { Py_Is(x, Py_False()) } } // skipped Py_RETURN_TRUE diff --git a/pyo3-ffi/src/bytearrayobject.rs b/pyo3-ffi/src/bytearrayobject.rs index 24a97bcc31b..db543b7fd3d 100644 --- a/pyo3-ffi/src/bytearrayobject.rs +++ b/pyo3-ffi/src/bytearrayobject.rs @@ -29,12 +29,12 @@ extern "C" { #[inline] pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyByteArray_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyByteArray_Type)) } } #[inline] pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyByteArray_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyByteArray_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/bytesobject.rs b/pyo3-ffi/src/bytesobject.rs index 0fd327b6fca..05709e828fa 100644 --- a/pyo3-ffi/src/bytesobject.rs +++ b/pyo3-ffi/src/bytesobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) } } #[inline] pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyBytes_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyBytes_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/complexobject.rs b/pyo3-ffi/src/complexobject.rs index 283bacf6e84..33f7c9b072d 100644 --- a/pyo3-ffi/src/complexobject.rs +++ b/pyo3-ffi/src/complexobject.rs @@ -10,12 +10,12 @@ extern "C" { #[inline] pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyComplex_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyComplex_Type)) } } #[inline] pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int { - Py_IS_TYPE(op, addr_of_mut!(PyComplex_Type)) + unsafe { Py_IS_TYPE(op, addr_of_mut!(PyComplex_Type)) } } extern "C" { diff --git a/pyo3-ffi/src/context.rs b/pyo3-ffi/src/context.rs index 210d6e21f04..265a410cedc 100644 --- a/pyo3-ffi/src/context.rs +++ b/pyo3-ffi/src/context.rs @@ -13,17 +13,17 @@ extern "C" { #[inline] pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyContext_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyContext_Type)) as c_int } } #[inline] pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyContextVar_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyContextVar_Type)) as c_int } } #[inline] pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyContextToken_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyContextToken_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/cpython/abstract_.rs b/pyo3-ffi/src/cpython/abstract_.rs index 6ada1a754ef..2d0ff9cfc72 100644 --- a/pyo3-ffi/src/cpython/abstract_.rs +++ b/pyo3-ffi/src/cpython/abstract_.rs @@ -55,16 +55,18 @@ pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t { #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] #[inline(always)] pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option { - assert!(!callable.is_null()); - let tp = crate::Py_TYPE(callable); - if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 { - return None; + unsafe { + assert!(!callable.is_null()); + let tp = crate::Py_TYPE(callable); + if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 { + return None; + } + assert!(PyCallable_Check(callable) > 0); + let offset = (*tp).tp_vectorcall_offset; + assert!(offset > 0); + let ptr = callable.cast::().offset(offset).cast(); + *ptr } - assert!(PyCallable_Check(callable) > 0); - let offset = (*tp).tp_vectorcall_offset; - assert!(offset > 0); - let ptr = callable.cast::().offset(offset).cast(); - *ptr } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] @@ -76,17 +78,19 @@ pub unsafe fn _PyObject_VectorcallTstate( nargsf: size_t, kwnames: *mut PyObject, ) -> *mut PyObject { - assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0); - assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0); - - match PyVectorcall_Function(callable) { - None => { - let nargs = PyVectorcall_NARGS(nargsf); - _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames) - } - Some(func) => { - let res = func(callable, args, nargsf, kwnames); - _Py_CheckFunctionResult(tstate, callable, res, std::ptr::null_mut()) + unsafe { + assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0); + assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0); + + match PyVectorcall_Function(callable) { + None => { + let nargs = PyVectorcall_NARGS(nargsf); + _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames) + } + Some(func) => { + let res = func(callable, args, nargsf, kwnames); + _Py_CheckFunctionResult(tstate, callable, res, std::ptr::null_mut()) + } } } } @@ -135,7 +139,7 @@ pub unsafe fn _PyObject_FastCallTstate( args: *const *mut PyObject, nargs: Py_ssize_t, ) -> *mut PyObject { - _PyObject_VectorcallTstate(tstate, func, args, nargs as size_t, std::ptr::null_mut()) + unsafe { _PyObject_VectorcallTstate(tstate, func, args, nargs as size_t, std::ptr::null_mut()) } } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] @@ -145,19 +149,21 @@ pub unsafe fn _PyObject_FastCall( args: *const *mut PyObject, nargs: Py_ssize_t, ) -> *mut PyObject { - _PyObject_FastCallTstate(PyThreadState_GET(), func, args, nargs) + unsafe { _PyObject_FastCallTstate(PyThreadState_GET(), func, args, nargs) } } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] #[inline(always)] pub unsafe fn _PyObject_CallNoArg(func: *mut PyObject) -> *mut PyObject { - _PyObject_VectorcallTstate( - PyThreadState_GET(), - func, - std::ptr::null_mut(), - 0, - std::ptr::null_mut(), - ) + unsafe { + _PyObject_VectorcallTstate( + PyThreadState_GET(), + func, + std::ptr::null_mut(), + 0, + std::ptr::null_mut(), + ) + } } extern "C" { @@ -171,10 +177,10 @@ extern "C" { pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { assert!(!arg.is_null()); let args_array = [std::ptr::null_mut(), arg]; - let args = args_array.as_ptr().offset(1); // For PY_VECTORCALL_ARGUMENTS_OFFSET - let tstate = PyThreadState_GET(); + let args = unsafe { args_array.as_ptr().offset(1) }; // For PY_VECTORCALL_ARGUMENTS_OFFSET + let tstate = unsafe { PyThreadState_GET() }; let nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; - _PyObject_VectorcallTstate(tstate, func, args, nargsf, std::ptr::null_mut()) + unsafe { _PyObject_VectorcallTstate(tstate, func, args, nargsf, std::ptr::null_mut()) } } #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] @@ -183,12 +189,14 @@ pub unsafe fn PyObject_CallMethodNoArgs( self_: *mut PyObject, name: *mut PyObject, ) -> *mut PyObject { - crate::PyObject_VectorcallMethod( - name, - &self_, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, - std::ptr::null_mut(), - ) + unsafe { + crate::PyObject_VectorcallMethod( + name, + &self_, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, + std::ptr::null_mut(), + ) + } } #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] @@ -200,12 +208,14 @@ pub unsafe fn PyObject_CallMethodOneArg( ) -> *mut PyObject { let args = [self_, arg]; assert!(!arg.is_null()); - crate::PyObject_VectorcallMethod( - name, - args.as_ptr(), - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, - std::ptr::null_mut(), - ) + unsafe { + crate::PyObject_VectorcallMethod( + name, + args.as_ptr(), + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + std::ptr::null_mut(), + ) + } } // skipped _PyObject_VectorcallMethodId diff --git a/pyo3-ffi/src/cpython/code.rs b/pyo3-ffi/src/cpython/code.rs index 230096ca378..81ecf0fd5de 100644 --- a/pyo3-ffi/src/cpython/code.rs +++ b/pyo3-ffi/src/cpython/code.rs @@ -244,7 +244,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int } } #[inline] diff --git a/pyo3-ffi/src/cpython/floatobject.rs b/pyo3-ffi/src/cpython/floatobject.rs index e7caa441c5d..6d5ac33d1fc 100644 --- a/pyo3-ffi/src/cpython/floatobject.rs +++ b/pyo3-ffi/src/cpython/floatobject.rs @@ -11,14 +11,14 @@ pub struct PyFloatObject { #[inline] pub unsafe fn _PyFloat_CAST(op: *mut PyObject) -> *mut PyFloatObject { - debug_assert_eq!(PyFloat_Check(op), 1); + debug_assert_eq!(unsafe { PyFloat_Check(op) }, 1); op.cast() } #[inline] pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double { #[cfg(not(GraalPy))] - return (*_PyFloat_CAST(op)).ob_fval; + return unsafe { (*_PyFloat_CAST(op)).ob_fval }; #[cfg(GraalPy)] return PyFloat_AsDouble(op); } diff --git a/pyo3-ffi/src/cpython/frameobject.rs b/pyo3-ffi/src/cpython/frameobject.rs index e9b9c183f37..c2e273f0769 100644 --- a/pyo3-ffi/src/cpython/frameobject.rs +++ b/pyo3-ffi/src/cpython/frameobject.rs @@ -66,7 +66,7 @@ extern "C" { #[inline] pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyFrame_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyFrame_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/cpython/funcobject.rs b/pyo3-ffi/src/cpython/funcobject.rs index 25de30d57f7..bccc07474d9 100644 --- a/pyo3-ffi/src/cpython/funcobject.rs +++ b/pyo3-ffi/src/cpython/funcobject.rs @@ -70,7 +70,7 @@ extern "C" { #[cfg(not(all(PyPy, not(Py_3_8))))] #[inline] pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { - (crate::Py_TYPE(op) == addr_of_mut!(PyFunction_Type)) as c_int + unsafe { (crate::Py_TYPE(op) == addr_of_mut!(PyFunction_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/cpython/genobject.rs b/pyo3-ffi/src/cpython/genobject.rs index c9d419e3782..4170953debe 100644 --- a/pyo3-ffi/src/cpython/genobject.rs +++ b/pyo3-ffi/src/cpython/genobject.rs @@ -42,12 +42,12 @@ extern "C" { #[inline] pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyGen_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyGen_Type)) } } #[inline] pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyGen_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyGen_Type)) as c_int } } extern "C" { @@ -72,7 +72,7 @@ extern "C" { #[inline] pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyCoro_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyCoro_Type)) } } // skipped _PyCoro_GetAwaitableIter @@ -92,7 +92,7 @@ extern "C" { #[inline] pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyAsyncGen_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyAsyncGen_Type)) } } // skipped _PyAsyncGenValueWrapperNew diff --git a/pyo3-ffi/src/cpython/listobject.rs b/pyo3-ffi/src/cpython/listobject.rs index 694e6bc4290..803fb9c835e 100644 --- a/pyo3-ffi/src/cpython/listobject.rs +++ b/pyo3-ffi/src/cpython/listobject.rs @@ -23,18 +23,20 @@ pub struct PyListObject { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - *(*(op as *mut PyListObject)).ob_item.offset(i) + unsafe { *(*(op as *mut PyListObject)).ob_item.offset(i) } } /// Macro, *only* to be used to fill in brand new lists #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - *(*(op as *mut PyListObject)).ob_item.offset(i) = v; + unsafe { + *(*(op as *mut PyListObject)).ob_item.offset(i) = v; + } } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { - Py_SIZE(op) + unsafe { Py_SIZE(op) } } diff --git a/pyo3-ffi/src/cpython/methodobject.rs b/pyo3-ffi/src/cpython/methodobject.rs index 97ad9ce35f0..5d4fd0ec352 100644 --- a/pyo3-ffi/src/cpython/methodobject.rs +++ b/pyo3-ffi/src/cpython/methodobject.rs @@ -17,55 +17,61 @@ extern "C" { #[inline] pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyCMethod_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyCMethod_Type)) as c_int } } #[inline] pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyCMethod_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyCMethod_Type)) } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer { - debug_assert_eq!(PyCMethod_Check(func), 1); + unsafe { + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - (*(*func).m_ml).ml_meth + let func = func.cast::(); + (*(*func).m_ml).ml_meth + } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject { - debug_assert_eq!(PyCMethod_Check(func), 1); + unsafe { + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - if (*(*func).m_ml).ml_flags & METH_STATIC != 0 { - std::ptr::null_mut() - } else { - (*func).m_self + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_STATIC != 0 { + std::ptr::null_mut() + } else { + (*func).m_self + } } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int { - debug_assert_eq!(PyCMethod_Check(func), 1); + debug_assert_eq!(unsafe { PyCMethod_Check(func) }, 1); let func = func.cast::(); - (*(*func).m_ml).ml_flags + unsafe { (*(*func).m_ml).ml_flags } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject { - debug_assert_eq!(PyCMethod_Check(func), 1); + unsafe { + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - if (*(*func).m_ml).ml_flags & METH_METHOD != 0 { - let func = func.cast::(); - (*func).mm_class - } else { - std::ptr::null_mut() + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_METHOD != 0 { + let func = func.cast::(); + (*func).mm_class + } else { + std::ptr::null_mut() + } } } diff --git a/pyo3-ffi/src/cpython/objimpl.rs b/pyo3-ffi/src/cpython/objimpl.rs index 14f7121a202..7044c7c2ea0 100644 --- a/pyo3-ffi/src/cpython/objimpl.rs +++ b/pyo3-ffi/src/cpython/objimpl.rs @@ -45,11 +45,13 @@ extern "C" { #[inline] #[cfg(not(Py_3_9))] pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int { - (crate::PyType_IS_GC(Py_TYPE(o)) != 0 - && match (*Py_TYPE(o)).tp_is_gc { - Some(tp_is_gc) => tp_is_gc(o) != 0, - None => true, - }) as c_int + unsafe { + (crate::PyType_IS_GC(Py_TYPE(o)) != 0 + && match (*Py_TYPE(o)).tp_is_gc { + Some(tp_is_gc) => tp_is_gc(o) != 0, + None => true, + }) as c_int + } } #[cfg(not(Py_3_11))] @@ -60,13 +62,15 @@ extern "C" { #[inline] pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int { - ((*t).tp_weaklistoffset > 0) as c_int + unsafe { ((*t).tp_weaklistoffset > 0) as c_int } } #[inline] pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject { - let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset; - o.offset(weaklistoffset) as *mut *mut PyObject + unsafe { + let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset; + o.offset(weaklistoffset) as *mut *mut PyObject + } } // skipped PyUnstable_Object_GC_NewWithExtraData diff --git a/pyo3-ffi/src/cpython/pythonrun.rs b/pyo3-ffi/src/cpython/pythonrun.rs index fe78f55ca07..9edeaceef6a 100644 --- a/pyo3-ffi/src/cpython/pythonrun.rs +++ b/pyo3-ffi/src/cpython/pythonrun.rs @@ -137,7 +137,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { - Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1) + unsafe { Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1) } } #[inline] @@ -148,7 +148,7 @@ pub unsafe fn Py_CompileStringFlags( s: c_int, f: *mut PyCompilerFlags, ) -> *mut PyObject { - Py_CompileStringExFlags(string, p, s, f, -1) + unsafe { Py_CompileStringExFlags(string, p, s, f, -1) } } // skipped _Py_SourceAsString diff --git a/pyo3-ffi/src/cpython/tupleobject.rs b/pyo3-ffi/src/cpython/tupleobject.rs index 9616d4372cc..ef2df625ece 100644 --- a/pyo3-ffi/src/cpython/tupleobject.rs +++ b/pyo3-ffi/src/cpython/tupleobject.rs @@ -17,20 +17,20 @@ pub struct PyTupleObject { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { - Py_SIZE(op) + unsafe { Py_SIZE(op) } } #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - *(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i) + unsafe { *(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i) } } /// Macro, *only* to be used to fill in brand new tuples #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - *(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v; + unsafe { *(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v }; } // skipped _PyTuple_DebugMallocStats diff --git a/pyo3-ffi/src/cpython/unicodeobject.rs b/pyo3-ffi/src/cpython/unicodeobject.rs index 3527a5aeadb..568400f7bc4 100644 --- a/pyo3-ffi/src/cpython/unicodeobject.rs +++ b/pyo3-ffi/src/cpython/unicodeobject.rs @@ -166,51 +166,57 @@ struct PyASCIIObjectState { impl PyASCIIObjectState { #[inline] unsafe fn interned(&self) -> c_uint { - std::mem::transmute( - self.bitfield - .get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32, - ) + unsafe { + std::mem::transmute( + self.bitfield + .get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32, + ) + } } #[inline] unsafe fn set_interned(&mut self, val: c_uint) { - let val: u32 = std::mem::transmute(val); + let val: u32 = unsafe { std::mem::transmute(val) }; self.bitfield .set(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH, val as u64) } #[inline] unsafe fn kind(&self) -> c_uint { - std::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32) + unsafe { std::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32) } } #[inline] unsafe fn set_kind(&mut self, val: c_uint) { - let val: u32 = std::mem::transmute(val); + let val: u32 = unsafe { std::mem::transmute(val) }; self.bitfield .set(STATE_KIND_INDEX, STATE_KIND_WIDTH, val as u64) } #[inline] unsafe fn compact(&self) -> c_uint { - std::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32) + unsafe { + std::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32) + } } #[inline] unsafe fn set_compact(&mut self, val: c_uint) { - let val: u32 = std::mem::transmute(val); + let val: u32 = unsafe { std::mem::transmute(val) }; self.bitfield .set(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH, val as u64) } #[inline] unsafe fn ascii(&self) -> c_uint { - std::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32) + unsafe { + std::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32) + } } #[inline] unsafe fn set_ascii(&mut self, val: c_uint) { - let val: u32 = std::mem::transmute(val); + let val: u32 = unsafe { std::mem::transmute(val) }; self.bitfield .set(STATE_ASCII_INDEX, STATE_ASCII_WIDTH, val as u64) } @@ -279,7 +285,7 @@ impl PyASCIIObject { /// [`SSTATE_INTERNED_IMMORTAL`], or [`SSTATE_INTERNED_IMMORTAL_STATIC`]. #[inline] pub unsafe fn interned(&self) -> c_uint { - PyASCIIObjectState::from(self.state).interned() + unsafe { PyASCIIObjectState::from(self.state).interned() } } #[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12 @@ -291,7 +297,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_interned(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - state.set_interned(val); + unsafe { state.set_interned(val) }; self.state = u32::from(state); } @@ -302,7 +308,7 @@ impl PyASCIIObject { /// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`]. #[inline] pub unsafe fn kind(&self) -> c_uint { - PyASCIIObjectState::from(self.state).kind() + unsafe { PyASCIIObjectState::from(self.state).kind() } } /// Set the `kind` field of the [`PyASCIIObject`] state bitfield. @@ -313,7 +319,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_kind(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - state.set_kind(val); + unsafe { state.set_kind(val) }; self.state = u32::from(state); } @@ -322,7 +328,7 @@ impl PyASCIIObject { /// Returns either `0` or `1`. #[inline] pub unsafe fn compact(&self) -> c_uint { - PyASCIIObjectState::from(self.state).compact() + unsafe { PyASCIIObjectState::from(self.state).compact() } } /// Set the `compact` flag of the [`PyASCIIObject`] state bitfield. @@ -331,7 +337,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_compact(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - state.set_compact(val); + unsafe { state.set_compact(val) }; self.state = u32::from(state); } @@ -340,7 +346,7 @@ impl PyASCIIObject { /// Returns either `0` or `1`. #[inline] pub unsafe fn ascii(&self) -> c_uint { - PyASCIIObjectState::from(self.state).ascii() + unsafe { PyASCIIObjectState::from(self.state).ascii() } } /// Set the `ascii` flag of the [`PyASCIIObject`] state bitfield. @@ -349,7 +355,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_ascii(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - state.set_ascii(val); + unsafe { state.set_ascii(val) }; self.state = u32::from(state); } @@ -416,23 +422,27 @@ pub const SSTATE_INTERNED_IMMORTAL_STATIC: c_uint = 3; #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint { - debug_assert!(crate::PyUnicode_Check(op) != 0); - #[cfg(not(Py_3_12))] - debug_assert!(PyUnicode_IS_READY(op) != 0); + unsafe { + debug_assert!(crate::PyUnicode_Check(op) != 0); + #[cfg(not(Py_3_12))] + debug_assert!(PyUnicode_IS_READY(op) != 0); - (*(op as *mut PyASCIIObject)).ascii() + (*(op as *mut PyASCIIObject)).ascii() + } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_COMPACT(op: *mut PyObject) -> c_uint { - (*(op as *mut PyASCIIObject)).compact() + unsafe { (*(op as *mut PyASCIIObject)).compact() } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_COMPACT_ASCII(op: *mut PyObject) -> c_uint { - ((*(op as *mut PyASCIIObject)).ascii() != 0 && PyUnicode_IS_COMPACT(op) != 0).into() + (unsafe { (*(op as *mut PyASCIIObject)).ascii() != 0 } + && unsafe { PyUnicode_IS_COMPACT(op) != 0 }) + .into() } #[cfg(not(Py_3_12))] @@ -446,58 +456,64 @@ pub const PyUnicode_4BYTE_KIND: c_uint = 4; #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_1BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS1 { - PyUnicode_DATA(op) as *mut Py_UCS1 + unsafe { PyUnicode_DATA(op) as *mut Py_UCS1 } } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_2BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS2 { - PyUnicode_DATA(op) as *mut Py_UCS2 + unsafe { PyUnicode_DATA(op) as *mut Py_UCS2 } } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_4BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS4 { - PyUnicode_DATA(op) as *mut Py_UCS4 + unsafe { PyUnicode_DATA(op) as *mut Py_UCS4 } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint { - debug_assert!(crate::PyUnicode_Check(op) != 0); + debug_assert!(unsafe { crate::PyUnicode_Check(op) } != 0); #[cfg(not(Py_3_12))] - debug_assert!(PyUnicode_IS_READY(op) != 0); + debug_assert!(unsafe { PyUnicode_IS_READY(op) } != 0); - (*(op as *mut PyASCIIObject)).kind() + unsafe { (*(op as *mut PyASCIIObject)).kind() } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn _PyUnicode_COMPACT_DATA(op: *mut PyObject) -> *mut c_void { - if PyUnicode_IS_ASCII(op) != 0 { - (op as *mut PyASCIIObject).offset(1) as *mut c_void - } else { - (op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void + unsafe { + if PyUnicode_IS_ASCII(op) != 0 { + (op as *mut PyASCIIObject).offset(1) as *mut c_void + } else { + (op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void + } } } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn _PyUnicode_NONCOMPACT_DATA(op: *mut PyObject) -> *mut c_void { - debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null()); + unsafe { + debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null()); - (*(op as *mut PyUnicodeObject)).data.any + (*(op as *mut PyUnicodeObject)).data.any + } } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { - debug_assert!(crate::PyUnicode_Check(op) != 0); + unsafe { + debug_assert!(crate::PyUnicode_Check(op) != 0); - if PyUnicode_IS_COMPACT(op) != 0 { - _PyUnicode_COMPACT_DATA(op) - } else { - _PyUnicode_NONCOMPACT_DATA(op) + if PyUnicode_IS_COMPACT(op) != 0 { + _PyUnicode_COMPACT_DATA(op) + } else { + _PyUnicode_NONCOMPACT_DATA(op) + } } } @@ -508,11 +524,11 @@ pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t { - debug_assert!(crate::PyUnicode_Check(op) != 0); + debug_assert!(unsafe { crate::PyUnicode_Check(op) } != 0); #[cfg(not(Py_3_12))] debug_assert!(PyUnicode_IS_READY(op) != 0); - (*(op as *mut PyASCIIObject)).length + unsafe { (*(op as *mut PyASCIIObject)).length } } #[cfg(any(Py_3_12, GraalPy))] diff --git a/pyo3-ffi/src/datetime.rs b/pyo3-ffi/src/datetime.rs index 7f2d7958364..f70ea93607a 100644 --- a/pyo3-ffi/src/datetime.rs +++ b/pyo3-ffi/src/datetime.rs @@ -118,7 +118,7 @@ pub struct PyDateTime_DateTime { /// Returns a signed integer greater than 0. pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { // This should work for Date or DateTime - let data = (*(o as *mut PyDateTime_Date)).data; + let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; (c_int::from(data[0]) << 8) | c_int::from(data[1]) } @@ -127,7 +127,7 @@ pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { /// Retrieve the month component of a `PyDateTime_Date` or `PyDateTime_DateTime`. /// Returns a signed integer in the range `[1, 12]`. pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { - let data = (*(o as *mut PyDateTime_Date)).data; + let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; c_int::from(data[2]) } @@ -136,7 +136,7 @@ pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { /// Retrieve the day component of a `PyDateTime_Date` or `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[1, 31]`. pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int { - let data = (*(o as *mut PyDateTime_Date)).data; + let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; c_int::from(data[3]) } @@ -181,10 +181,10 @@ macro_rules! _PyDateTime_GET_FOLD { #[cfg(not(any(PyPy, GraalPy)))] macro_rules! _PyDateTime_GET_TZINFO { ($o: expr) => { - if (*$o).hastzinfo != 0 { - (*$o).tzinfo + if unsafe { (*$o).hastzinfo } != 0 { + unsafe { (*$o).tzinfo } } else { - $crate::Py_None() + unsafe { $crate::Py_None() } } }; } @@ -195,7 +195,7 @@ macro_rules! _PyDateTime_GET_TZINFO { /// Retrieve the hour component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 23]` pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { - _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) + unsafe { _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } } #[inline] @@ -203,7 +203,7 @@ pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { /// Retrieve the minute component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { - _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) + unsafe { _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } } #[inline] @@ -211,7 +211,7 @@ pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { /// Retrieve the second component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { - _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) + unsafe { _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } } #[inline] @@ -219,7 +219,9 @@ pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { /// Retrieve the microsecond component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 999999]` pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { - _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) + unsafe { + _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) + } } #[inline] @@ -227,7 +229,7 @@ pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { /// Retrieve the fold component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 1]` pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar { - _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) + unsafe { _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) } } #[inline] @@ -245,7 +247,7 @@ pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { /// Retrieve the hour component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 23]` pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { - _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0) + unsafe { _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0) } } #[inline] @@ -253,7 +255,7 @@ pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { /// Retrieve the minute component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { - _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0) + unsafe { _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0) } } #[inline] @@ -261,7 +263,7 @@ pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { /// Retrieve the second component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { - _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0) + unsafe { _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0) } } #[inline] @@ -269,7 +271,7 @@ pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { /// Retrieve the microsecond component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 999999]` pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { - _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) + unsafe { _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) } } #[cfg(not(any(PyPy, GraalPy)))] @@ -277,7 +279,7 @@ pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { /// Retrieve the fold component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 1]` pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar { - _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) + unsafe { _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) } } #[inline] @@ -293,7 +295,7 @@ pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { #[cfg(not(any(PyPy, GraalPy)))] macro_rules! _access_field { ($obj:expr, $type: ident, $field:ident) => { - (*($obj as *mut $type)).$field + unsafe { (*($obj as *mut $type)).$field } }; } @@ -595,7 +597,7 @@ pub const PyDateTime_CAPSULE_NAME: &CStr = c_str!("datetime.datetime_CAPI"); /// `PyDateTime_IMPORT` is called #[inline] pub unsafe fn PyDateTimeAPI() -> *mut PyDateTime_CAPI { - *PyDateTimeAPI_impl.ptr.get() + unsafe { *PyDateTimeAPI_impl.ptr.get() } } /// Populates the `PyDateTimeAPI` object @@ -607,8 +609,9 @@ pub unsafe fn PyDateTime_IMPORT() { let py_datetime_c_api = PyDateTime_Import(); #[cfg(not(PyPy))] - let py_datetime_c_api = - PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI; + let py_datetime_c_api = unsafe { + PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI + }; if py_datetime_c_api.is_null() { return; @@ -617,7 +620,7 @@ pub unsafe fn PyDateTime_IMPORT() { // Protect against race conditions when the datetime API is concurrently // initialized in multiple threads. UnsafeCell.get() cannot panic so this // won't panic either. - PyDateTimeAPI_impl.once.call_once(|| { + PyDateTimeAPI_impl.once.call_once(|| unsafe { *PyDateTimeAPI_impl.ptr.get() = py_datetime_c_api; }); } @@ -625,7 +628,7 @@ pub unsafe fn PyDateTime_IMPORT() { #[inline] pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject { - (*PyDateTimeAPI()).TimeZone_UTC + unsafe { (*PyDateTimeAPI()).TimeZone_UTC } } /// Type Check macros @@ -636,61 +639,61 @@ pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject { #[inline] /// Check if `op` is a `PyDateTimeAPI.DateType` or subtype. pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int + unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int } } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`. pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == (*PyDateTimeAPI()).DateType) as c_int + unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DateType) as c_int } } #[inline] /// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype. pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int + unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int } } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`. pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == (*PyDateTimeAPI()).DateTimeType) as c_int + unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DateTimeType) as c_int } } #[inline] /// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype. pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int + unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int } } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`. pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == (*PyDateTimeAPI()).TimeType) as c_int + unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).TimeType) as c_int } } #[inline] /// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype. pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int + unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int } } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`. pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == (*PyDateTimeAPI()).DeltaType) as c_int + unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DeltaType) as c_int } } #[inline] /// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype. pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int + unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int } } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`. pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == (*PyDateTimeAPI()).TZInfoType) as c_int + unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).TZInfoType) as c_int } } // skipped non-limited PyDate_FromDate @@ -701,26 +704,30 @@ pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int { // skipped non-limited PyDelta_FromDSU pub unsafe fn PyTimeZone_FromOffset(offset: *mut PyObject) -> *mut PyObject { - ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, std::ptr::null_mut()) + unsafe { ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, std::ptr::null_mut()) } } pub unsafe fn PyTimeZone_FromOffsetAndName( offset: *mut PyObject, name: *mut PyObject, ) -> *mut PyObject { - ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name) + unsafe { ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name) } } #[cfg(not(PyPy))] pub unsafe fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject { - let f = (*PyDateTimeAPI()).DateTime_FromTimestamp; - f((*PyDateTimeAPI()).DateTimeType, args, std::ptr::null_mut()) + unsafe { + let f = (*PyDateTimeAPI()).DateTime_FromTimestamp; + f((*PyDateTimeAPI()).DateTimeType, args, std::ptr::null_mut()) + } } #[cfg(not(PyPy))] pub unsafe fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject { - let f = (*PyDateTimeAPI()).Date_FromTimestamp; - f((*PyDateTimeAPI()).DateType, args) + unsafe { + let f = (*PyDateTimeAPI()).Date_FromTimestamp; + f((*PyDateTimeAPI()).DateType, args) + } } #[cfg(PyPy)] diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 710be80243f..b3d3ba02756 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -11,12 +11,12 @@ extern "C" { #[inline] pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) } } #[inline] pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyDict_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyDict_Type)) as c_int } } extern "C" { @@ -85,22 +85,22 @@ extern "C" { #[inline] pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyDictKeys_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictKeys_Type)) as c_int } } #[inline] pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyDictValues_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictValues_Type)) as c_int } } #[inline] pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyDictItems_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictItems_Type)) as c_int } } #[inline] pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int { - (PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int + unsafe { (PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int } } #[cfg_attr(windows, link(name = "pythonXY"))] diff --git a/pyo3-ffi/src/floatobject.rs b/pyo3-ffi/src/floatobject.rs index 65fc1d4c316..16c5927a23f 100644 --- a/pyo3-ffi/src/floatobject.rs +++ b/pyo3-ffi/src/floatobject.rs @@ -14,12 +14,12 @@ extern "C" { #[inline] pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyFloat_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyFloat_Type)) } } #[inline] pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyFloat_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyFloat_Type)) as c_int } } // skipped Py_RETURN_NAN diff --git a/pyo3-ffi/src/import.rs b/pyo3-ffi/src/import.rs index e15a37b0a72..02a9b5d89de 100644 --- a/pyo3-ffi/src/import.rs +++ b/pyo3-ffi/src/import.rs @@ -62,7 +62,7 @@ pub unsafe fn PyImport_ImportModuleEx( locals: *mut PyObject, fromlist: *mut PyObject, ) -> *mut PyObject { - PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) + unsafe { PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) } } extern "C" { diff --git a/pyo3-ffi/src/iterobject.rs b/pyo3-ffi/src/iterobject.rs index aa0c7b26db1..fae92d5ef42 100644 --- a/pyo3-ffi/src/iterobject.rs +++ b/pyo3-ffi/src/iterobject.rs @@ -10,7 +10,7 @@ extern "C" { #[inline] pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PySeqIter_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PySeqIter_Type)) as c_int } } extern "C" { @@ -20,7 +20,7 @@ extern "C" { #[inline] pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyCallIter_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyCallIter_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/listobject.rs b/pyo3-ffi/src/listobject.rs index 881a8a8707b..70179afaf9f 100644 --- a/pyo3-ffi/src/listobject.rs +++ b/pyo3-ffi/src/listobject.rs @@ -13,12 +13,12 @@ extern "C" { #[inline] pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) } } #[inline] pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyList_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyList_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/longobject.rs b/pyo3-ffi/src/longobject.rs index 68b4ecba540..b018ac6db11 100644 --- a/pyo3-ffi/src/longobject.rs +++ b/pyo3-ffi/src/longobject.rs @@ -8,12 +8,12 @@ opaque_struct!(PyLongObject); #[inline] pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) } } #[inline] pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyLong_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyLong_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/memoryobject.rs b/pyo3-ffi/src/memoryobject.rs index b7ef9e2ef1d..6371ec6b326 100644 --- a/pyo3-ffi/src/memoryobject.rs +++ b/pyo3-ffi/src/memoryobject.rs @@ -14,7 +14,7 @@ extern "C" { #[inline] pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyMemoryView_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyMemoryView_Type)) as c_int } } // skipped non-limited PyMemoryView_GET_BUFFER diff --git a/pyo3-ffi/src/methodobject.rs b/pyo3-ffi/src/methodobject.rs index 3dfbbb5a208..950256756d6 100644 --- a/pyo3-ffi/src/methodobject.rs +++ b/pyo3-ffi/src/methodobject.rs @@ -24,13 +24,13 @@ extern "C" { #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int + unsafe { (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } } #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, ptr::addr_of_mut!(PyCFunction_Type)) + unsafe { PyObject_TypeCheck(op, ptr::addr_of_mut!(PyCFunction_Type)) } } #[cfg(not(Py_3_9))] @@ -224,7 +224,7 @@ extern "C" { #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject { - PyCFunction_NewEx(ml, slf, std::ptr::null_mut()) + unsafe { PyCFunction_NewEx(ml, slf, std::ptr::null_mut()) } } #[cfg(Py_3_9)] @@ -234,7 +234,7 @@ pub unsafe fn PyCFunction_NewEx( slf: *mut PyObject, module: *mut PyObject, ) -> *mut PyObject { - PyCMethod_New(ml, slf, module, std::ptr::null_mut()) + unsafe { PyCMethod_New(ml, slf, module, std::ptr::null_mut()) } } #[cfg(Py_3_9)] diff --git a/pyo3-ffi/src/modsupport.rs b/pyo3-ffi/src/modsupport.rs index 4a18d30f97c..814612cf1d4 100644 --- a/pyo3-ffi/src/modsupport.rs +++ b/pyo3-ffi/src/modsupport.rs @@ -120,25 +120,29 @@ pub unsafe fn PyModule_FromDefAndSpec2( #[inline] pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject { - PyModule_Create2( - module, - if cfg!(Py_LIMITED_API) { - PYTHON_ABI_VERSION - } else { - PYTHON_API_VERSION - }, - ) + unsafe { + PyModule_Create2( + module, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) + } } #[inline] pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject) -> *mut PyObject { - PyModule_FromDefAndSpec2( - def, - spec, - if cfg!(Py_LIMITED_API) { - PYTHON_ABI_VERSION - } else { - PYTHON_API_VERSION - }, - ) + unsafe { + PyModule_FromDefAndSpec2( + def, + spec, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) + } } diff --git a/pyo3-ffi/src/moduleobject.rs b/pyo3-ffi/src/moduleobject.rs index 2417664a421..46a8509d9d8 100644 --- a/pyo3-ffi/src/moduleobject.rs +++ b/pyo3-ffi/src/moduleobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(PyModule_Type)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyModule_Type)) } } #[inline] pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyModule_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyModule_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index 087cd32920c..3560a0e2001 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -170,26 +170,26 @@ pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] { - (*ob).ob_refcnt.ob_refcnt + unsafe { (*ob).ob_refcnt.ob_refcnt } } #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] { - (*ob).ob_refcnt + unsafe { (*ob).ob_refcnt } } #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] { - _Py_REFCNT(ob) + unsafe { _Py_REFCNT(ob) } } } #[inline] pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject { #[cfg(not(GraalPy))] - return (*ob).ob_type; + return unsafe { (*ob).ob_type }; #[cfg(GraalPy)] - return _Py_TYPE(ob); + return unsafe { _Py_TYPE(ob) }; } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -203,32 +203,34 @@ extern "C" { #[inline] pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t { #[cfg(not(GraalPy))] - { + unsafe { debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyLong_Type)); debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyBool_Type)); (*ob.cast::()).ob_size } #[cfg(GraalPy)] - _Py_SIZE(ob) + unsafe { + _Py_SIZE(ob) + } } #[inline(always)] #[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int { #[cfg(target_pointer_width = "64")] - { + unsafe { (((*op).ob_refcnt.ob_refcnt as crate::PY_INT32_T) < 0) as c_int } #[cfg(target_pointer_width = "32")] - { + unsafe { ((*op).ob_refcnt.ob_refcnt == _Py_IMMORTAL_REFCNT) as c_int } } #[inline] pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { - (Py_TYPE(ob) == tp) as c_int + unsafe { (Py_TYPE(ob) == tp) as c_int } } // skipped _Py_SetRefCnt @@ -379,7 +381,7 @@ extern "C" { #[inline] pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { - (Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int + unsafe { (Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int } } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -651,7 +653,7 @@ pub unsafe fn Py_INCREF(op: *mut PyObject) { )))] { #[cfg(all(Py_3_12, target_pointer_width = "64"))] - { + unsafe { let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; let new_refcnt = cur_refcnt.wrapping_add(1); if new_refcnt == 0 { @@ -693,7 +695,7 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), GraalPy ))] - { + unsafe { // _Py_DecRef was added to the ABI in 3.10; skips null checks #[cfg(all(Py_3_10, not(PyPy)))] { @@ -712,7 +714,7 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), GraalPy )))] - { + unsafe { #[cfg(Py_3_12)] if _Py_IsImmortal(op) != 0 { return; @@ -753,24 +755,26 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { #[inline] pub unsafe fn Py_CLEAR(op: *mut *mut PyObject) { - let tmp = *op; - if !tmp.is_null() { - *op = ptr::null_mut(); - Py_DECREF(tmp); + unsafe { + let tmp = *op; + if !tmp.is_null() { + *op = ptr::null_mut(); + Py_DECREF(tmp) + }; } } #[inline] pub unsafe fn Py_XINCREF(op: *mut PyObject) { if !op.is_null() { - Py_INCREF(op) + unsafe { Py_INCREF(op) } } } #[inline] pub unsafe fn Py_XDECREF(op: *mut PyObject) { if !op.is_null() { - Py_DECREF(op) + unsafe { Py_DECREF(op) } } } @@ -790,7 +794,7 @@ extern "C" { #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] #[inline] pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject { - Py_INCREF(obj); + unsafe { Py_INCREF(obj) }; obj } @@ -798,7 +802,7 @@ pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject { #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] #[inline] pub unsafe fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject { - Py_XINCREF(obj); + unsafe { Py_XINCREF(obj) }; obj } @@ -856,7 +860,7 @@ pub unsafe fn Py_None() -> *mut PyObject { #[inline] pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int { - Py_Is(x, Py_None()) + unsafe { Py_Is(x, Py_None()) } } // skipped Py_RETURN_NONE @@ -874,13 +878,13 @@ extern "C" { #[inline] pub unsafe fn Py_NotImplemented() -> *mut PyObject { #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] - return Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED); + return unsafe { Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED) }; #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] return ptr::addr_of_mut!(_Py_NotImplementedStruct); #[cfg(GraalPy)] - return _Py_NotImplementedStructReference; + return unsafe { _Py_NotImplementedStructReference }; } // skipped Py_RETURN_NOTIMPLEMENTED @@ -920,19 +924,19 @@ pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_in #[inline] pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int { - PyType_HasFeature(t, f) + unsafe { PyType_HasFeature(t, f) } } #[inline] pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) } } // skipped _PyType_CAST #[inline] pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int { - Py_IS_TYPE(op, ptr::addr_of_mut!(PyType_Type)) + unsafe { Py_IS_TYPE(op, ptr::addr_of_mut!(PyType_Type)) } } extern "C" { diff --git a/pyo3-ffi/src/objimpl.rs b/pyo3-ffi/src/objimpl.rs index 76835a6d158..9dd29f3899d 100644 --- a/pyo3-ffi/src/objimpl.rs +++ b/pyo3-ffi/src/objimpl.rs @@ -61,7 +61,7 @@ extern "C" { #[inline] pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int { - PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC) + unsafe { PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC) } } extern "C" { diff --git a/pyo3-ffi/src/pycapsule.rs b/pyo3-ffi/src/pycapsule.rs index 5b77841c23c..8496245fb71 100644 --- a/pyo3-ffi/src/pycapsule.rs +++ b/pyo3-ffi/src/pycapsule.rs @@ -12,7 +12,7 @@ pub type PyCapsule_Destructor = unsafe extern "C" fn(o: *mut PyObject); #[inline] pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int { - (Py_TYPE(ob) == addr_of_mut!(PyCapsule_Type)) as c_int + unsafe { (Py_TYPE(ob) == addr_of_mut!(PyCapsule_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/pyerrors.rs b/pyo3-ffi/src/pyerrors.rs index d341239a07b..23419e29a97 100644 --- a/pyo3-ffi/src/pyerrors.rs +++ b/pyo3-ffi/src/pyerrors.rs @@ -73,20 +73,22 @@ extern "C" { #[inline] pub unsafe fn PyExceptionClass_Check(x: *mut PyObject) -> c_int { - (PyType_Check(x) != 0 - && PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0) - as c_int + unsafe { + (PyType_Check(x) != 0 + && PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0) + as c_int + } } #[inline] pub unsafe fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) } } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject { - Py_TYPE(x) as *mut PyObject + unsafe { Py_TYPE(x) as *mut PyObject } } // ported from cpython exception.c (line 2096) diff --git a/pyo3-ffi/src/pystate.rs b/pyo3-ffi/src/pystate.rs index a6caf421ff6..dd833cbabff 100644 --- a/pyo3-ffi/src/pystate.rs +++ b/pyo3-ffi/src/pystate.rs @@ -52,7 +52,7 @@ extern "C" { #[inline] pub unsafe fn PyThreadState_GET() -> *mut PyThreadState { - PyThreadState_Get() + unsafe { PyThreadState_Get() } } extern "C" { @@ -67,7 +67,7 @@ extern "C" { // skipped non-limited / 3.9 PyThreadState_GetInterpreter // skipped non-limited / 3.9 PyThreadState_GetID -extern "C" { +unsafe extern "C" { // PyThreadState_GetFrame #[cfg(all(Py_3_10, not(PyPy), not(Py_LIMITED_API)))] pub fn PyThreadState_GetFrame(arg1: *mut PyThreadState) -> *mut PyFrameObject; @@ -105,7 +105,7 @@ impl Drop for HangThread { // pthread_exit from PyGILState_Ensure (https://github.com/python/cpython/issues/87135). mod raw { #[cfg(all(not(Py_3_14), rustc_has_extern_c_unwind))] - extern "C-unwind" { + unsafe extern "C-unwind" { #[cfg_attr(PyPy, link_name = "PyPyGILState_Ensure")] pub fn PyGILState_Ensure() -> super::PyGILState_STATE; } @@ -138,7 +138,7 @@ pub unsafe extern "C" fn PyGILState_Ensure() -> PyGILState_STATE { // and therefore will cause unsafety if there are pinned objects on the stack. AFAICT there's // nothing we can do it other than waiting for Python 3.14 or not using Windows. At least, // if there is nothing pinned on the stack, it won't cause the process to crash. - let ret: PyGILState_STATE = raw::PyGILState_Ensure(); + let ret: PyGILState_STATE = unsafe { raw::PyGILState_Ensure() }; std::mem::forget(guard); ret } diff --git a/pyo3-ffi/src/rangeobject.rs b/pyo3-ffi/src/rangeobject.rs index 408b5cdc5a4..81d2a5b9f69 100644 --- a/pyo3-ffi/src/rangeobject.rs +++ b/pyo3-ffi/src/rangeobject.rs @@ -12,5 +12,5 @@ extern "C" { #[inline] pub unsafe fn PyRange_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyRange_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyRange_Type)) as c_int } } diff --git a/pyo3-ffi/src/setobject.rs b/pyo3-ffi/src/setobject.rs index 9d5351fc798..adecc5e0f8e 100644 --- a/pyo3-ffi/src/setobject.rs +++ b/pyo3-ffi/src/setobject.rs @@ -34,9 +34,11 @@ pub struct PySetObject { #[inline] #[cfg(all(not(any(PyPy, GraalPy)), not(Py_LIMITED_API)))] pub unsafe fn PySet_GET_SIZE(so: *mut PyObject) -> Py_ssize_t { - debug_assert_eq!(PyAnySet_Check(so), 1); - let so = so.cast::(); - (*so).used + unsafe { + debug_assert_eq!(PyAnySet_Check(so), 1); + let so = so.cast::(); + (*so).used + } } #[cfg(not(Py_LIMITED_API))] @@ -94,7 +96,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int { - (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) as c_int + unsafe { (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) as c_int } } extern "C" { @@ -106,8 +108,10 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int { - (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type) - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int + unsafe { + (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type) + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int + } } extern "C" { @@ -119,21 +123,25 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int { - (Py_TYPE(ob) == addr_of_mut!(PySet_Type) || Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) - as c_int + unsafe { + (Py_TYPE(ob) == addr_of_mut!(PySet_Type) || Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) + as c_int + } } #[inline] pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int { - (PyAnySet_CheckExact(ob) != 0 - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0 - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int + unsafe { + (PyAnySet_CheckExact(ob) != 0 + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0 + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int + } } #[inline] #[cfg(Py_3_10)] pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int { - crate::Py_IS_TYPE(op, addr_of_mut!(PySet_Type)) + unsafe { crate::Py_IS_TYPE(op, addr_of_mut!(PySet_Type)) } } extern "C" { @@ -145,6 +153,8 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int { - (Py_TYPE(ob) == addr_of_mut!(PySet_Type) - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0) as c_int + unsafe { + (Py_TYPE(ob) == addr_of_mut!(PySet_Type) + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0) as c_int + } } diff --git a/pyo3-ffi/src/sliceobject.rs b/pyo3-ffi/src/sliceobject.rs index a3ea153987c..5747ab8cd39 100644 --- a/pyo3-ffi/src/sliceobject.rs +++ b/pyo3-ffi/src/sliceobject.rs @@ -42,7 +42,7 @@ extern "C" { #[inline] pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PySlice_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PySlice_Type)) as c_int } } extern "C" { @@ -75,12 +75,14 @@ pub unsafe fn PySlice_GetIndicesEx( step: *mut Py_ssize_t, slicelength: *mut Py_ssize_t, ) -> c_int { - if PySlice_Unpack(slice, start, stop, step) < 0 { - *slicelength = 0; - -1 - } else { - *slicelength = PySlice_AdjustIndices(length, start, stop, *step); - 0 + unsafe { + if PySlice_Unpack(slice, start, stop, step) < 0 { + *slicelength = 0; + -1 + } else { + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); + 0 + } } } diff --git a/pyo3-ffi/src/structseq.rs b/pyo3-ffi/src/structseq.rs index f8566787b51..0d62c99df2d 100644 --- a/pyo3-ffi/src/structseq.rs +++ b/pyo3-ffi/src/structseq.rs @@ -45,13 +45,13 @@ pub type PyStructSequence = crate::PyTupleObject; #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] #[inline] pub unsafe fn PyStructSequence_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - crate::PyTuple_SET_ITEM(op, i, v) + unsafe { crate::PyTuple_SET_ITEM(op, i, v) } } #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] #[inline] pub unsafe fn PyStructSequence_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - crate::PyTuple_GET_ITEM(op, i) + unsafe { crate::PyTuple_GET_ITEM(op, i) } } extern "C" { diff --git a/pyo3-ffi/src/traceback.rs b/pyo3-ffi/src/traceback.rs index 432b6980ef5..d58ac40a448 100644 --- a/pyo3-ffi/src/traceback.rs +++ b/pyo3-ffi/src/traceback.rs @@ -23,5 +23,5 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyTraceBack_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyTraceBack_Type)) as c_int } } diff --git a/pyo3-ffi/src/tupleobject.rs b/pyo3-ffi/src/tupleobject.rs index d265c91a4b1..145038c1e64 100644 --- a/pyo3-ffi/src/tupleobject.rs +++ b/pyo3-ffi/src/tupleobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyTuple_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) } } #[inline] pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyTuple_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyTuple_Type)) as c_int } } extern "C" { diff --git a/pyo3-ffi/src/unicodeobject.rs b/pyo3-ffi/src/unicodeobject.rs index 1e0425ce2a2..9dc0c641d79 100644 --- a/pyo3-ffi/src/unicodeobject.rs +++ b/pyo3-ffi/src/unicodeobject.rs @@ -34,13 +34,13 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int { - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) + unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) } } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(PyUnicode_Type)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(PyUnicode_Type)) as c_int } } pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD; diff --git a/pyo3-ffi/src/weakrefobject.rs b/pyo3-ffi/src/weakrefobject.rs index 305dc290fa8..0d9685e2270 100644 --- a/pyo3-ffi/src/weakrefobject.rs +++ b/pyo3-ffi/src/weakrefobject.rs @@ -31,25 +31,27 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int { - PyObject_TypeCheck(op, addr_of_mut!(_PyWeakref_RefType)) + unsafe { PyObject_TypeCheck(op, addr_of_mut!(_PyWeakref_RefType)) } } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut!(_PyWeakref_RefType)) as c_int + unsafe { (Py_TYPE(op) == addr_of_mut!(_PyWeakref_RefType)) as c_int } } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int { - ((Py_TYPE(op) == addr_of_mut!(_PyWeakref_ProxyType)) - || (Py_TYPE(op) == addr_of_mut!(_PyWeakref_CallableProxyType))) as c_int + unsafe { + ((Py_TYPE(op) == addr_of_mut!(_PyWeakref_ProxyType)) + || (Py_TYPE(op) == addr_of_mut!(_PyWeakref_CallableProxyType))) as c_int + } } #[inline] pub unsafe fn PyWeakref_Check(op: *mut PyObject) -> c_int { - (PyWeakref_CheckRef(op) != 0 || PyWeakref_CheckProxy(op) != 0) as c_int + unsafe { (PyWeakref_CheckRef(op) != 0 || PyWeakref_CheckProxy(op) != 0) as c_int } } extern "C" { diff --git a/src/err/err_state.rs b/src/err/err_state.rs index 98be633e91c..9353f032e93 100644 --- a/src/err/err_state.rs +++ b/src/err/err_state.rs @@ -240,9 +240,11 @@ impl PyErrStateNormalized { ptraceback: *mut ffi::PyObject, ) -> Self { PyErrStateNormalized { - ptype: Py::from_owned_ptr_or_opt(py, ptype).expect("Exception type missing"), - pvalue: Py::from_owned_ptr_or_opt(py, pvalue).expect("Exception value missing"), - ptraceback: Py::from_owned_ptr_or_opt(py, ptraceback), + ptype: unsafe { Py::from_owned_ptr_or_opt(py, ptype).expect("Exception type missing") }, + pvalue: unsafe { + Py::from_owned_ptr_or_opt(py, pvalue).expect("Exception value missing") + }, + ptraceback: unsafe { Py::from_owned_ptr_or_opt(py, ptraceback) }, } } diff --git a/src/ffi_ptr_ext.rs b/src/ffi_ptr_ext.rs index 956b4e8406c..108f088ea18 100644 --- a/src/ffi_ptr_ext.rs +++ b/src/ffi_ptr_ext.rs @@ -40,23 +40,23 @@ pub(crate) trait FfiPtrExt: Sealed { impl FfiPtrExt for *mut ffi::PyObject { #[inline] unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult> { - Bound::from_owned_ptr_or_err(py, self) + unsafe { Bound::from_owned_ptr_or_err(py, self) } } #[inline] unsafe fn assume_owned_or_opt(self, py: Python<'_>) -> Option> { - Bound::from_owned_ptr_or_opt(py, self) + unsafe { Bound::from_owned_ptr_or_opt(py, self) } } #[inline] #[track_caller] unsafe fn assume_owned(self, py: Python<'_>) -> Bound<'_, PyAny> { - Bound::from_owned_ptr(py, self) + unsafe { Bound::from_owned_ptr(py, self) } } #[inline] unsafe fn assume_owned_unchecked(self, py: Python<'_>) -> Bound<'_, PyAny> { - Bound::from_owned_ptr_unchecked(py, self) + unsafe { Bound::from_owned_ptr_unchecked(py, self) } } #[inline] @@ -64,22 +64,22 @@ impl FfiPtrExt for *mut ffi::PyObject { self, py: Python<'_>, ) -> PyResult> { - Borrowed::from_ptr_or_err(py, self) + unsafe { Borrowed::from_ptr_or_err(py, self) } } #[inline] unsafe fn assume_borrowed_or_opt<'a>(self, py: Python<'_>) -> Option> { - Borrowed::from_ptr_or_opt(py, self) + unsafe { Borrowed::from_ptr_or_opt(py, self) } } #[inline] #[track_caller] unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> { - Borrowed::from_ptr(py, self) + unsafe { Borrowed::from_ptr(py, self) } } #[inline] unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> { - Borrowed::from_ptr_unchecked(py, self) + unsafe { Borrowed::from_ptr_unchecked(py, self) } } } diff --git a/src/gil.rs b/src/gil.rs index d7e6daae918..5fccb04ef6a 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -111,15 +111,15 @@ where F: for<'p> FnOnce(Python<'p>) -> R, { assert_eq!( - ffi::Py_IsInitialized(), + unsafe { ffi::Py_IsInitialized() }, 0, "called `with_embedded_python_interpreter` but a Python interpreter is already running." ); - ffi::Py_InitializeEx(0); + unsafe { ffi::Py_InitializeEx(0) }; let result = { - let guard = GILGuard::assume(); + let guard = unsafe { GILGuard::assume() }; let py = guard.python(); // Import the threading module - this ensures that it will associate this thread as the "main" // thread, which is important to avoid an `AssertionError` at finalization. @@ -130,7 +130,7 @@ where }; // Finalize the Python interpreter. - ffi::Py_Finalize(); + unsafe { ffi::Py_Finalize() }; result } @@ -201,15 +201,15 @@ impl GILGuard { /// as part of multi-phase interpreter initialization. pub(crate) unsafe fn acquire_unchecked() -> Self { if gil_is_acquired() { - return Self::assume(); + return unsafe { Self::assume() }; } - let gstate = ffi::PyGILState_Ensure(); // acquire GIL + let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL increment_gil_count(); #[cfg(not(pyo3_disable_reference_pool))] if let Some(pool) = Lazy::get(&POOL) { - pool.update_counts(Python::assume_gil_acquired()); + pool.update_counts(unsafe { Python::assume_gil_acquired() }); } GILGuard::Ensured { gstate } } @@ -300,7 +300,7 @@ pub(crate) struct SuspendGIL { impl SuspendGIL { pub(crate) unsafe fn new() -> Self { let count = GIL_COUNT.with(|c| c.replace(0)); - let tstate = ffi::PyEval_SaveThread(); + let tstate = unsafe { ffi::PyEval_SaveThread() }; Self { count, tstate } } @@ -364,7 +364,7 @@ impl Drop for LockGIL { #[track_caller] pub unsafe fn register_incref(obj: NonNull) { if gil_is_acquired() { - ffi::Py_INCREF(obj.as_ptr()) + unsafe { ffi::Py_INCREF(obj.as_ptr()) } } else { panic!("Cannot clone pointer into Python heap without the GIL being held."); } @@ -381,7 +381,7 @@ pub unsafe fn register_incref(obj: NonNull) { #[track_caller] pub unsafe fn register_decref(obj: NonNull) { if gil_is_acquired() { - ffi::Py_DECREF(obj.as_ptr()) + unsafe { ffi::Py_DECREF(obj.as_ptr()) } } else { #[cfg(not(pyo3_disable_reference_pool))] POOL.register_decref(obj); @@ -617,13 +617,15 @@ mod tests { unsafe extern "C" fn capsule_drop(capsule: *mut ffi::PyObject) { // This line will implicitly call update_counts // -> and so cause deadlock if update_counts is not handling recursion correctly. - let pool = GILGuard::assume(); + let pool = unsafe { GILGuard::assume() }; // Rebuild obj so that it can be dropped - PyObject::from_owned_ptr( - pool.python(), - ffi::PyCapsule_GetPointer(capsule, std::ptr::null()) as _, - ); + unsafe { + PyObject::from_owned_ptr( + pool.python(), + ffi::PyCapsule_GetPointer(capsule, std::ptr::null()) as _, + ) + }; } let ptr = obj.into_ptr(); diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index cbf79a14707..f06298dface 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -296,9 +296,10 @@ impl FunctionDescription { // the rest are varargs. let positional_args_to_consume = num_positional_parameters.min(positional_args_provided); - let (positional_parameters, remaining) = + let (positional_parameters, remaining) = unsafe { std::slice::from_raw_parts(args, positional_args_provided) - .split_at(positional_args_to_consume); + .split_at(positional_args_to_consume) + }; output[..positional_args_to_consume].copy_from_slice(positional_parameters); remaining }; @@ -309,14 +310,17 @@ impl FunctionDescription { // Safety: kwnames is known to be a pointer to a tuple, or null // - we both have the GIL and can borrow this input reference for the `'py` lifetime. - let kwnames: Option> = - Borrowed::from_ptr_or_opt(py, kwnames).map(|kwnames| kwnames.downcast_unchecked()); + let kwnames: Option> = unsafe { + Borrowed::from_ptr_or_opt(py, kwnames).map(|kwnames| kwnames.downcast_unchecked()) + }; if let Some(kwnames) = kwnames { - let kwargs = ::std::slice::from_raw_parts( - // Safety: PyArg has the same memory layout as `*mut ffi::PyObject` - args.offset(nargs).cast::>(), - kwnames.len(), - ); + let kwargs = unsafe { + ::std::slice::from_raw_parts( + // Safety: PyArg has the same memory layout as `*mut ffi::PyObject` + args.offset(nargs).cast::>(), + kwnames.len(), + ) + }; self.handle_kwargs::( kwnames.iter_borrowed().zip(kwargs.iter().copied()), @@ -362,9 +366,10 @@ impl FunctionDescription { // - `kwargs` is known to be a dict or null // - we both have the GIL and can borrow these input references for the `'py` lifetime. let args: Borrowed<'py, 'py, PyTuple> = - Borrowed::from_ptr(py, args).downcast_unchecked::(); - let kwargs: Option> = - Borrowed::from_ptr_or_opt(py, kwargs).map(|kwargs| kwargs.downcast_unchecked()); + unsafe { Borrowed::from_ptr(py, args).downcast_unchecked::() }; + let kwargs: Option> = unsafe { + Borrowed::from_ptr_or_opt(py, kwargs).map(|kwargs| kwargs.downcast_unchecked()) + }; let num_positional_parameters = self.positional_parameter_names.len(); @@ -391,7 +396,7 @@ impl FunctionDescription { let mut varkeywords = K::Varkeywords::default(); if let Some(kwargs) = kwargs { self.handle_kwargs::( - kwargs.iter_borrowed(), + unsafe { kwargs.iter_borrowed() }, &mut varkeywords, num_positional_parameters, output, diff --git a/src/impl_/pyclass.rs b/src/impl_/pyclass.rs index 06ec83d6ff2..270ba2de47e 100644 --- a/src/impl_/pyclass.rs +++ b/src/impl_/pyclass.rs @@ -116,7 +116,7 @@ impl PyClassWeakRef for PyClassWeakRefSlot { #[inline] unsafe fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python<'_>) { if !self.0.is_null() { - ffi::PyObject_ClearWeakRefs(obj) + unsafe { ffi::PyObject_ClearWeakRefs(obj) } } } } @@ -332,7 +332,7 @@ slot_fragment_trait! { slf: *mut ffi::PyObject, attr: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { - let res = ffi::PyObject_GenericGetAttr(slf, attr); + let res = unsafe { ffi::PyObject_GenericGetAttr(slf, attr) }; if res.is_null() { Err(PyErr::fetch(py)) } else { @@ -353,7 +353,7 @@ slot_fragment_trait! { attr: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { Err(PyErr::new::( - (Py::::from_borrowed_ptr(py, attr),) + (unsafe {Py::::from_borrowed_ptr(py, attr)},) )) } } @@ -366,24 +366,26 @@ macro_rules! generate_pyclass_getattro_slot { _slf: *mut $crate::ffi::PyObject, attr: *mut $crate::ffi::PyObject, ) -> *mut $crate::ffi::PyObject { - $crate::impl_::trampoline::getattrofunc(_slf, attr, |py, _slf, attr| { - use ::std::result::Result::*; - use $crate::impl_::pyclass::*; - let collector = PyClassImplCollector::<$cls>::new(); - - // Strategy: - // - Try __getattribute__ first. Its default is PyObject_GenericGetAttr. - // - If it returns a result, use it. - // - If it fails with AttributeError, try __getattr__. - // - If it fails otherwise, reraise. - match collector.__getattribute__(py, _slf, attr) { - Ok(obj) => Ok(obj), - Err(e) if e.is_instance_of::<$crate::exceptions::PyAttributeError>(py) => { - collector.__getattr__(py, _slf, attr) + unsafe { + $crate::impl_::trampoline::getattrofunc(_slf, attr, |py, _slf, attr| { + use ::std::result::Result::*; + use $crate::impl_::pyclass::*; + let collector = PyClassImplCollector::<$cls>::new(); + + // Strategy: + // - Try __getattribute__ first. Its default is PyObject_GenericGetAttr. + // - If it returns a result, use it. + // - If it fails with AttributeError, try __getattr__. + // - If it fails otherwise, reraise. + match collector.__getattribute__(py, _slf, attr) { + Ok(obj) => Ok(obj), + Err(e) if e.is_instance_of::<$crate::exceptions::PyAttributeError>(py) => { + collector.__getattr__(py, _slf, attr) + } + Err(e) => Err(e), } - Err(e) => Err(e), - } - }) + }) + } } $crate::ffi::PyType_Slot { slot: $crate::ffi::Py_tp_getattro, @@ -450,22 +452,24 @@ macro_rules! define_pyclass_setattr_slot { attr: *mut $crate::ffi::PyObject, value: *mut $crate::ffi::PyObject, ) -> ::std::os::raw::c_int { - $crate::impl_::trampoline::setattrofunc( - _slf, - attr, - value, - |py, _slf, attr, value| { - use ::std::option::Option::*; - use $crate::impl_::callback::IntoPyCallbackOutput; - use $crate::impl_::pyclass::*; - let collector = PyClassImplCollector::<$cls>::new(); - if let Some(value) = ::std::ptr::NonNull::new(value) { - collector.$set(py, _slf, attr, value).convert(py) - } else { - collector.$del(py, _slf, attr).convert(py) - } - }, - ) + unsafe { + $crate::impl_::trampoline::setattrofunc( + _slf, + attr, + value, + |py, _slf, attr, value| { + use ::std::option::Option::*; + use $crate::impl_::callback::IntoPyCallbackOutput; + use $crate::impl_::pyclass::*; + let collector = PyClassImplCollector::<$cls>::new(); + if let Some(value) = ::std::ptr::NonNull::new(value) { + collector.$set(py, _slf, attr, value).convert(py) + } else { + collector.$del(py, _slf, attr).convert(py) + } + }, + ) + } } $crate::ffi::PyType_Slot { slot: $crate::ffi::$slot, @@ -565,17 +569,19 @@ macro_rules! define_pyclass_binary_operator_slot { _slf: *mut $crate::ffi::PyObject, _other: *mut $crate::ffi::PyObject, ) -> *mut $crate::ffi::PyObject { - $crate::impl_::trampoline::binaryfunc(_slf, _other, |py, _slf, _other| { - use $crate::impl_::pyclass::*; - let collector = PyClassImplCollector::<$cls>::new(); - let lhs_result = collector.$lhs(py, _slf, _other)?; - if lhs_result == $crate::ffi::Py_NotImplemented() { - $crate::ffi::Py_DECREF(lhs_result); - collector.$rhs(py, _other, _slf) - } else { - ::std::result::Result::Ok(lhs_result) - } - }) + unsafe { + $crate::impl_::trampoline::binaryfunc(_slf, _other, |py, _slf, _other| { + use $crate::impl_::pyclass::*; + let collector = PyClassImplCollector::<$cls>::new(); + let lhs_result = collector.$lhs(py, _slf, _other)?; + if lhs_result == $crate::ffi::Py_NotImplemented() { + $crate::ffi::Py_DECREF(lhs_result); + collector.$rhs(py, _other, _slf) + } else { + ::std::result::Result::Ok(lhs_result) + } + }) + } } $crate::ffi::PyType_Slot { slot: $crate::ffi::$slot, @@ -758,17 +764,24 @@ macro_rules! generate_pyclass_pow_slot { _other: *mut $crate::ffi::PyObject, _mod: *mut $crate::ffi::PyObject, ) -> *mut $crate::ffi::PyObject { - $crate::impl_::trampoline::ternaryfunc(_slf, _other, _mod, |py, _slf, _other, _mod| { - use $crate::impl_::pyclass::*; - let collector = PyClassImplCollector::<$cls>::new(); - let lhs_result = collector.__pow__(py, _slf, _other, _mod)?; - if lhs_result == $crate::ffi::Py_NotImplemented() { - $crate::ffi::Py_DECREF(lhs_result); - collector.__rpow__(py, _other, _slf, _mod) - } else { - ::std::result::Result::Ok(lhs_result) - } - }) + unsafe { + $crate::impl_::trampoline::ternaryfunc( + _slf, + _other, + _mod, + |py, _slf, _other, _mod| { + use $crate::impl_::pyclass::*; + let collector = PyClassImplCollector::<$cls>::new(); + let lhs_result = collector.__pow__(py, _slf, _other, _mod)?; + if lhs_result == $crate::ffi::Py_NotImplemented() { + $crate::ffi::Py_DECREF(lhs_result); + collector.__rpow__(py, _other, _slf, _mod) + } else { + ::std::result::Result::Ok(lhs_result) + } + }, + ) + } } $crate::ffi::PyType_Slot { slot: $crate::ffi::Py_nb_power, @@ -835,8 +848,8 @@ slot_fragment_trait! { other: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { // By default `__ne__` will try `__eq__` and invert the result - let slf = Borrowed::from_ptr(py, slf); - let other = Borrowed::from_ptr(py, other); + let slf = unsafe { Borrowed::from_ptr(py, slf)}; + let other = unsafe { Borrowed::from_ptr(py, other)}; slf.eq(other).map(|is_eq| PyBool::new(py, !is_eq).to_owned().into_ptr()) } } @@ -883,19 +896,21 @@ macro_rules! generate_pyclass_richcompare_slot { other: *mut $crate::ffi::PyObject, op: ::std::os::raw::c_int, ) -> *mut $crate::ffi::PyObject { - $crate::impl_::trampoline::richcmpfunc(slf, other, op, |py, slf, other, op| { - use $crate::class::basic::CompareOp; - use $crate::impl_::pyclass::*; - let collector = PyClassImplCollector::<$cls>::new(); - match CompareOp::from_raw(op).expect("invalid compareop") { - CompareOp::Lt => collector.__lt__(py, slf, other), - CompareOp::Le => collector.__le__(py, slf, other), - CompareOp::Eq => collector.__eq__(py, slf, other), - CompareOp::Ne => collector.__ne__(py, slf, other), - CompareOp::Gt => collector.__gt__(py, slf, other), - CompareOp::Ge => collector.__ge__(py, slf, other), - } - }) + unsafe { + $crate::impl_::trampoline::richcmpfunc(slf, other, op, |py, slf, other, op| { + use $crate::class::basic::CompareOp; + use $crate::impl_::pyclass::*; + let collector = PyClassImplCollector::<$cls>::new(); + match CompareOp::from_raw(op).expect("invalid compareop") { + CompareOp::Lt => collector.__lt__(py, slf, other), + CompareOp::Le => collector.__le__(py, slf, other), + CompareOp::Eq => collector.__eq__(py, slf, other), + CompareOp::Ne => collector.__ne__(py, slf, other), + CompareOp::Gt => collector.__gt__(py, slf, other), + CompareOp::Ge => collector.__ge__(py, slf, other), + } + }) + } } } $crate::ffi::PyType_Slot { @@ -925,10 +940,12 @@ pub unsafe extern "C" fn alloc_with_freelist( subtype: *mut ffi::PyTypeObject, nitems: ffi::Py_ssize_t, ) -> *mut ffi::PyObject { - let py = Python::assume_gil_acquired(); + let py = unsafe { Python::assume_gil_acquired() }; #[cfg(not(Py_3_8))] - bpo_35810_workaround(py, subtype); + unsafe { + bpo_35810_workaround(py, subtype) + }; let self_type = T::type_object_raw(py); // If this type is a variable type or the subtype is not equal to this type, we cannot use the @@ -937,12 +954,13 @@ pub unsafe extern "C" fn alloc_with_freelist( let mut free_list = T::get_free_list(py).lock().unwrap(); if let Some(obj) = free_list.pop() { drop(free_list); - ffi::PyObject_Init(obj, subtype); + unsafe { ffi::PyObject_Init(obj, subtype) }; + unsafe { ffi::PyObject_Init(obj, subtype) }; return obj as _; } } - ffi::PyType_GenericAlloc(subtype, nitems) + unsafe { ffi::PyType_GenericAlloc(subtype, nitems) } } /// Implementation of tp_free for `freelist` classes. @@ -952,28 +970,30 @@ pub unsafe extern "C" fn alloc_with_freelist( /// - The GIL must be held. pub unsafe extern "C" fn free_with_freelist(obj: *mut c_void) { let obj = obj as *mut ffi::PyObject; - debug_assert_eq!( - T::type_object_raw(Python::assume_gil_acquired()), - ffi::Py_TYPE(obj) - ); - let mut free_list = T::get_free_list(Python::assume_gil_acquired()) - .lock() - .unwrap(); - if let Some(obj) = free_list.insert(obj) { - drop(free_list); - let ty = ffi::Py_TYPE(obj); - - // Deduce appropriate inverse of PyType_GenericAlloc - let free = if ffi::PyType_IS_GC(ty) != 0 { - ffi::PyObject_GC_Del - } else { - ffi::PyObject_Free - }; - free(obj as *mut c_void); - - #[cfg(Py_3_8)] - if ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) != 0 { - ffi::Py_DECREF(ty as *mut ffi::PyObject); + unsafe { + debug_assert_eq!( + T::type_object_raw(Python::assume_gil_acquired()), + ffi::Py_TYPE(obj) + ); + let mut free_list = T::get_free_list(Python::assume_gil_acquired()) + .lock() + .unwrap(); + if let Some(obj) = free_list.insert(obj) { + drop(free_list); + let ty = ffi::Py_TYPE(obj); + + // Deduce appropriate inverse of PyType_GenericAlloc + let free = if ffi::PyType_IS_GC(ty) != 0 { + ffi::PyObject_GC_Del + } else { + ffi::PyObject_Free + }; + free(obj as *mut c_void); + + #[cfg(Py_3_8)] + if ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) != 0 { + ffi::Py_DECREF(ty as *mut ffi::PyObject); + } } } } @@ -1000,7 +1020,7 @@ unsafe fn bpo_35810_workaround(py: Python<'_>, ty: *mut ffi::PyTypeObject) { let _ = py; } - ffi::Py_INCREF(ty as *mut ffi::PyObject); + unsafe { ffi::Py_INCREF(ty as *mut ffi::PyObject) }; } /// Method storage for `#[pyclass]`. @@ -1150,28 +1170,28 @@ pub trait PyClassBaseType: Sized { /// Implementation of tp_dealloc for pyclasses without gc pub(crate) unsafe extern "C" fn tp_dealloc(obj: *mut ffi::PyObject) { - crate::impl_::trampoline::dealloc(obj, PyClassObject::::tp_dealloc) + unsafe { crate::impl_::trampoline::dealloc(obj, PyClassObject::::tp_dealloc) } } /// Implementation of tp_dealloc for pyclasses with gc pub(crate) unsafe extern "C" fn tp_dealloc_with_gc(obj: *mut ffi::PyObject) { #[cfg(not(PyPy))] - { + unsafe { ffi::PyObject_GC_UnTrack(obj.cast()); } - crate::impl_::trampoline::dealloc(obj, PyClassObject::::tp_dealloc) + unsafe { crate::impl_::trampoline::dealloc(obj, PyClassObject::::tp_dealloc) } } pub(crate) unsafe extern "C" fn get_sequence_item_from_mapping( obj: *mut ffi::PyObject, index: ffi::Py_ssize_t, ) -> *mut ffi::PyObject { - let index = ffi::PyLong_FromSsize_t(index); + let index = unsafe { ffi::PyLong_FromSsize_t(index) }; if index.is_null() { return std::ptr::null_mut(); } - let result = ffi::PyObject_GetItem(obj, index); - ffi::Py_DECREF(index); + let result = unsafe { ffi::PyObject_GetItem(obj, index) }; + unsafe { ffi::Py_DECREF(index) }; result } @@ -1180,17 +1200,19 @@ pub(crate) unsafe extern "C" fn assign_sequence_item_from_mapping( index: ffi::Py_ssize_t, value: *mut ffi::PyObject, ) -> c_int { - let index = ffi::PyLong_FromSsize_t(index); - if index.is_null() { - return -1; + unsafe { + let index = ffi::PyLong_FromSsize_t(index); + if index.is_null() { + return -1; + } + let result = if value.is_null() { + ffi::PyObject_DelItem(obj, index) + } else { + ffi::PyObject_SetItem(obj, index, value) + }; + ffi::Py_DECREF(index); + result } - let result = if value.is_null() { - ffi::PyObject_DelItem(obj, index) - } else { - ffi::PyObject_SetItem(obj, index, value) - }; - ffi::Py_DECREF(index); - result } /// Helper trait to locate field within a `#[pyclass]` for a `#[pyo3(get)]`. @@ -1437,9 +1459,11 @@ unsafe fn ensure_no_mutable_alias<'py, ClassT: PyClass>( py: Python<'py>, obj: &*mut ffi::PyObject, ) -> Result, PyBorrowError> { - BoundRef::ref_from_ptr(py, obj) - .downcast_unchecked::() - .try_borrow() + unsafe { + BoundRef::ref_from_ptr(py, obj) + .downcast_unchecked::() + .try_borrow() + } } /// calculates the field pointer from an PyObject pointer diff --git a/src/impl_/pyclass_init.rs b/src/impl_/pyclass_init.rs index 7242b6186d9..ff0e4e80e96 100644 --- a/src/impl_/pyclass_init.rs +++ b/src/impl_/pyclass_init.rs @@ -39,17 +39,19 @@ impl PyObjectInit for PyNativeTypeInitializer { ) -> PyResult<*mut ffi::PyObject> { // HACK (due to FIXME below): PyBaseObject_Type's tp_new isn't happy with NULL arguments let is_base_object = type_object == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type); - let subtype_borrowed: Borrowed<'_, '_, PyType> = subtype - .cast::() - .assume_borrowed_unchecked(py) - .downcast_unchecked(); + let subtype_borrowed: Borrowed<'_, '_, PyType> = unsafe { + subtype + .cast::() + .assume_borrowed_unchecked(py) + .downcast_unchecked() + }; if is_base_object { let alloc = subtype_borrowed .get_slot(TP_ALLOC) .unwrap_or(ffi::PyType_GenericAlloc); - let obj = alloc(subtype, 0); + let obj = unsafe { alloc(subtype, 0) }; return if obj.is_null() { Err(PyErr::fetch(py)) } else { @@ -62,10 +64,11 @@ impl PyObjectInit for PyNativeTypeInitializer { #[cfg(not(Py_LIMITED_API))] { - match (*type_object).tp_new { + match unsafe { (*type_object).tp_new } { // FIXME: Call __new__ with actual arguments Some(newfunc) => { - let obj = newfunc(subtype, std::ptr::null_mut(), std::ptr::null_mut()); + let obj = + unsafe { newfunc(subtype, std::ptr::null_mut(), std::ptr::null_mut()) }; if obj.is_null() { Err(PyErr::fetch(py)) } else { @@ -79,7 +82,7 @@ impl PyObjectInit for PyNativeTypeInitializer { } } let type_object = T::type_object_raw(py); - inner(py, type_object, subtype) + unsafe { inner(py, type_object, subtype) } } #[inline] diff --git a/src/impl_/pymethods.rs b/src/impl_/pymethods.rs index e6cbaec86f5..8f869068463 100644 --- a/src/impl_/pymethods.rs +++ b/src/impl_/pymethods.rs @@ -295,14 +295,14 @@ where let trap = PanicTrap::new("uncaught panic inside __traverse__ handler"); let lock = LockGIL::during_traverse(); - let super_retval = call_super_traverse(slf, visit, arg, current_traverse); + let super_retval = unsafe { call_super_traverse(slf, visit, arg, current_traverse) }; if super_retval != 0 { return super_retval; } // SAFETY: `slf` is a valid Python object pointer to a class object of type T, and // traversal is running so no mutations can occur. - let class_object: &PyClassObject = &*slf.cast(); + let class_object: &PyClassObject = unsafe { &*slf.cast() }; let retval = // `#[pyclass(unsendable)]` types can only be deallocated by their own thread, so @@ -320,7 +320,7 @@ where // `.try_borrow()` above created a borrow, we need to release it when we're done // traversing the object. This allows us to read `instance` safely. let _guard = TraverseGuard(class_object); - let instance = &*class_object.contents.value.get(); + let instance = unsafe {&*class_object.contents.value.get()}; let visit = PyVisit { visit, arg, _guard: PhantomData }; @@ -359,16 +359,16 @@ unsafe fn call_super_traverse( // because the GC is running and so // - (a) we cannot do refcounting and // - (b) the type of the object cannot change. - let mut ty = ffi::Py_TYPE(obj); + let mut ty = unsafe { ffi::Py_TYPE(obj) }; let mut traverse: Option; // First find the current type by the current_traverse function loop { - traverse = get_slot(ty, TP_TRAVERSE); + traverse = unsafe { get_slot(ty, TP_TRAVERSE) }; if traverse_eq(traverse, current_traverse) { break; } - ty = get_slot(ty, TP_BASE); + ty = unsafe { get_slot(ty, TP_BASE) }; if ty.is_null() { // FIXME: return an error if current type not in the MRO? Should be impossible. return 0; @@ -377,16 +377,16 @@ unsafe fn call_super_traverse( // Get first base which has a different traverse function while traverse_eq(traverse, current_traverse) { - ty = get_slot(ty, TP_BASE); + ty = unsafe { get_slot(ty, TP_BASE) }; if ty.is_null() { break; } - traverse = get_slot(ty, TP_TRAVERSE); + traverse = unsafe { get_slot(ty, TP_TRAVERSE) }; } // If we found a type with a different traverse function, call it if let Some(traverse) = traverse { - return traverse(obj, visit, arg); + return unsafe { traverse(obj, visit, arg) }; } // FIXME same question as cython: what if the current type is not in the MRO? @@ -399,14 +399,16 @@ pub unsafe fn _call_clear( impl_: for<'py> unsafe fn(Python<'py>, *mut ffi::PyObject) -> PyResult<()>, current_clear: ffi::inquiry, ) -> c_int { - trampoline::trampoline(move |py| { - let super_retval = call_super_clear(py, slf, current_clear); - if super_retval != 0 { - return Err(PyErr::fetch(py)); - } - impl_(py, slf)?; - Ok(0) - }) + unsafe { + trampoline::trampoline(move |py| { + let super_retval = call_super_clear(py, slf, current_clear); + if super_retval != 0 { + return Err(PyErr::fetch(py)); + } + impl_(py, slf)?; + Ok(0) + }) + } } /// Call super-type traverse method, if necessary. @@ -424,7 +426,7 @@ unsafe fn call_super_clear( obj: *mut ffi::PyObject, current_clear: ffi::inquiry, ) -> c_int { - let mut ty = PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(obj)); + let mut ty = unsafe { PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(obj)) }; let mut clear: Option; // First find the current type by the current_clear function @@ -438,7 +440,7 @@ unsafe fn call_super_clear( // FIXME: return an error if current type not in the MRO? Should be impossible. return 0; } - ty = PyType::from_borrowed_type_ptr(py, base); + ty = unsafe { PyType::from_borrowed_type_ptr(py, base) }; } // Get first base which has a different clear function @@ -447,13 +449,13 @@ unsafe fn call_super_clear( if base.is_null() { break; } - ty = PyType::from_borrowed_type_ptr(py, base); + ty = unsafe { PyType::from_borrowed_type_ptr(py, base) }; clear = ty.get_slot(TP_CLEAR); } // If we found a type with a different clear function, call it if let Some(clear) = clear { - return clear(obj); + return unsafe { clear(obj) }; } // FIXME same question as cython: what if the current type is not in the MRO? @@ -633,14 +635,14 @@ pub struct BoundRef<'a, 'py, T>(pub &'a Bound<'py, T>); impl<'a, 'py> BoundRef<'a, 'py, PyAny> { pub unsafe fn ref_from_ptr(py: Python<'py>, ptr: &'a *mut ffi::PyObject) -> Self { - BoundRef(Bound::ref_from_ptr(py, ptr)) + unsafe { BoundRef(Bound::ref_from_ptr(py, ptr)) } } pub unsafe fn ref_from_ptr_or_opt( py: Python<'py>, ptr: &'a *mut ffi::PyObject, ) -> Option { - Bound::ref_from_ptr_or_opt(py, ptr).as_ref().map(BoundRef) + unsafe { Bound::ref_from_ptr_or_opt(py, ptr).as_ref().map(BoundRef) } } pub fn downcast(self) -> Result, DowncastError<'a, 'py>> { @@ -648,7 +650,7 @@ impl<'a, 'py> BoundRef<'a, 'py, PyAny> { } pub unsafe fn downcast_unchecked(self) -> BoundRef<'a, 'py, T> { - BoundRef(self.0.downcast_unchecked::()) + unsafe { BoundRef(self.0.downcast_unchecked::()) } } } @@ -702,9 +704,11 @@ pub unsafe fn tp_new_impl( initializer: PyClassInitializer, target_type: *mut ffi::PyTypeObject, ) -> PyResult<*mut ffi::PyObject> { - initializer - .create_class_object_of_type(py, target_type) - .map(Bound::into_ptr) + unsafe { + initializer + .create_class_object_of_type(py, target_type) + .map(Bound::into_ptr) + } } #[cfg(test)] @@ -725,7 +729,7 @@ mod tests { ) -> *mut ffi::PyObject { assert_eq!(nargs, 0); assert!(kwargs.is_null()); - Python::assume_gil_acquired().None().into_ptr() + unsafe { Python::assume_gil_acquired().None().into_ptr() } } let f = PyCFunction::internal_new( diff --git a/src/impl_/trampoline.rs b/src/impl_/trampoline.rs index 7ffad8abdcd..01f8f5e8b0e 100644 --- a/src/impl_/trampoline.rs +++ b/src/impl_/trampoline.rs @@ -19,7 +19,7 @@ use crate::{ pub unsafe fn module_init( f: for<'py> unsafe fn(Python<'py>) -> PyResult>, ) -> *mut ffi::PyObject { - trampoline(|py| f(py).map(|module| module.into_ptr())) + unsafe { trampoline(|py| f(py).map(|module| module.into_ptr())) } } #[inline] @@ -31,7 +31,7 @@ pub unsafe fn noargs( ) -> *mut ffi::PyObject { #[cfg(not(GraalPy))] // this is not specified and GraalPy does not pass null here debug_assert!(_args.is_null()); - trampoline(|py| f(py, slf)) + unsafe { trampoline(|py| f(py, slf)) } } macro_rules! trampoline { @@ -41,7 +41,7 @@ macro_rules! trampoline { $($arg_names: $arg_types,)* f: for<'py> unsafe fn (Python<'py>, $($arg_types),*) -> PyResult<$ret>, ) -> $ret { - trampoline(|py| f(py, $($arg_names,)*)) + unsafe {trampoline(|py| f(py, $($arg_names,)*))} } } } @@ -134,7 +134,7 @@ pub unsafe fn releasebufferproc( buf: *mut ffi::Py_buffer, f: for<'py> unsafe fn(Python<'py>, *mut ffi::PyObject, *mut ffi::Py_buffer) -> PyResult<()>, ) { - trampoline_unraisable(|py| f(py, slf, buf), slf) + unsafe { trampoline_unraisable(|py| f(py, slf, buf), slf) } } #[inline] @@ -146,13 +146,15 @@ pub(crate) unsafe fn dealloc( // so pass null_mut() to the context. // // (Note that we don't allow the implementation `f` to fail.) - trampoline_unraisable( - |py| { - f(py, slf); - Ok(()) - }, - std::ptr::null_mut(), - ) + unsafe { + trampoline_unraisable( + |py| { + f(py, slf); + Ok(()) + }, + std::ptr::null_mut(), + ) + } } // Ipowfunc is a unique case where PyO3 has its own type @@ -181,7 +183,7 @@ where let trap = PanicTrap::new("uncaught panic at ffi boundary"); // SAFETY: This function requires the GIL to already be held. - let guard = GILGuard::assume(); + let guard = unsafe { GILGuard::assume() }; let py = guard.python(); let out = panic_result_into_callback_output( py, @@ -229,13 +231,13 @@ where let trap = PanicTrap::new("uncaught panic at ffi boundary"); // SAFETY: The GIL is already held. - let guard = GILGuard::assume(); + let guard = unsafe { GILGuard::assume() }; let py = guard.python(); if let Err(py_err) = panic::catch_unwind(move || body(py)) .unwrap_or_else(|payload| Err(PanicException::from_panic_payload(payload))) { - py_err.write_unraisable(py, ctx.assume_borrowed_or_opt(py).as_deref()); + py_err.write_unraisable(py, unsafe { ctx.assume_borrowed_or_opt(py) }.as_deref()); } trap.disarm(); } diff --git a/src/instance.rs b/src/instance.rs index f3fe7a91783..6c85d20beb0 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -107,7 +107,10 @@ impl<'py> Bound<'py, PyAny> { #[inline] #[track_caller] pub unsafe fn from_owned_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self { - Self(py, ManuallyDrop::new(Py::from_owned_ptr(py, ptr))) + Self( + py, + ManuallyDrop::new(unsafe { Py::from_owned_ptr(py, ptr) }), + ) } /// Constructs a new `Bound<'py, PyAny>` from a pointer. Returns `None` if `ptr` is null. @@ -118,7 +121,7 @@ impl<'py> Bound<'py, PyAny> { /// - `ptr` must be an owned Python reference, as the `Bound<'py, PyAny>` will assume ownership #[inline] pub unsafe fn from_owned_ptr_or_opt(py: Python<'py>, ptr: *mut ffi::PyObject) -> Option { - Py::from_owned_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + unsafe { Py::from_owned_ptr_or_opt(py, ptr) }.map(|obj| Self(py, ManuallyDrop::new(obj))) } /// Constructs a new `Bound<'py, PyAny>` from a pointer. Returns an `Err` by calling `PyErr::fetch` @@ -133,7 +136,7 @@ impl<'py> Bound<'py, PyAny> { py: Python<'py>, ptr: *mut ffi::PyObject, ) -> PyResult { - Py::from_owned_ptr_or_err(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + unsafe { Py::from_owned_ptr_or_err(py, ptr) }.map(|obj| Self(py, ManuallyDrop::new(obj))) } /// Constructs a new `Bound<'py, PyAny>` from a pointer without checking for null. @@ -146,7 +149,10 @@ impl<'py> Bound<'py, PyAny> { py: Python<'py>, ptr: *mut ffi::PyObject, ) -> Self { - Self(py, ManuallyDrop::new(Py::from_owned_ptr_unchecked(ptr))) + Self( + py, + ManuallyDrop::new(unsafe { Py::from_owned_ptr_unchecked(ptr) }), + ) } /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference. @@ -158,7 +164,7 @@ impl<'py> Bound<'py, PyAny> { #[inline] #[track_caller] pub unsafe fn from_borrowed_ptr(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self { - Self(py, ManuallyDrop::new(Py::from_borrowed_ptr(py, ptr))) + unsafe { Self(py, ManuallyDrop::new(Py::from_borrowed_ptr(py, ptr))) } } /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference. @@ -172,7 +178,7 @@ impl<'py> Bound<'py, PyAny> { py: Python<'py>, ptr: *mut ffi::PyObject, ) -> Option { - Py::from_borrowed_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + unsafe { Py::from_borrowed_ptr_or_opt(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) } } /// Constructs a new `Bound<'py, PyAny>` from a pointer by creating a new Python reference. @@ -186,7 +192,7 @@ impl<'py> Bound<'py, PyAny> { py: Python<'py>, ptr: *mut ffi::PyObject, ) -> PyResult { - Py::from_borrowed_ptr_or_err(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) + unsafe { Py::from_borrowed_ptr_or_err(py, ptr).map(|obj| Self(py, ManuallyDrop::new(obj))) } } /// This slightly strange method is used to obtain `&Bound` from a pointer in macro code @@ -204,7 +210,7 @@ impl<'py> Bound<'py, PyAny> { _py: Python<'py>, ptr: &'a *mut ffi::PyObject, ) -> &'a Self { - &*ptr_from_ref(ptr).cast::>() + unsafe { &*ptr_from_ref(ptr).cast::>() } } /// Variant of the above which returns `None` for null pointers. @@ -216,7 +222,7 @@ impl<'py> Bound<'py, PyAny> { _py: Python<'py>, ptr: &'a *mut ffi::PyObject, ) -> &'a Option { - &*ptr_from_ref(ptr).cast::>>() + unsafe { &*ptr_from_ref(ptr).cast::>>() } } } @@ -762,7 +768,7 @@ impl<'a, 'py> Borrowed<'a, 'py, PyAny> { /// derived from is valid for the lifetime `'a`. #[inline] pub(crate) unsafe fn from_ptr_unchecked(py: Python<'py>, ptr: *mut ffi::PyObject) -> Self { - Self(NonNull::new_unchecked(ptr), PhantomData, py) + Self(unsafe { NonNull::new_unchecked(ptr) }, PhantomData, py) } #[inline] @@ -1675,7 +1681,7 @@ impl Py { /// /// - `ptr` must be a non-null pointer to a Python object or type `T`. pub(crate) unsafe fn from_owned_ptr_unchecked(ptr: *mut ffi::PyObject) -> Self { - Py(NonNull::new_unchecked(ptr), PhantomData) + Py(unsafe { NonNull::new_unchecked(ptr) }, PhantomData) } /// Create a `Py` instance by creating a new reference from the given FFI pointer. @@ -1688,7 +1694,7 @@ impl Py { #[inline] #[track_caller] pub unsafe fn from_borrowed_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py { - match Self::from_borrowed_ptr_or_opt(py, ptr) { + match unsafe { Self::from_borrowed_ptr_or_opt(py, ptr) } { Some(slf) => slf, None => crate::err::panic_after_error(py), } @@ -1705,7 +1711,7 @@ impl Py { py: Python<'_>, ptr: *mut ffi::PyObject, ) -> PyResult { - Self::from_borrowed_ptr_or_opt(py, ptr).ok_or_else(|| PyErr::fetch(py)) + unsafe { Self::from_borrowed_ptr_or_opt(py, ptr).ok_or_else(|| PyErr::fetch(py)) } } /// Create a `Py` instance by creating a new reference from the given FFI pointer. @@ -1719,10 +1725,12 @@ impl Py { _py: Python<'_>, ptr: *mut ffi::PyObject, ) -> Option { - NonNull::new(ptr).map(|nonnull_ptr| { - ffi::Py_INCREF(ptr); - Py(nonnull_ptr, PhantomData) - }) + unsafe { + NonNull::new(ptr).map(|nonnull_ptr| { + ffi::Py_INCREF(ptr); + Py(nonnull_ptr, PhantomData) + }) + } } /// For internal conversions. @@ -1985,7 +1993,7 @@ impl PyObject { /// Callers must ensure that the type is valid or risk type confusion. #[inline] pub unsafe fn downcast_bound_unchecked<'py, T>(&self, py: Python<'py>) -> &Bound<'py, T> { - self.bind(py).downcast_unchecked() + unsafe { self.bind(py).downcast_unchecked() } } } @@ -2069,9 +2077,10 @@ mod tests { Python::with_gil(|py| { let obj: PyObject = PyDict::new(py).into(); assert!(obj.call_method0(py, "asdf").is_err()); - assert!(obj - .call_method(py, "nonexistent_method", (1,), None) - .is_err()); + assert!( + obj.call_method(py, "nonexistent_method", (1,), None) + .is_err() + ); assert!(obj.call_method0(py, "nonexistent_method").is_err()); assert!(obj.call_method1(py, "nonexistent_method", (1,)).is_err()); }); @@ -2119,10 +2128,12 @@ a = A() instance.setattr(py, "foo", "bar")?; - assert!(instance - .getattr(py, "foo")? - .bind(py) - .eq(PyString::new(py, "bar"))?); + assert!( + instance + .getattr(py, "foo")? + .bind(py) + .eq(PyString::new(py, "bar"))? + ); instance.getattr(py, "foo")?; Ok(()) diff --git a/src/internal/get_slot.rs b/src/internal/get_slot.rs index 260893d4204..611644cb6bc 100644 --- a/src/internal/get_slot.rs +++ b/src/internal/get_slot.rs @@ -51,12 +51,14 @@ pub(crate) unsafe fn get_slot( where Slot: GetSlotImpl, { - slot.get_slot( - ty, - // SAFETY: the Python runtime is initialized - #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] - is_runtime_3_10(crate::Python::assume_gil_acquired()), - ) + unsafe { + slot.get_slot( + ty, + // SAFETY: the Python runtime is initialized + #[cfg(all(Py_LIMITED_API, not(Py_3_10)))] + is_runtime_3_10(crate::Python::assume_gil_acquired()), + ) + } } pub(crate) trait GetSlotImpl { @@ -93,7 +95,7 @@ macro_rules! impl_slots { ) -> Self::Type { #[cfg(not(Py_LIMITED_API))] { - (*ty).$field + unsafe {(*ty).$field } } #[cfg(Py_LIMITED_API)] @@ -105,14 +107,14 @@ macro_rules! impl_slots { // (3.7, 3.8, 3.9) and then look in the type object anyway. This is only ok // because we know that the interpreter is not going to change the size // of the type objects for these historical versions. - if !is_runtime_3_10 && ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE) == 0 + if !is_runtime_3_10 && unsafe {ffi::PyType_HasFeature(ty, ffi::Py_TPFLAGS_HEAPTYPE)} == 0 { - return (*ty.cast::()).$field; + return unsafe {(*ty.cast::()).$field}; } } // SAFETY: slot type is set carefully to be valid - std::mem::transmute(ffi::PyType_GetSlot(ty, ffi::$slot)) + unsafe {std::mem::transmute(ffi::PyType_GetSlot(ty, ffi::$slot))} } } } diff --git a/src/marker.rs b/src/marker.rs index f98a725da0e..4fe91464244 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -439,7 +439,7 @@ impl Python<'_> { where F: for<'py> FnOnce(Python<'py>) -> R, { - let guard = GILGuard::acquire_unchecked(); + let guard = unsafe { GILGuard::acquire_unchecked() }; f(guard.python()) } diff --git a/src/py_result_ext.rs b/src/py_result_ext.rs index 2ad079ed7ac..bcb152e7ef0 100644 --- a/src/py_result_ext.rs +++ b/src/py_result_ext.rs @@ -13,6 +13,6 @@ impl<'py> PyResultExt<'py> for PyResult> { #[inline] unsafe fn downcast_into_unchecked(self) -> PyResult> { - self.map(|instance| instance.downcast_into_unchecked()) + self.map(|instance| unsafe { instance.downcast_into_unchecked() }) } } diff --git a/src/pycell/impl_.rs b/src/pycell/impl_.rs index 1b1344f8aa8..42e60553c74 100644 --- a/src/pycell/impl_.rs +++ b/src/pycell/impl_.rs @@ -237,21 +237,21 @@ where // at runtime? To be investigated. let type_obj = T::type_object(py); let type_ptr = type_obj.as_type_ptr(); - let actual_type = PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(slf)); + let actual_type = unsafe { PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(slf)) }; // For `#[pyclass]` types which inherit from PyAny, we can just call tp_free if type_ptr == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type) { let tp_free = actual_type .get_slot(TP_FREE) .expect("PyBaseObject_Type should have tp_free"); - return tp_free(slf.cast()); + return unsafe { tp_free(slf.cast()) }; } // More complex native types (e.g. `extends=PyDict`) require calling the base's dealloc. #[cfg(not(Py_LIMITED_API))] { // FIXME: should this be using actual_type.tp_dealloc? - if let Some(dealloc) = (*type_ptr).tp_dealloc { + if let Some(dealloc) = unsafe { (*type_ptr).tp_dealloc } { // Before CPython 3.11 BaseException_dealloc would use Py_GC_UNTRACK which // assumes the exception is currently GC tracked, so we have to re-track // before calling the dealloc so that it can safely call Py_GC_UNTRACK. @@ -259,11 +259,13 @@ where if ffi::PyType_FastSubclass(type_ptr, ffi::Py_TPFLAGS_BASE_EXC_SUBCLASS) == 1 { ffi::PyObject_GC_Track(slf.cast()); } - dealloc(slf); + unsafe { dealloc(slf) }; } else { - (*actual_type.as_type_ptr()) - .tp_free - .expect("type missing tp_free")(slf.cast()); + unsafe { + (*actual_type.as_type_ptr()) + .tp_free + .expect("type missing tp_free")(slf.cast()) + }; } } @@ -343,13 +345,15 @@ where } unsafe fn tp_dealloc(py: Python<'_>, slf: *mut ffi::PyObject) { // Safety: Python only calls tp_dealloc when no references to the object remain. - let class_object = &mut *(slf.cast::>()); + let class_object = unsafe { &mut *(slf.cast::>()) }; if class_object.contents.thread_checker.can_drop(py) { - ManuallyDrop::drop(&mut class_object.contents.value); + unsafe { ManuallyDrop::drop(&mut class_object.contents.value) }; } class_object.contents.dict.clear_dict(py); - class_object.contents.weakref.clear_weakrefs(slf, py); - ::LayoutAsBase::tp_dealloc(py, slf) + unsafe { + class_object.contents.weakref.clear_weakrefs(slf, py); + ::LayoutAsBase::tp_dealloc(py, slf) + } } } diff --git a/src/pyclass/create_type_object.rs b/src/pyclass/create_type_object.rs index 8a02baa8ad1..918dedbbc8b 100644 --- a/src/pyclass/create_type_object.rs +++ b/src/pyclass/create_type_object.rs @@ -49,33 +49,35 @@ where module: Option<&'static str>, size_of: usize, ) -> PyResult { - PyTypeBuilder { - slots: Vec::new(), - method_defs: Vec::new(), - member_defs: Vec::new(), - getset_builders: HashMap::new(), - cleanup: Vec::new(), - tp_base: base, - tp_dealloc: dealloc, - tp_dealloc_with_gc: dealloc_with_gc, - is_mapping, - is_sequence, - has_new: false, - has_dealloc: false, - has_getitem: false, - has_setitem: false, - has_traverse: false, - has_clear: false, - dict_offset: None, - class_flags: 0, - #[cfg(all(not(Py_3_9), not(Py_LIMITED_API)))] - buffer_procs: Default::default(), + unsafe { + PyTypeBuilder { + slots: Vec::new(), + method_defs: Vec::new(), + member_defs: Vec::new(), + getset_builders: HashMap::new(), + cleanup: Vec::new(), + tp_base: base, + tp_dealloc: dealloc, + tp_dealloc_with_gc: dealloc_with_gc, + is_mapping, + is_sequence, + has_new: false, + has_dealloc: false, + has_getitem: false, + has_setitem: false, + has_traverse: false, + has_clear: false, + dict_offset: None, + class_flags: 0, + #[cfg(all(not(Py_3_9), not(Py_LIMITED_API)))] + buffer_procs: Default::default(), + } + .type_doc(doc) + .offsets(dict_offset, weaklist_offset) + .set_is_basetype(is_basetype) + .class_items(items_iter) + .build(py, name, module, size_of) } - .type_doc(doc) - .offsets(dict_offset, weaklist_offset) - .set_is_basetype(is_basetype) - .class_items(items_iter) - .build(py, name, module, size_of) } unsafe { @@ -167,8 +169,10 @@ impl PyTypeBuilder { unsafe fn push_raw_vec_slot(&mut self, slot: c_int, mut data: Vec) { if !data.is_empty() { // Python expects a zeroed entry to mark the end of the defs - data.push(std::mem::zeroed()); - self.push_slot(slot, Box::into_raw(data.into_boxed_slice()) as *mut c_void); + unsafe { + data.push(std::mem::zeroed()); + self.push_slot(slot, Box::into_raw(data.into_boxed_slice()) as *mut c_void); + } } } @@ -314,7 +318,7 @@ impl PyTypeBuilder { unsafe fn class_items(mut self, iter: PyClassItemsIter) -> Self { for items in iter { for slot in items.slots { - self.push_slot(slot.slot, slot.pfunc); + unsafe { self.push_slot(slot.slot, slot.pfunc) }; } for method in items.methods { let built_method; @@ -545,20 +549,22 @@ unsafe extern "C" fn no_constructor_defined( _args: *mut ffi::PyObject, _kwds: *mut ffi::PyObject, ) -> *mut ffi::PyObject { - trampoline(|py| { - let tpobj = PyType::from_borrowed_type_ptr(py, subtype); - let name = tpobj - .name() - .map_or_else(|_| "".into(), |name| name.to_string()); - Err(crate::exceptions::PyTypeError::new_err(format!( - "No constructor defined for {}", - name - ))) - }) + unsafe { + trampoline(|py| { + let tpobj = PyType::from_borrowed_type_ptr(py, subtype); + let name = tpobj + .name() + .map_or_else(|_| "".into(), |name| name.to_string()); + Err(crate::exceptions::PyTypeError::new_err(format!( + "No constructor defined for {}", + name + ))) + }) + } } unsafe extern "C" fn call_super_clear(slf: *mut ffi::PyObject) -> c_int { - _call_clear(slf, |_, _| Ok(()), call_super_clear) + unsafe { _call_clear(slf, |_, _| Ok(()), call_super_clear) } } #[derive(Default)] @@ -643,8 +649,8 @@ impl GetSetDefType { closure: *mut c_void, ) -> *mut ffi::PyObject { // Safety: PyO3 sets the closure when constructing the ffi getter so this cast should always be valid - let getter: Getter = std::mem::transmute(closure); - trampoline(|py| getter(py, slf)) + let getter: Getter = unsafe { std::mem::transmute(closure) }; + unsafe { trampoline(|py| getter(py, slf)) } } (Some(getter), None, closure as Getter as _) } @@ -655,8 +661,8 @@ impl GetSetDefType { closure: *mut c_void, ) -> c_int { // Safety: PyO3 sets the closure when constructing the ffi setter so this cast should always be valid - let setter: Setter = std::mem::transmute(closure); - trampoline(|py| setter(py, slf, value)) + let setter: Setter = unsafe { std::mem::transmute(closure) }; + unsafe { trampoline(|py| setter(py, slf, value)) } } (None, Some(setter), closure as Setter as _) } @@ -665,8 +671,8 @@ impl GetSetDefType { slf: *mut ffi::PyObject, closure: *mut c_void, ) -> *mut ffi::PyObject { - let getset: &GetterAndSetter = &*closure.cast(); - trampoline(|py| (getset.getter)(py, slf)) + let getset: &GetterAndSetter = unsafe { &*closure.cast() }; + unsafe { trampoline(|py| (getset.getter)(py, slf)) } } unsafe extern "C" fn getset_setter( @@ -674,8 +680,8 @@ impl GetSetDefType { value: *mut ffi::PyObject, closure: *mut c_void, ) -> c_int { - let getset: &GetterAndSetter = &*closure.cast(); - trampoline(|py| (getset.setter)(py, slf, value)) + let getset: &GetterAndSetter = unsafe { &*closure.cast() }; + unsafe { trampoline(|py| (getset.setter)(py, slf, value)) } } ( Some(getset_getter), diff --git a/src/pyclass_init.rs b/src/pyclass_init.rs index 6dc6ec12c6b..3a3253fffbc 100644 --- a/src/pyclass_init.rs +++ b/src/pyclass_init.rs @@ -178,23 +178,25 @@ impl PyClassInitializer { PyClassInitializerImpl::New { init, super_init } => (init, super_init), }; - let obj = super_init.into_new_object(py, target_type)?; + let obj = unsafe { super_init.into_new_object(py, target_type)? }; let part_init: *mut PartiallyInitializedClassObject = obj.cast(); - std::ptr::write( - (*part_init).contents.as_mut_ptr(), - PyClassObjectContents { - value: ManuallyDrop::new(UnsafeCell::new(init)), - borrow_checker: ::Storage::new(), - thread_checker: T::ThreadChecker::new(), - dict: T::Dict::INIT, - weakref: T::WeakRef::INIT, - }, - ); + unsafe { + std::ptr::write( + (*part_init).contents.as_mut_ptr(), + PyClassObjectContents { + value: ManuallyDrop::new(UnsafeCell::new(init)), + borrow_checker: ::Storage::new(), + thread_checker: T::ThreadChecker::new(), + dict: T::Dict::INIT, + weakref: T::WeakRef::INIT, + }, + ); + } // Safety: obj is a valid pointer to an object of type `target_type`, which` is a known // subclass of `T` - Ok(obj.assume_owned(py).downcast_into_unchecked()) + Ok(unsafe { obj.assume_owned(py).downcast_into_unchecked() }) } } @@ -204,8 +206,10 @@ impl PyObjectInit for PyClassInitializer { py: Python<'_>, subtype: *mut PyTypeObject, ) -> PyResult<*mut ffi::PyObject> { - self.create_class_object_of_type(py, subtype) - .map(Bound::into_ptr) + unsafe { + self.create_class_object_of_type(py, subtype) + .map(Bound::into_ptr) + } } #[inline] diff --git a/src/types/any.rs b/src/types/any.rs index 0725453e569..5f0b4691a89 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -1430,12 +1430,12 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { #[inline] unsafe fn downcast_unchecked(&self) -> &Bound<'py, T> { - &*ptr_from_ref(self).cast() + unsafe { &*ptr_from_ref(self).cast() } } #[inline] unsafe fn downcast_into_unchecked(self) -> Bound<'py, T> { - std::mem::transmute(self) + unsafe { std::mem::transmute(self) } } fn extract<'a, T>(&'a self) -> PyResult diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index d1bbd0ac7e4..094cdf3144b 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -286,12 +286,12 @@ impl<'py> PyByteArrayMethods<'py> for Bound<'py, PyByteArray> { } unsafe fn as_bytes(&self) -> &[u8] { - self.as_borrowed().as_bytes() + unsafe { self.as_borrowed().as_bytes() } } #[allow(clippy::mut_from_ref)] unsafe fn as_bytes_mut(&self) -> &mut [u8] { - self.as_borrowed().as_bytes_mut() + unsafe { self.as_borrowed().as_bytes_mut() } } fn to_vec(&self) -> Vec { @@ -317,12 +317,12 @@ impl<'a> Borrowed<'a, '_, PyByteArray> { #[allow(clippy::wrong_self_convention)] unsafe fn as_bytes(self) -> &'a [u8] { - slice::from_raw_parts(self.data(), self.len()) + unsafe { slice::from_raw_parts(self.data(), self.len()) } } #[allow(clippy::wrong_self_convention)] unsafe fn as_bytes_mut(self) -> &'a mut [u8] { - slice::from_raw_parts_mut(self.data(), self.len()) + unsafe { slice::from_raw_parts_mut(self.data(), self.len()) } } } diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 77b1d2b735d..a820ece3b45 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -135,9 +135,11 @@ impl PyBytes { /// `std::slice::from_raw_parts`, this is /// unsafe](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety). pub unsafe fn from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> { - ffi::PyBytes_FromStringAndSize(ptr.cast(), len as isize) - .assume_owned(py) - .downcast_into_unchecked() + unsafe { + ffi::PyBytes_FromStringAndSize(ptr.cast(), len as isize) + .assume_owned(py) + .downcast_into_unchecked() + } } /// Deprecated name for [`PyBytes::from_ptr`]. @@ -151,7 +153,7 @@ impl PyBytes { #[deprecated(since = "0.23.0", note = "renamed to `PyBytes::from_ptr`")] #[inline] pub unsafe fn bound_from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> { - Self::from_ptr(py, ptr, len) + unsafe { Self::from_ptr(py, ptr, len) } } } diff --git a/src/types/capsule.rs b/src/types/capsule.rs index 9d9e6e4eb72..5f97aeda5c5 100644 --- a/src/types/capsule.rs +++ b/src/types/capsule.rs @@ -163,11 +163,11 @@ impl PyCapsule { /// /// It must be known that the capsule imported by `name` contains an item of type `T`. pub unsafe fn import<'py, T>(py: Python<'py>, name: &CStr) -> PyResult<&'py T> { - let ptr = ffi::PyCapsule_Import(name.as_ptr(), false as c_int); + let ptr = unsafe { ffi::PyCapsule_Import(name.as_ptr(), false as c_int) }; if ptr.is_null() { Err(PyErr::fetch(py)) } else { - Ok(&*ptr.cast::()) + Ok(unsafe { &*ptr.cast::() }) } } } @@ -267,7 +267,7 @@ impl<'py> PyCapsuleMethods<'py> for Bound<'py, PyCapsule> { } unsafe fn reference(&self) -> &'py T { - &*self.pointer().cast() + unsafe { &*self.pointer().cast() } } fn pointer(&self) -> *mut c_void { @@ -316,12 +316,14 @@ struct CapsuleContents { unsafe extern "C" fn capsule_destructor( capsule: *mut ffi::PyObject, ) { - let ptr = ffi::PyCapsule_GetPointer(capsule, ffi::PyCapsule_GetName(capsule)); - let ctx = ffi::PyCapsule_GetContext(capsule); - let CapsuleContents { - value, destructor, .. - } = *Box::from_raw(ptr.cast::>()); - destructor(value, ctx) + unsafe { + let ptr = ffi::PyCapsule_GetPointer(capsule, ffi::PyCapsule_GetName(capsule)); + let ctx = ffi::PyCapsule_GetContext(capsule); + let CapsuleContents { + value, destructor, .. + } = *Box::from_raw(ptr.cast::>()); + destructor(value, ctx) + } } /// Guarantee `T` is not zero sized at compile time. diff --git a/src/types/datetime.rs b/src/types/datetime.rs index e091ace2591..0b0a7324c4b 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -68,8 +68,8 @@ macro_rules! ffi_fun_with_autoinit { /// Must only be called while the GIL is held unsafe fn $name($arg: *mut crate::ffi::PyObject) -> $ret { - let _ = ensure_datetime_api(Python::assume_gil_acquired()); - crate::ffi::$name($arg) + let _ = ensure_datetime_api(unsafe { Python::assume_gil_acquired() }); + unsafe { crate::ffi::$name($arg) } } )* diff --git a/src/types/function.rs b/src/types/function.rs index 039e2774546..2f4da950b0a 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -189,22 +189,24 @@ where { use crate::types::any::PyAnyMethods; - crate::impl_::trampoline::cfunction_with_keywords( - capsule_ptr, - args, - kwargs, - |py, capsule_ptr, args, kwargs| { - let boxed_fn: &ClosureDestructor = - &*(ffi::PyCapsule_GetPointer(capsule_ptr, CLOSURE_CAPSULE_NAME.as_ptr()) - as *mut ClosureDestructor); - let args = Bound::ref_from_ptr(py, &args).downcast_unchecked::(); - let kwargs = Bound::ref_from_ptr_or_opt(py, &kwargs) - .as_ref() - .map(|b| b.downcast_unchecked::()); - let result = (boxed_fn.closure)(args, kwargs); - crate::impl_::callback::convert(py, result) - }, - ) + unsafe { + crate::impl_::trampoline::cfunction_with_keywords( + capsule_ptr, + args, + kwargs, + |py, capsule_ptr, args, kwargs| { + let boxed_fn: &ClosureDestructor = + &*(ffi::PyCapsule_GetPointer(capsule_ptr, CLOSURE_CAPSULE_NAME.as_ptr()) + as *mut ClosureDestructor); + let args = Bound::ref_from_ptr(py, &args).downcast_unchecked::(); + let kwargs = Bound::ref_from_ptr_or_opt(py, &kwargs) + .as_ref() + .map(|b| b.downcast_unchecked::()); + let result = (boxed_fn.closure)(args, kwargs); + crate::impl_::callback::convert(py, result) + }, + ) + } } struct ClosureDestructor { diff --git a/src/types/list.rs b/src/types/list.rs index ead22315f05..bd770aaeca7 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -318,9 +318,11 @@ impl<'py> PyListMethods<'py> for Bound<'py, PyList> { #[cfg(not(Py_LIMITED_API))] unsafe fn get_item_unchecked(&self, index: usize) -> Bound<'py, PyAny> { // PyList_GET_ITEM return borrowed ptr; must make owned for safety (see #890). - ffi::PyList_GET_ITEM(self.as_ptr(), index as Py_ssize_t) - .assume_borrowed(self.py()) - .to_owned() + unsafe { + ffi::PyList_GET_ITEM(self.as_ptr(), index as Py_ssize_t) + .assume_borrowed(self.py()) + .to_owned() + } } /// Takes the slice `self[low:high]` and returns it as a new list. diff --git a/src/types/mappingproxy.rs b/src/types/mappingproxy.rs index 5a0b1537cb0..436a52dc3e9 100644 --- a/src/types/mappingproxy.rs +++ b/src/types/mappingproxy.rs @@ -16,7 +16,7 @@ pub struct PyMappingProxy(PyAny); #[inline] unsafe fn dict_proxy_check(op: *mut ffi::PyObject) -> c_int { - ffi::Py_IS_TYPE(op, std::ptr::addr_of_mut!(ffi::PyDictProxy_Type)) + unsafe { ffi::Py_IS_TYPE(op, std::ptr::addr_of_mut!(ffi::PyDictProxy_Type)) } } pyobject_native_type_core!( diff --git a/src/types/string.rs b/src/types/string.rs index 65a9e85fa3e..ad30dba02d6 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -310,7 +310,7 @@ impl<'py> PyStringMethods<'py> for Bound<'py, PyString> { #[cfg(not(any(Py_LIMITED_API, GraalPy, PyPy)))] unsafe fn data(&self) -> PyResult> { - self.as_borrowed().data() + unsafe { self.as_borrowed().data() } } } @@ -388,24 +388,26 @@ impl<'a> Borrowed<'a, '_, PyString> { // The string should be in its canonical form after calling `PyUnicode_READY()`. // And non-canonical form not possible after Python 3.12. So it should be safe // to call these APIs. - let length = ffi::PyUnicode_GET_LENGTH(ptr) as usize; - let raw_data = ffi::PyUnicode_DATA(ptr); - let kind = ffi::PyUnicode_KIND(ptr); - - match kind { - ffi::PyUnicode_1BYTE_KIND => Ok(PyStringData::Ucs1(std::slice::from_raw_parts( - raw_data as *const u8, - length, - ))), - ffi::PyUnicode_2BYTE_KIND => Ok(PyStringData::Ucs2(std::slice::from_raw_parts( - raw_data as *const u16, - length, - ))), - ffi::PyUnicode_4BYTE_KIND => Ok(PyStringData::Ucs4(std::slice::from_raw_parts( - raw_data as *const u32, - length, - ))), - _ => unreachable!(), + unsafe { + let length = ffi::PyUnicode_GET_LENGTH(ptr) as usize; + let raw_data = ffi::PyUnicode_DATA(ptr); + let kind = ffi::PyUnicode_KIND(ptr); + + match kind { + ffi::PyUnicode_1BYTE_KIND => Ok(PyStringData::Ucs1(std::slice::from_raw_parts( + raw_data as *const u8, + length, + ))), + ffi::PyUnicode_2BYTE_KIND => Ok(PyStringData::Ucs2(std::slice::from_raw_parts( + raw_data as *const u16, + length, + ))), + ffi::PyUnicode_4BYTE_KIND => Ok(PyStringData::Ucs4(std::slice::from_raw_parts( + raw_data as *const u32, + length, + ))), + _ => unreachable!(), + } } } } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 81a7ad911e9..a35f5805c15 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -272,12 +272,12 @@ impl<'py> PyTupleMethods<'py> for Bound<'py, PyTuple> { #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] unsafe fn get_item_unchecked(&self, index: usize) -> Bound<'py, PyAny> { - self.get_borrowed_item_unchecked(index).to_owned() + unsafe { self.get_borrowed_item_unchecked(index).to_owned() } } #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] unsafe fn get_borrowed_item_unchecked<'a>(&'a self, index: usize) -> Borrowed<'a, 'py, PyAny> { - self.as_borrowed().get_borrowed_item_unchecked(index) + unsafe { self.as_borrowed().get_borrowed_item_unchecked(index) } } #[cfg(not(any(Py_LIMITED_API, GraalPy)))] @@ -329,7 +329,9 @@ impl<'a, 'py> Borrowed<'a, 'py, PyTuple> { #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] unsafe fn get_borrowed_item_unchecked(self, index: usize) -> Borrowed<'a, 'py, PyAny> { - ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t).assume_borrowed(self.py()) + unsafe { + ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t).assume_borrowed(self.py()) + } } pub(crate) fn iter_borrowed(self) -> BorrowedTupleIterator<'a, 'py> { @@ -540,7 +542,7 @@ impl<'a, 'py> BorrowedTupleIterator<'a, 'py> { #[cfg(any(Py_LIMITED_API, PyPy, GraalPy))] let item = tuple.get_borrowed_item(index).expect("tuple.get failed"); #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] - let item = tuple.get_borrowed_item_unchecked(index); + let item = unsafe { tuple.get_borrowed_item_unchecked(index) }; item } } diff --git a/src/types/typeobject.rs b/src/types/typeobject.rs index 7a66b7ad0df..7ab3690b90b 100644 --- a/src/types/typeobject.rs +++ b/src/types/typeobject.rs @@ -46,9 +46,11 @@ impl PyType { py: Python<'_>, p: *mut ffi::PyTypeObject, ) -> Bound<'_, PyType> { - Borrowed::from_ptr_unchecked(py, p.cast()) - .downcast_unchecked() - .to_owned() + unsafe { + Borrowed::from_ptr_unchecked(py, p.cast()) + .downcast_unchecked() + .to_owned() + } } } diff --git a/src/types/weakref/anyref.rs b/src/types/weakref/anyref.rs index d5af956ac9e..741a638c295 100644 --- a/src/types/weakref/anyref.rs +++ b/src/types/weakref/anyref.rs @@ -181,7 +181,7 @@ pub trait PyWeakrefMethods<'py>: crate::sealed::Sealed { /// [`weakref.ReferenceType`]: https://docs.python.org/3/library/weakref.html#weakref.ReferenceType /// [`weakref.ref`]: https://docs.python.org/3/library/weakref.html#weakref.ref unsafe fn upgrade_as_unchecked(&self) -> Option> { - Some(self.upgrade()?.downcast_into_unchecked()) + Some(unsafe { self.upgrade()?.downcast_into_unchecked() }) } /// Upgrade the weakref to a exact direct Bound object reference. From a96a1b8f4dfcdad6e93beb141790f4d1f6097356 Mon Sep 17 00:00:00 2001 From: Jonas Pleyer Date: Thu, 13 Mar 2025 19:47:42 +0100 Subject: [PATCH 02/13] mark unsafe function calls in tests as well --- tests/test_buffer.rs | 68 ++++++++++++++++++----------------- tests/test_buffer_protocol.rs | 67 +++++++++++++++++----------------- tests/test_gc.rs | 2 +- tests/test_pyfunction.rs | 32 +++++++++-------- 4 files changed, 87 insertions(+), 82 deletions(-) diff --git a/tests/test_buffer.rs b/tests/test_buffer.rs index 60db80b81c8..5da434ec581 100644 --- a/tests/test_buffer.rs +++ b/tests/test_buffer.rs @@ -42,42 +42,44 @@ impl TestBufferErrors { let bytes = &slf.buf; - (*view).buf = bytes.as_ptr() as *mut c_void; - (*view).len = bytes.len() as isize; - (*view).readonly = 1; - (*view).itemsize = std::mem::size_of::() as isize; - - let msg = ffi::c_str!("I"); - (*view).format = msg.as_ptr() as *mut _; - - (*view).ndim = 1; - (*view).shape = &mut (*view).len; - - (*view).strides = &mut (*view).itemsize; - - (*view).suboffsets = ptr::null_mut(); - (*view).internal = ptr::null_mut(); - - if let Some(err) = &slf.error { - use TestGetBufferError::*; - match err { - NullShape => { - (*view).shape = std::ptr::null_mut(); + unsafe { + (*view).buf = bytes.as_ptr() as *mut c_void; + (*view).len = bytes.len() as isize; + (*view).readonly = 1; + (*view).itemsize = std::mem::size_of::() as isize; + + let msg = ffi::c_str!("I"); + (*view).format = msg.as_ptr() as *mut _; + + (*view).ndim = 1; + (*view).shape = &mut (*view).len; + + (*view).strides = &mut (*view).itemsize; + + (*view).suboffsets = ptr::null_mut(); + (*view).internal = ptr::null_mut(); + + if let Some(err) = &slf.error { + use TestGetBufferError::*; + match err { + NullShape => { + (*view).shape = std::ptr::null_mut(); + } + NullStrides => { + (*view).strides = std::ptr::null_mut(); + } + IncorrectItemSize => { + (*view).itemsize += 1; + } + IncorrectFormat => { + (*view).format = ffi::c_str!("B").as_ptr() as _; + } + IncorrectAlignment => (*view).buf = (*view).buf.add(1), } - NullStrides => { - (*view).strides = std::ptr::null_mut(); - } - IncorrectItemSize => { - (*view).itemsize += 1; - } - IncorrectFormat => { - (*view).format = ffi::c_str!("B").as_ptr() as _; - } - IncorrectAlignment => (*view).buf = (*view).buf.add(1), } - } - (*view).obj = slf.into_ptr(); + (*view).obj = slf.into_ptr(); + } Ok(()) } diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index 1f15e34b384..b3b2144cc32 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -28,12 +28,12 @@ impl TestBufferClass { view: *mut ffi::Py_buffer, flags: c_int, ) -> PyResult<()> { - fill_view_from_readonly_data(view, flags, &slf.borrow().vec, slf.into_any()) + unsafe { fill_view_from_readonly_data(view, flags, &slf.borrow().vec, slf.into_any()) } } unsafe fn __releasebuffer__(&self, view: *mut ffi::Py_buffer) { // Release memory held by the format string - drop(CString::from_raw((*view).format)); + drop(unsafe { CString::from_raw((*view).format) }); } } @@ -111,7 +111,7 @@ fn test_releasebuffer_unraisable_error() { flags: c_int, ) -> PyResult<()> { static BUF_BYTES: &[u8] = b"hello world"; - fill_view_from_readonly_data(view, flags, BUF_BYTES, slf.into_any()) + unsafe { fill_view_from_readonly_data(view, flags, BUF_BYTES, slf.into_any()) } } unsafe fn __releasebuffer__(&self, _view: *mut ffi::Py_buffer) -> PyResult<()> { @@ -156,35 +156,36 @@ unsafe fn fill_view_from_readonly_data( return Err(PyBufferError::new_err("Object is not writable")); } - (*view).obj = owner.into_ptr(); - - (*view).buf = data.as_ptr() as *mut c_void; - (*view).len = data.len() as isize; - (*view).readonly = 1; - (*view).itemsize = 1; - - (*view).format = if (flags & ffi::PyBUF_FORMAT) == ffi::PyBUF_FORMAT { - let msg = CString::new("B").unwrap(); - msg.into_raw() - } else { - ptr::null_mut() - }; - - (*view).ndim = 1; - (*view).shape = if (flags & ffi::PyBUF_ND) == ffi::PyBUF_ND { - &mut (*view).len - } else { - ptr::null_mut() - }; - - (*view).strides = if (flags & ffi::PyBUF_STRIDES) == ffi::PyBUF_STRIDES { - &mut (*view).itemsize - } else { - ptr::null_mut() - }; - - (*view).suboffsets = ptr::null_mut(); - (*view).internal = ptr::null_mut(); - + unsafe { + (*view).obj = owner.into_ptr(); + + (*view).buf = data.as_ptr() as *mut c_void; + (*view).len = data.len() as isize; + (*view).readonly = 1; + (*view).itemsize = 1; + + (*view).format = if (flags & ffi::PyBUF_FORMAT) == ffi::PyBUF_FORMAT { + let msg = CString::new("B").unwrap(); + msg.into_raw() + } else { + ptr::null_mut() + }; + + (*view).ndim = 1; + (*view).shape = if (flags & ffi::PyBUF_ND) == ffi::PyBUF_ND { + &mut (*view).len + } else { + ptr::null_mut() + }; + + (*view).strides = if (flags & ffi::PyBUF_STRIDES) == ffi::PyBUF_STRIDES { + &mut (*view).itemsize + } else { + ptr::null_mut() + }; + + (*view).suboffsets = ptr::null_mut(); + (*view).internal = ptr::null_mut(); + } Ok(()) } diff --git a/tests/test_gc.rs b/tests/test_gc.rs index a88b9a21f91..234481962d4 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -720,7 +720,7 @@ fn test_traverse_subclass_override_clear() { // Manual traversal utilities unsafe fn get_type_traverse(tp: *mut pyo3::ffi::PyTypeObject) -> Option { - std::mem::transmute(pyo3::ffi::PyType_GetSlot(tp, pyo3::ffi::Py_tp_traverse)) + unsafe { std::mem::transmute(pyo3::ffi::PyType_GetSlot(tp, pyo3::ffi::Py_tp_traverse)) } } // a dummy visitor function diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 4e3bdce9e05..03bc096519e 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -339,7 +339,7 @@ fn test_pycfunction_new() { _self: *mut ffi::PyObject, _args: *mut ffi::PyObject, ) -> *mut ffi::PyObject { - ffi::PyLong_FromLong(4200) + unsafe { ffi::PyLong_FromLong(4200) } } let py_fn = PyCFunction::new( @@ -389,24 +389,26 @@ fn test_pycfunction_new_with_keywords() { ptr::null_mut(), ]; - ffi::PyArg_ParseTupleAndKeywords( - args, - kwds, - c_str!("l|l").as_ptr(), - #[cfg(Py_3_13)] - args_names.as_ptr(), - #[cfg(not(Py_3_13))] - args_names.as_mut_ptr(), - &mut foo, - &mut bar, - ); + unsafe { + ffi::PyArg_ParseTupleAndKeywords( + args, + kwds, + c_str!("l|l").as_ptr(), + #[cfg(Py_3_13)] + args_names.as_ptr(), + #[cfg(not(Py_3_13))] + args_names.as_mut_ptr(), + &mut foo, + &mut bar, + ) + }; #[cfg(not(Py_3_13))] - drop(std::ffi::CString::from_raw(args_names[0])); + drop(unsafe { std::ffi::CString::from_raw(args_names[0]) }); #[cfg(not(Py_3_13))] - drop(std::ffi::CString::from_raw(args_names[1])); + drop(unsafe { std::ffi::CString::from_raw(args_names[1]) }); - ffi::PyLong_FromLong(foo * bar) + unsafe { ffi::PyLong_FromLong(foo * bar) } } let py_fn = PyCFunction::new_with_keywords( From d38019b9f80fd7c8cbad9a0fc1b19257a1667551 Mon Sep 17 00:00:00 2001 From: Jonas Pleyer Date: Thu, 13 Mar 2025 23:10:00 +0100 Subject: [PATCH 03/13] add workspace lints to enhance migration to 2024 edition --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 315c1f622ea..997ca78cdfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -167,6 +167,8 @@ todo = "warn" unnecessary_wraps = "warn" useless_transmute = "warn" used_underscore_binding = "warn" +missing_unsafe_on_extern = "warn" +unsafe_op_in_unsafe_fn = "warn" [workspace.lints.rust] elided_lifetimes_in_paths = "warn" From 140d15edfbc46ac390173ec8191d8cb7ad99adf6 Mon Sep 17 00:00:00 2001 From: Jonas Pleyer Date: Mon, 17 Mar 2025 13:44:00 +0100 Subject: [PATCH 04/13] formatting --- src/instance.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index 6c85d20beb0..7a32f4c9c30 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2077,10 +2077,9 @@ mod tests { Python::with_gil(|py| { let obj: PyObject = PyDict::new(py).into(); assert!(obj.call_method0(py, "asdf").is_err()); - assert!( - obj.call_method(py, "nonexistent_method", (1,), None) - .is_err() - ); + assert!(obj + .call_method(py, "nonexistent_method", (1,), None) + .is_err()); assert!(obj.call_method0(py, "nonexistent_method").is_err()); assert!(obj.call_method1(py, "nonexistent_method", (1,)).is_err()); }); @@ -2128,12 +2127,10 @@ a = A() instance.setattr(py, "foo", "bar")?; - assert!( - instance - .getattr(py, "foo")? - .bind(py) - .eq(PyString::new(py, "bar"))? - ); + assert!(instance + .getattr(py, "foo")? + .bind(py) + .eq(PyString::new(py, "bar"))?); instance.getattr(py, "foo")?; Ok(()) From 7f601f041d6902bcc5bdc4d9b530c57fc99d21a1 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Mon, 17 Mar 2025 21:45:08 +0000 Subject: [PATCH 05/13] Apply suggestions from code review --- pyo3-ffi/src/abstract_.rs | 2 +- pyo3-ffi/src/pystate.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyo3-ffi/src/abstract_.rs b/pyo3-ffi/src/abstract_.rs index 90105e85921..1c27d102be8 100644 --- a/pyo3-ffi/src/abstract_.rs +++ b/pyo3-ffi/src/abstract_.rs @@ -83,7 +83,7 @@ extern "C" { pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = 1 << (8 * std::mem::size_of::() as size_t - 1); -unsafe extern "C" { +extern "C" { #[cfg_attr(PyPy, link_name = "PyPyObject_Vectorcall")] #[cfg(any(Py_3_12, all(Py_3_11, not(Py_LIMITED_API))))] pub fn PyObject_Vectorcall( diff --git a/pyo3-ffi/src/pystate.rs b/pyo3-ffi/src/pystate.rs index dd833cbabff..dab802094d5 100644 --- a/pyo3-ffi/src/pystate.rs +++ b/pyo3-ffi/src/pystate.rs @@ -67,7 +67,7 @@ extern "C" { // skipped non-limited / 3.9 PyThreadState_GetInterpreter // skipped non-limited / 3.9 PyThreadState_GetID -unsafe extern "C" { +extern "C" { // PyThreadState_GetFrame #[cfg(all(Py_3_10, not(PyPy), not(Py_LIMITED_API)))] pub fn PyThreadState_GetFrame(arg1: *mut PyThreadState) -> *mut PyFrameObject; From 63ea58858adc13d7312fbe5e79664a27bf6d0085 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 17:04:36 +0000 Subject: [PATCH 06/13] add feature to control warnings on MSRV --- pyo3-build-config/src/lib.rs | 59 ++++++++++++++---------------------- pyo3-ffi/src/lib.rs | 1 + src/lib.rs | 2 ++ 3 files changed, 25 insertions(+), 37 deletions(-) diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs index a908fe88068..68d597a8f2e 100644 --- a/pyo3-build-config/src/lib.rs +++ b/pyo3-build-config/src/lib.rs @@ -168,44 +168,36 @@ fn resolve_cross_compile_config_path() -> Option { }) } +/// Helper to print a feature cfg with a minimum rust version required. +fn print_feature_cfg(minor_version_required: u32, cfg: &str) { + let minor_version = rustc_minor_version().unwrap_or(0); + + if minor_version >= minor_version_required { + println!("cargo:rustc-cfg={}", cfg); + } + + // rustc 1.80.0 stabilized `rustc-check-cfg` feature, don't emit before + if minor_version >= 80 { + println!("cargo:rustc-check-cfg=cfg({})", cfg); + } +} + /// Use certain features if we detect the compiler being used supports them. /// /// Features may be removed or added as MSRV gets bumped or new features become available, /// so this function is unstable. #[doc(hidden)] pub fn print_feature_cfgs() { - let rustc_minor_version = rustc_minor_version().unwrap_or(0); - - if rustc_minor_version >= 70 { - println!("cargo:rustc-cfg=rustc_has_once_lock"); - } - - if rustc_minor_version >= 71 { - println!("cargo:rustc-cfg=rustc_has_extern_c_unwind"); - } - - // invalid_from_utf8 lint was added in Rust 1.74 - if rustc_minor_version >= 74 { - println!("cargo:rustc-cfg=invalid_from_utf8_lint"); - } - - if rustc_minor_version >= 79 { - println!("cargo:rustc-cfg=c_str_lit"); - } - + print_feature_cfg(70, "rustc_has_once_lock"); + print_feature_cfg(70, "cargo_toml_lints"); + print_feature_cfg(71, "rustc_has_extern_c_unwind"); + print_feature_cfg(74, "invalid_from_utf8_lint"); + print_feature_cfg(79, "c_str_lit"); // Actually this is available on 1.78, but we should avoid // https://github.com/rust-lang/rust/issues/124651 just in case - if rustc_minor_version >= 79 { - println!("cargo:rustc-cfg=diagnostic_namespace"); - } - - if rustc_minor_version >= 83 { - println!("cargo:rustc-cfg=io_error_more"); - } - - if rustc_minor_version >= 85 { - println!("cargo:rustc-cfg=fn_ptr_eq"); - } + print_feature_cfg(79, "diagnostic_namespace"); + print_feature_cfg(83, "io_error_more"); + print_feature_cfg(85, "fn_ptr_eq"); } /// Registers `pyo3`s config names as reachable cfg expressions @@ -224,15 +216,8 @@ pub fn print_expected_cfgs() { println!("cargo:rustc-check-cfg=cfg(PyPy)"); println!("cargo:rustc-check-cfg=cfg(GraalPy)"); println!("cargo:rustc-check-cfg=cfg(py_sys_config, values(\"Py_DEBUG\", \"Py_REF_DEBUG\", \"Py_TRACE_REFS\", \"COUNT_ALLOCS\"))"); - println!("cargo:rustc-check-cfg=cfg(invalid_from_utf8_lint)"); println!("cargo:rustc-check-cfg=cfg(pyo3_disable_reference_pool)"); println!("cargo:rustc-check-cfg=cfg(pyo3_leak_on_drop_without_reference_pool)"); - println!("cargo:rustc-check-cfg=cfg(diagnostic_namespace)"); - println!("cargo:rustc-check-cfg=cfg(c_str_lit)"); - println!("cargo:rustc-check-cfg=cfg(rustc_has_once_lock)"); - println!("cargo:rustc-check-cfg=cfg(rustc_has_extern_c_unwind)"); - println!("cargo:rustc-check-cfg=cfg(io_error_more)"); - println!("cargo:rustc-check-cfg=cfg(fn_ptr_eq)"); // allow `Py_3_*` cfgs from the minimum supported version up to the // maximum minor version (+1 for development for the next) diff --git a/pyo3-ffi/src/lib.rs b/pyo3-ffi/src/lib.rs index bb0d0ad040b..8218d4f83c4 100644 --- a/pyo3-ffi/src/lib.rs +++ b/pyo3-ffi/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] // necessary for MSRV 1.63 to build //! Raw FFI declarations for Python's C API. //! //! PyO3 can be used to write native Python modules or run Python code and modules from Rust. diff --git a/src/lib.rs b/src/lib.rs index 2a0c289204c..863fd010ade 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,8 @@ feature(auto_traits, negative_impls, try_trait_v2, iter_advance_by) )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] +// necessary for MSRV 1.63 to build // Deny some lints in doctests. // Use `#[allow(...)]` locally to override. #![doc(test(attr( From aef96e05de43616df9e7eb7d4d9318d7c36cb46a Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 18:05:17 +0000 Subject: [PATCH 07/13] fix configuration of workspace lints --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 06d67ae5ce4..84c6daba30e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,8 +168,6 @@ todo = "warn" unnecessary_wraps = "warn" useless_transmute = "warn" used_underscore_binding = "warn" -missing_unsafe_on_extern = "warn" -unsafe_op_in_unsafe_fn = "warn" [workspace.lints.rust] elided_lifetimes_in_paths = "warn" @@ -177,6 +175,7 @@ invalid_doc_attributes = "warn" rust_2018_idioms = { level = "warn", priority = -1 } rust_2021_prelude_collisions = "warn" unused_lifetimes = "warn" +unsafe_op_in_unsafe_fn = "warn" [workspace.lints.rustdoc] broken_intra_doc_links = "warn" From d1f65de69fdcf9ca62ee438776a038044316f393 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 18:10:05 +0000 Subject: [PATCH 08/13] another run of `cargo fix --lib -p pyo3-ffi` --- pyo3-ffi/src/abstract_.rs | 8 ++++---- pyo3-ffi/src/object.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pyo3-ffi/src/abstract_.rs b/pyo3-ffi/src/abstract_.rs index 1c27d102be8..311d0e5b518 100644 --- a/pyo3-ffi/src/abstract_.rs +++ b/pyo3-ffi/src/abstract_.rs @@ -6,7 +6,7 @@ use std::os::raw::{c_char, c_int}; #[inline] #[cfg(all( - not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int { @@ -15,7 +15,7 @@ pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) #[inline] #[cfg(all( - not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int { @@ -201,8 +201,8 @@ extern "C" { #[cfg(not(any(Py_LIMITED_API, PyPy)))] #[inline] pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int { - let tp_as_number = (*Py_TYPE(o)).tp_as_number; - unsafe { (!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int } + let tp_as_number = unsafe { (*Py_TYPE(o)).tp_as_number }; + (!tp_as_number.is_null() && unsafe { (*tp_as_number).nb_index }.is_some()) as c_int } extern "C" { diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index 3560a0e2001..c18c773e491 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -157,7 +157,7 @@ extern "C" { // skipped private _Py_IsOwnedByCurrentThread #[inline] -pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { +pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { unsafe { #[cfg(Py_GIL_DISABLED)] { let local = (*ob).ob_ref_local.load(Relaxed); @@ -182,7 +182,7 @@ pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { { unsafe { _Py_REFCNT(ob) } } -} +}} #[inline] pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject { @@ -622,7 +622,7 @@ extern "C" { } #[inline(always)] -pub unsafe fn Py_INCREF(op: *mut PyObject) { +pub unsafe fn Py_INCREF(op: *mut PyObject) { unsafe { // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. #[cfg(any( @@ -678,7 +678,7 @@ pub unsafe fn Py_INCREF(op: *mut PyObject) { // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue // or submit a PR supporting Py_STATS build option and pystats.h } -} +}} #[inline(always)] #[cfg_attr( @@ -909,7 +909,7 @@ pub enum PySendResult { // skipped Py_RETURN_RICHCOMPARE #[inline] -pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { +pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { unsafe { #[cfg(Py_LIMITED_API)] let flags = PyType_GetFlags(ty); @@ -920,7 +920,7 @@ pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_in let flags = (*ty).tp_flags; ((flags & feature) != 0) as c_int -} +}} #[inline] pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int { From 3dae9fc836b23ea574d9c96d0f852777e113ed63 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 18:11:25 +0000 Subject: [PATCH 09/13] fmt --- pyo3-ffi/src/object.rs | 158 +++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index c18c773e491..7b5021a15cf 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -157,32 +157,34 @@ extern "C" { // skipped private _Py_IsOwnedByCurrentThread #[inline] -pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { unsafe { - #[cfg(Py_GIL_DISABLED)] - { - let local = (*ob).ob_ref_local.load(Relaxed); - if local == _Py_IMMORTAL_REFCNT_LOCAL { - return _Py_IMMORTAL_REFCNT; +pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { + unsafe { + #[cfg(Py_GIL_DISABLED)] + { + let local = (*ob).ob_ref_local.load(Relaxed); + if local == _Py_IMMORTAL_REFCNT_LOCAL { + return _Py_IMMORTAL_REFCNT; + } + let shared = (*ob).ob_ref_shared.load(Relaxed); + local as Py_ssize_t + Py_ssize_t::from(shared >> _Py_REF_SHARED_SHIFT) } - let shared = (*ob).ob_ref_shared.load(Relaxed); - local as Py_ssize_t + Py_ssize_t::from(shared >> _Py_REF_SHARED_SHIFT) - } - #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] - { - unsafe { (*ob).ob_refcnt.ob_refcnt } - } + #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] + { + unsafe { (*ob).ob_refcnt.ob_refcnt } + } - #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] - { - unsafe { (*ob).ob_refcnt } - } + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] + { + unsafe { (*ob).ob_refcnt } + } - #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] - { - unsafe { _Py_REFCNT(ob) } + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] + { + unsafe { _Py_REFCNT(ob) } + } } -}} +} #[inline] pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject { @@ -622,63 +624,65 @@ extern "C" { } #[inline(always)] -pub unsafe fn Py_INCREF(op: *mut PyObject) { unsafe { - // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting - // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. - #[cfg(any( - Py_GIL_DISABLED, - Py_LIMITED_API, - py_sys_config = "Py_REF_DEBUG", - GraalPy - ))] - { - // _Py_IncRef was added to the ABI in 3.10; skips null checks - #[cfg(all(Py_3_10, not(PyPy)))] +pub unsafe fn Py_INCREF(op: *mut PyObject) { + unsafe { + // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting + // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. + #[cfg(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + ))] { - _Py_IncRef(op); + // _Py_IncRef was added to the ABI in 3.10; skips null checks + #[cfg(all(Py_3_10, not(PyPy)))] + { + _Py_IncRef(op); + } + + #[cfg(any(not(Py_3_10), PyPy))] + { + Py_IncRef(op); + } } - #[cfg(any(not(Py_3_10), PyPy))] + // version-specific builds are allowed to directly manipulate the reference count + #[cfg(not(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + )))] { - Py_IncRef(op); - } - } + #[cfg(all(Py_3_12, target_pointer_width = "64"))] + unsafe { + let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; + let new_refcnt = cur_refcnt.wrapping_add(1); + if new_refcnt == 0 { + return; + } + (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt; + } - // version-specific builds are allowed to directly manipulate the reference count - #[cfg(not(any( - Py_GIL_DISABLED, - Py_LIMITED_API, - py_sys_config = "Py_REF_DEBUG", - GraalPy - )))] - { - #[cfg(all(Py_3_12, target_pointer_width = "64"))] - unsafe { - let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; - let new_refcnt = cur_refcnt.wrapping_add(1); - if new_refcnt == 0 { - return; + #[cfg(all(Py_3_12, target_pointer_width = "32"))] + { + if _Py_IsImmortal(op) != 0 { + return; + } + (*op).ob_refcnt.ob_refcnt += 1 } - (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt; - } - #[cfg(all(Py_3_12, target_pointer_width = "32"))] - { - if _Py_IsImmortal(op) != 0 { - return; + #[cfg(not(Py_3_12))] + { + (*op).ob_refcnt += 1 } - (*op).ob_refcnt.ob_refcnt += 1 - } - #[cfg(not(Py_3_12))] - { - (*op).ob_refcnt += 1 + // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue + // or submit a PR supporting Py_STATS build option and pystats.h } - - // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue - // or submit a PR supporting Py_STATS build option and pystats.h } -}} +} #[inline(always)] #[cfg_attr( @@ -909,18 +913,20 @@ pub enum PySendResult { // skipped Py_RETURN_RICHCOMPARE #[inline] -pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { unsafe { - #[cfg(Py_LIMITED_API)] - let flags = PyType_GetFlags(ty); +pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { + unsafe { + #[cfg(Py_LIMITED_API)] + let flags = PyType_GetFlags(ty); - #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] - let flags = (*ty).tp_flags.load(std::sync::atomic::Ordering::Relaxed); + #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] + let flags = (*ty).tp_flags.load(std::sync::atomic::Ordering::Relaxed); - #[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))] - let flags = (*ty).tp_flags; + #[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))] + let flags = (*ty).tp_flags; - ((flags & feature) != 0) as c_int -}} + ((flags & feature) != 0) as c_int + } +} #[inline] pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int { From 8376ce8c4db56ac34e87c17c672edf1caadb4855 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 18:22:54 +0000 Subject: [PATCH 10/13] even more fixes --- pyo3-ffi/src/ceval.rs | 6 ++- pyo3-ffi/src/compat/py_3_10.rs | 8 ++-- pyo3-ffi/src/compat/py_3_13.rs | 24 +++++----- pyo3-ffi/src/compat/py_3_9.rs | 8 ++-- pyo3-ffi/src/cpython/abstract_.rs | 6 ++- pyo3-ffi/src/cpython/object.rs | 8 ++-- pyo3-ffi/src/cpython/pydebug.rs | 12 +++-- pyo3-ffi/src/cpython/unicodeobject.rs | 38 +++++++++------ pyo3-ffi/src/methodobject.rs | 2 +- pyo3-ffi/src/object.rs | 38 ++++++++------- pyo3-ffi/src/pythonrun.rs | 12 +++-- src/pycell/impl_.rs | 66 +++++++++++++-------------- src/pyclass/create_type_object.rs | 4 +- src/types/string.rs | 28 ++++++------ 14 files changed, 139 insertions(+), 121 deletions(-) diff --git a/pyo3-ffi/src/ceval.rs b/pyo3-ffi/src/ceval.rs index d1839a108cb..485b2a988e3 100644 --- a/pyo3-ffi/src/ceval.rs +++ b/pyo3-ffi/src/ceval.rs @@ -38,8 +38,10 @@ extern "C" { #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { - #[allow(deprecated)] - PyEval_CallObjectWithKeywords(func, arg, std::ptr::null_mut()) + unsafe { + #[allow(deprecated)] + PyEval_CallObjectWithKeywords(func, arg, std::ptr::null_mut()) + } } extern "C" { diff --git a/pyo3-ffi/src/compat/py_3_10.rs b/pyo3-ffi/src/compat/py_3_10.rs index c6e8c2cb5ca..d528a74bbc4 100644 --- a/pyo3-ffi/src/compat/py_3_10.rs +++ b/pyo3-ffi/src/compat/py_3_10.rs @@ -2,18 +2,18 @@ compat_function!( originally_defined_for(Py_3_10); #[inline] - pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { + pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { crate::Py_INCREF(obj); obj - } + }} ); compat_function!( originally_defined_for(Py_3_10); #[inline] - pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { + pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { crate::Py_XINCREF(obj); obj - } + }} ); diff --git a/pyo3-ffi/src/compat/py_3_13.rs b/pyo3-ffi/src/compat/py_3_13.rs index 59289cb76ae..8ff46e4991a 100644 --- a/pyo3-ffi/src/compat/py_3_13.rs +++ b/pyo3-ffi/src/compat/py_3_13.rs @@ -6,7 +6,7 @@ compat_function!( dp: *mut crate::PyObject, key: *mut crate::PyObject, result: *mut *mut crate::PyObject, - ) -> std::os::raw::c_int { + ) -> std::os::raw::c_int { unsafe { use crate::{compat::Py_NewRef, PyDict_GetItemWithError, PyErr_Occurred}; let item = PyDict_GetItemWithError(dp, key); @@ -19,7 +19,7 @@ compat_function!( return 0; // not found } -1 - } + }} ); compat_function!( @@ -29,13 +29,13 @@ compat_function!( pub unsafe fn PyList_GetItemRef( arg1: *mut crate::PyObject, arg2: crate::Py_ssize_t, - ) -> *mut crate::PyObject { + ) -> *mut crate::PyObject { unsafe { use crate::{PyList_GetItem, Py_XINCREF}; let item = PyList_GetItem(arg1, arg2); Py_XINCREF(item); item - } + }} ); compat_function!( @@ -44,11 +44,11 @@ compat_function!( #[inline] pub unsafe fn PyImport_AddModuleRef( name: *const std::os::raw::c_char, - ) -> *mut crate::PyObject { + ) -> *mut crate::PyObject { unsafe { use crate::{compat::Py_XNewRef, PyImport_AddModule}; Py_XNewRef(PyImport_AddModule(name)) - } + }} ); compat_function!( @@ -58,7 +58,7 @@ compat_function!( pub unsafe fn PyWeakref_GetRef( reference: *mut crate::PyObject, pobj: *mut *mut crate::PyObject, - ) -> std::os::raw::c_int { + ) -> std::os::raw::c_int { unsafe { use crate::{ compat::Py_NewRef, PyErr_SetString, PyExc_TypeError, PyWeakref_Check, PyWeakref_GetObject, Py_None, @@ -81,7 +81,7 @@ compat_function!( } *pobj = Py_NewRef(obj); 1 - } + }} ); compat_function!( @@ -91,16 +91,16 @@ compat_function!( pub unsafe fn PyList_Extend( list: *mut crate::PyObject, iterable: *mut crate::PyObject, - ) -> std::os::raw::c_int { + ) -> std::os::raw::c_int { unsafe { crate::PyList_SetSlice(list, crate::PY_SSIZE_T_MAX, crate::PY_SSIZE_T_MAX, iterable) - } + }} ); compat_function!( originally_defined_for(Py_3_13); #[inline] - pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> std::os::raw::c_int { + pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> std::os::raw::c_int { unsafe { crate::PyList_SetSlice(list, 0, crate::PY_SSIZE_T_MAX, std::ptr::null_mut()) - } + }} ); diff --git a/pyo3-ffi/src/compat/py_3_9.rs b/pyo3-ffi/src/compat/py_3_9.rs index 285f2b2ae7e..b903f40823d 100644 --- a/pyo3-ffi/src/compat/py_3_9.rs +++ b/pyo3-ffi/src/compat/py_3_9.rs @@ -6,16 +6,16 @@ compat_function!( )); #[inline] - pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { + pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { crate::PyObject_CallObject(obj, std::ptr::null_mut()) - } + }} ); compat_function!( originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy)))); #[inline] - pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { + pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { crate::PyObject_CallMethodObjArgs(obj, name, std::ptr::null_mut::()) - } + }} ); diff --git a/pyo3-ffi/src/cpython/abstract_.rs b/pyo3-ffi/src/cpython/abstract_.rs index 2d0ff9cfc72..9f22800169f 100644 --- a/pyo3-ffi/src/cpython/abstract_.rs +++ b/pyo3-ffi/src/cpython/abstract_.rs @@ -236,8 +236,10 @@ extern "C" { #[cfg(not(any(Py_3_9, PyPy)))] #[inline] pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int { - let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer; - (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int + unsafe { + let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer; + (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int + } } #[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11 diff --git a/pyo3-ffi/src/cpython/object.rs b/pyo3-ffi/src/cpython/object.rs index 4e6932da789..4dd462ed3d5 100644 --- a/pyo3-ffi/src/cpython/object.rs +++ b/pyo3-ffi/src/cpython/object.rs @@ -326,9 +326,11 @@ impl Default for PyHeapTypeObject { #[inline] #[cfg(not(Py_3_11))] pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef { - let py_type = object::Py_TYPE(etype as *mut object::PyObject); - let ptr = etype.offset((*py_type).tp_basicsize); - ptr as *mut PyMemberDef + unsafe { + let py_type = object::Py_TYPE(etype as *mut object::PyObject); + let ptr = etype.offset((*py_type).tp_basicsize); + ptr as *mut PyMemberDef + } } // skipped private _PyType_Name diff --git a/pyo3-ffi/src/cpython/pydebug.rs b/pyo3-ffi/src/cpython/pydebug.rs index a42848e8fdb..2dc27401ddc 100644 --- a/pyo3-ffi/src/cpython/pydebug.rs +++ b/pyo3-ffi/src/cpython/pydebug.rs @@ -63,10 +63,12 @@ extern "C" { #[cfg(not(Py_3_11))] #[inline(always)] pub unsafe fn Py_GETENV(name: *const c_char) -> *mut c_char { - #[allow(deprecated)] - if Py_IgnoreEnvironmentFlag != 0 { - std::ptr::null_mut() - } else { - libc::getenv(name) + unsafe { + #[allow(deprecated)] + if Py_IgnoreEnvironmentFlag != 0 { + std::ptr::null_mut() + } else { + libc::getenv(name) + } } } diff --git a/pyo3-ffi/src/cpython/unicodeobject.rs b/pyo3-ffi/src/cpython/unicodeobject.rs index 568400f7bc4..d033443e0f9 100644 --- a/pyo3-ffi/src/cpython/unicodeobject.rs +++ b/pyo3-ffi/src/cpython/unicodeobject.rs @@ -224,15 +224,19 @@ impl PyASCIIObjectState { #[cfg(not(Py_3_12))] #[inline] unsafe fn ready(&self) -> c_uint { - std::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32) + unsafe { + std::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32) + } } #[cfg(not(Py_3_12))] #[inline] unsafe fn set_ready(&mut self, val: c_uint) { - let val: u32 = std::mem::transmute(val); - self.bitfield - .set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64) + unsafe { + let val: u32 = std::mem::transmute(val); + self.bitfield + .set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64) + } } } @@ -365,7 +369,7 @@ impl PyASCIIObject { #[cfg(not(Py_3_12))] #[inline] pub unsafe fn ready(&self) -> c_uint { - PyASCIIObjectState::from(self.state).ready() + unsafe { PyASCIIObjectState::from(self.state).ready() } } /// Set the `ready` flag of the [`PyASCIIObject`] state bitfield. @@ -374,9 +378,11 @@ impl PyASCIIObject { #[cfg(not(Py_3_12))] #[inline] pub unsafe fn set_ready(&mut self, val: c_uint) { - let mut state = PyASCIIObjectState::from(self.state); - state.set_ready(val); - self.state = u32::from(state); + unsafe { + let mut state = PyASCIIObjectState::from(self.state); + state.set_ready(val); + self.state = u32::from(state); + } } } @@ -526,7 +532,7 @@ pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t { debug_assert!(unsafe { crate::PyUnicode_Check(op) } != 0); #[cfg(not(Py_3_12))] - debug_assert!(PyUnicode_IS_READY(op) != 0); + debug_assert!(unsafe { PyUnicode_IS_READY(op) } != 0); unsafe { (*(op as *mut PyASCIIObject)).length } } @@ -541,7 +547,7 @@ pub unsafe fn PyUnicode_IS_READY(_op: *mut PyObject) -> c_uint { #[cfg(not(any(GraalPy, Py_3_12)))] #[inline] pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint { - (*(op as *mut PyASCIIObject)).ready() + unsafe { (*(op as *mut PyASCIIObject)).ready() } } #[cfg(any(Py_3_12, GraalPy))] @@ -553,12 +559,14 @@ pub unsafe fn PyUnicode_READY(_op: *mut PyObject) -> c_int { #[cfg(not(any(Py_3_12, GraalPy)))] #[inline] pub unsafe fn PyUnicode_READY(op: *mut PyObject) -> c_int { - debug_assert!(crate::PyUnicode_Check(op) != 0); + unsafe { + debug_assert!(crate::PyUnicode_Check(op) != 0); - if PyUnicode_IS_READY(op) != 0 { - 0 - } else { - _PyUnicode_Ready(op) + if PyUnicode_IS_READY(op) != 0 { + 0 + } else { + _PyUnicode_Ready(op) + } } } diff --git a/pyo3-ffi/src/methodobject.rs b/pyo3-ffi/src/methodobject.rs index 950256756d6..25226b3172f 100644 --- a/pyo3-ffi/src/methodobject.rs +++ b/pyo3-ffi/src/methodobject.rs @@ -36,7 +36,7 @@ pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { #[cfg(not(Py_3_9))] #[inline] pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int + unsafe { (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } } pub type PyCFunction = diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index 7b5021a15cf..2d296a9b85e 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -158,31 +158,29 @@ extern "C" { #[inline] pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { + #[cfg(Py_GIL_DISABLED)] unsafe { - #[cfg(Py_GIL_DISABLED)] - { - let local = (*ob).ob_ref_local.load(Relaxed); - if local == _Py_IMMORTAL_REFCNT_LOCAL { - return _Py_IMMORTAL_REFCNT; - } - let shared = (*ob).ob_ref_shared.load(Relaxed); - local as Py_ssize_t + Py_ssize_t::from(shared >> _Py_REF_SHARED_SHIFT) + let local = (*ob).ob_ref_local.load(Relaxed); + if local == _Py_IMMORTAL_REFCNT_LOCAL { + return _Py_IMMORTAL_REFCNT; } + let shared = (*ob).ob_ref_shared.load(Relaxed); + local as Py_ssize_t + Py_ssize_t::from(shared >> _Py_REF_SHARED_SHIFT) + } - #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] - { - unsafe { (*ob).ob_refcnt.ob_refcnt } - } + #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] + { + unsafe { (*ob).ob_refcnt.ob_refcnt } + } - #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] - { - unsafe { (*ob).ob_refcnt } - } + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] + { + unsafe { (*ob).ob_refcnt } + } - #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] - { - unsafe { _Py_REFCNT(ob) } - } + #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] + { + unsafe { _Py_REFCNT(ob) } } } diff --git a/pyo3-ffi/src/pythonrun.rs b/pyo3-ffi/src/pythonrun.rs index e7ea2d2efd0..3b510710b6e 100644 --- a/pyo3-ffi/src/pythonrun.rs +++ b/pyo3-ffi/src/pythonrun.rs @@ -60,16 +60,20 @@ opaque_struct!(_node); #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseString(s: *const c_char, b: c_int) -> *mut _node { - #[allow(deprecated)] - crate::PyParser_SimpleParseStringFlags(s, b, 0) + unsafe { + #[allow(deprecated)] + crate::PyParser_SimpleParseStringFlags(s, b, 0) + } } #[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseFile(fp: *mut FILE, s: *const c_char, b: c_int) -> *mut _node { - #[allow(deprecated)] - crate::PyParser_SimpleParseFileFlags(fp, s, b, 0) + unsafe { + #[allow(deprecated)] + crate::PyParser_SimpleParseFileFlags(fp, s, b, 0) + } } extern "C" { diff --git a/src/pycell/impl_.rs b/src/pycell/impl_.rs index 42e60553c74..6fe0545d529 100644 --- a/src/pycell/impl_.rs +++ b/src/pycell/impl_.rs @@ -233,44 +233,44 @@ where Ok(()) } unsafe fn tp_dealloc(py: Python<'_>, slf: *mut ffi::PyObject) { - // FIXME: there is potentially subtle issues here if the base is overwritten - // at runtime? To be investigated. - let type_obj = T::type_object(py); - let type_ptr = type_obj.as_type_ptr(); - let actual_type = unsafe { PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(slf)) }; - - // For `#[pyclass]` types which inherit from PyAny, we can just call tp_free - if type_ptr == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type) { - let tp_free = actual_type - .get_slot(TP_FREE) - .expect("PyBaseObject_Type should have tp_free"); - return unsafe { tp_free(slf.cast()) }; - } + unsafe { + // FIXME: there is potentially subtle issues here if the base is overwritten + // at runtime? To be investigated. + let type_obj = T::type_object(py); + let type_ptr = type_obj.as_type_ptr(); + let actual_type = PyType::from_borrowed_type_ptr(py, ffi::Py_TYPE(slf)); + + // For `#[pyclass]` types which inherit from PyAny, we can just call tp_free + if type_ptr == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type) { + let tp_free = actual_type + .get_slot(TP_FREE) + .expect("PyBaseObject_Type should have tp_free"); + return tp_free(slf.cast()); + } - // More complex native types (e.g. `extends=PyDict`) require calling the base's dealloc. - #[cfg(not(Py_LIMITED_API))] - { - // FIXME: should this be using actual_type.tp_dealloc? - if let Some(dealloc) = unsafe { (*type_ptr).tp_dealloc } { - // Before CPython 3.11 BaseException_dealloc would use Py_GC_UNTRACK which - // assumes the exception is currently GC tracked, so we have to re-track - // before calling the dealloc so that it can safely call Py_GC_UNTRACK. - #[cfg(not(any(Py_3_11, PyPy)))] - if ffi::PyType_FastSubclass(type_ptr, ffi::Py_TPFLAGS_BASE_EXC_SUBCLASS) == 1 { - ffi::PyObject_GC_Track(slf.cast()); - } - unsafe { dealloc(slf) }; - } else { - unsafe { + // More complex native types (e.g. `extends=PyDict`) require calling the base's dealloc. + #[cfg(not(Py_LIMITED_API))] + { + // FIXME: should this be using actual_type.tp_dealloc? + if let Some(dealloc) = (*type_ptr).tp_dealloc { + // Before CPython 3.11 BaseException_dealloc would use Py_GC_UNTRACK which + // assumes the exception is currently GC tracked, so we have to re-track + // before calling the dealloc so that it can safely call Py_GC_UNTRACK. + #[cfg(not(any(Py_3_11, PyPy)))] + if ffi::PyType_FastSubclass(type_ptr, ffi::Py_TPFLAGS_BASE_EXC_SUBCLASS) == 1 { + ffi::PyObject_GC_Track(slf.cast()); + } + dealloc(slf); + } else { (*actual_type.as_type_ptr()) .tp_free - .expect("type missing tp_free")(slf.cast()) - }; + .expect("type missing tp_free")(slf.cast()); + } } - } - #[cfg(Py_LIMITED_API)] - unreachable!("subclassing native types is not possible with the `abi3` feature"); + #[cfg(Py_LIMITED_API)] + unreachable!("subclassing native types is not possible with the `abi3` feature"); + } } } diff --git a/src/pyclass/create_type_object.rs b/src/pyclass/create_type_object.rs index 918dedbbc8b..bbc3e465772 100644 --- a/src/pyclass/create_type_object.rs +++ b/src/pyclass/create_type_object.rs @@ -147,13 +147,13 @@ impl PyTypeBuilder { ffi::Py_bf_getbuffer => { // Safety: slot.pfunc is a valid function pointer self.buffer_procs.bf_getbuffer = - Some(std::mem::transmute::<*mut T, ffi::getbufferproc>(pfunc)); + Some(unsafe { std::mem::transmute::<*mut T, ffi::getbufferproc>(pfunc) }); } #[cfg(all(not(Py_3_9), not(Py_LIMITED_API)))] ffi::Py_bf_releasebuffer => { // Safety: slot.pfunc is a valid function pointer self.buffer_procs.bf_releasebuffer = - Some(std::mem::transmute::<*mut T, ffi::releasebufferproc>(pfunc)); + Some(unsafe { std::mem::transmute::<*mut T, ffi::releasebufferproc>(pfunc) }); } _ => {} } diff --git a/src/types/string.rs b/src/types/string.rs index ad30dba02d6..0b0de39c681 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -373,22 +373,22 @@ impl<'a> Borrowed<'a, '_, PyString> { #[cfg(not(any(Py_LIMITED_API, GraalPy, PyPy)))] unsafe fn data(self) -> PyResult> { - let ptr = self.as_ptr(); - - #[cfg(not(Py_3_12))] - #[allow(deprecated)] - { - let ready = ffi::PyUnicode_READY(ptr); - if ready != 0 { - // Exception was created on failure. - return Err(crate::PyErr::fetch(self.py())); + unsafe { + let ptr = self.as_ptr(); + + #[cfg(not(Py_3_12))] + #[allow(deprecated)] + { + let ready = ffi::PyUnicode_READY(ptr); + if ready != 0 { + // Exception was created on failure. + return Err(crate::PyErr::fetch(self.py())); + } } - } - // The string should be in its canonical form after calling `PyUnicode_READY()`. - // And non-canonical form not possible after Python 3.12. So it should be safe - // to call these APIs. - unsafe { + // The string should be in its canonical form after calling `PyUnicode_READY()`. + // And non-canonical form not possible after Python 3.12. So it should be safe + // to call these APIs. let length = ffi::PyUnicode_GET_LENGTH(ptr) as usize; let raw_data = ffi::PyUnicode_DATA(ptr); let kind = ffi::PyUnicode_KIND(ptr); From 0048365ad7616ff15c6ceede59c6ff866d509b7c Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 18:59:03 +0000 Subject: [PATCH 11/13] fix unnecessary unsafe --- pyo3-ffi/src/object.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index 2d296a9b85e..be81326328f 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -654,7 +654,7 @@ pub unsafe fn Py_INCREF(op: *mut PyObject) { )))] { #[cfg(all(Py_3_12, target_pointer_width = "64"))] - unsafe { + { let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; let new_refcnt = cur_refcnt.wrapping_add(1); if new_refcnt == 0 { From ff3df6cd11a0ed2049c7f5d9cb475100c786910c Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 19:20:17 +0000 Subject: [PATCH 12/13] allow `unsafe_op_in_unsafe_fn` in `pyo3-ffi` --- pyo3-ffi/src/abstract_.rs | 26 ++-- pyo3-ffi/src/boolobject.rs | 6 +- pyo3-ffi/src/bytearrayobject.rs | 4 +- pyo3-ffi/src/bytesobject.rs | 4 +- pyo3-ffi/src/ceval.rs | 6 +- pyo3-ffi/src/compat/py_3_10.rs | 8 +- pyo3-ffi/src/compat/py_3_13.rs | 24 ++-- pyo3-ffi/src/compat/py_3_9.rs | 8 +- pyo3-ffi/src/complexobject.rs | 4 +- pyo3-ffi/src/context.rs | 6 +- pyo3-ffi/src/cpython/abstract_.rs | 104 +++++++--------- pyo3-ffi/src/cpython/code.rs | 2 +- pyo3-ffi/src/cpython/floatobject.rs | 4 +- pyo3-ffi/src/cpython/frameobject.rs | 2 +- pyo3-ffi/src/cpython/funcobject.rs | 2 +- pyo3-ffi/src/cpython/genobject.rs | 8 +- pyo3-ffi/src/cpython/listobject.rs | 8 +- pyo3-ffi/src/cpython/methodobject.rs | 46 ++++--- pyo3-ffi/src/cpython/object.rs | 8 +- pyo3-ffi/src/cpython/objimpl.rs | 20 ++-- pyo3-ffi/src/cpython/pydebug.rs | 12 +- pyo3-ffi/src/cpython/pythonrun.rs | 4 +- pyo3-ffi/src/cpython/tupleobject.rs | 6 +- pyo3-ffi/src/cpython/unicodeobject.rs | 142 +++++++++------------- pyo3-ffi/src/datetime.rs | 83 ++++++------- pyo3-ffi/src/dictobject.rs | 12 +- pyo3-ffi/src/floatobject.rs | 4 +- pyo3-ffi/src/import.rs | 2 +- pyo3-ffi/src/iterobject.rs | 4 +- pyo3-ffi/src/lib.rs | 6 +- pyo3-ffi/src/listobject.rs | 4 +- pyo3-ffi/src/longobject.rs | 4 +- pyo3-ffi/src/memoryobject.rs | 2 +- pyo3-ffi/src/methodobject.rs | 10 +- pyo3-ffi/src/modsupport.rs | 38 +++--- pyo3-ffi/src/moduleobject.rs | 4 +- pyo3-ffi/src/object.rs | 166 ++++++++++++-------------- pyo3-ffi/src/objimpl.rs | 2 +- pyo3-ffi/src/pycapsule.rs | 2 +- pyo3-ffi/src/pyerrors.rs | 12 +- pyo3-ffi/src/pystate.rs | 6 +- pyo3-ffi/src/pythonrun.rs | 12 +- pyo3-ffi/src/rangeobject.rs | 2 +- pyo3-ffi/src/setobject.rs | 38 +++--- pyo3-ffi/src/sliceobject.rs | 16 ++- pyo3-ffi/src/structseq.rs | 4 +- pyo3-ffi/src/traceback.rs | 2 +- pyo3-ffi/src/tupleobject.rs | 4 +- pyo3-ffi/src/unicodeobject.rs | 4 +- pyo3-ffi/src/weakrefobject.rs | 12 +- 50 files changed, 415 insertions(+), 504 deletions(-) diff --git a/pyo3-ffi/src/abstract_.rs b/pyo3-ffi/src/abstract_.rs index 311d0e5b518..a79ec43f271 100644 --- a/pyo3-ffi/src/abstract_.rs +++ b/pyo3-ffi/src/abstract_.rs @@ -6,20 +6,20 @@ use std::os::raw::{c_char, c_int}; #[inline] #[cfg(all( - not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int { - unsafe { PyObject_SetAttrString(o, attr_name, std::ptr::null_mut()) } + PyObject_SetAttrString(o, attr_name, std::ptr::null_mut()) } #[inline] #[cfg(all( - not(Py_3_13), // CPython exposed as a function in 3.13, in object.h + not(Py_3_13), // CPython exposed as a function in 3.13, in object.h not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+ ))] pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int { - unsafe { PyObject_SetAttr(o, attr_name, std::ptr::null_mut()) } + PyObject_SetAttr(o, attr_name, std::ptr::null_mut()) } extern "C" { @@ -108,7 +108,7 @@ extern "C" { #[inline] pub unsafe fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t { - unsafe { PyObject_Size(o) } + PyObject_Size(o) } extern "C" { @@ -137,7 +137,7 @@ extern "C" { #[cfg(not(any(Py_3_8, PyPy)))] #[inline] pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int { - unsafe { crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), c_str!("__next__").as_ptr()) } + crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), c_str!("__next__").as_ptr()) } extern "C" { @@ -201,8 +201,8 @@ extern "C" { #[cfg(not(any(Py_LIMITED_API, PyPy)))] #[inline] pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int { - let tp_as_number = unsafe { (*Py_TYPE(o)).tp_as_number }; - (!tp_as_number.is_null() && unsafe { (*tp_as_number).nb_index }.is_some()) as c_int + let tp_as_number = (*Py_TYPE(o)).tp_as_number; + (!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int } extern "C" { @@ -263,7 +263,7 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t { - unsafe { PySequence_Size(o) } + PySequence_Size(o) } extern "C" { @@ -304,7 +304,7 @@ extern "C" { #[inline] pub unsafe fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int { - unsafe { PySequence_Contains(o, value) } + PySequence_Contains(o, value) } extern "C" { @@ -327,17 +327,17 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t { - unsafe { PyMapping_Size(o) } + PyMapping_Size(o) } #[inline] pub unsafe fn PyMapping_DelItemString(o: *mut PyObject, key: *mut c_char) -> c_int { - unsafe { PyObject_DelItemString(o, key) } + PyObject_DelItemString(o, key) } #[inline] pub unsafe fn PyMapping_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int { - unsafe { PyObject_DelItem(o, key) } + PyObject_DelItem(o, key) } extern "C" { diff --git a/pyo3-ffi/src/boolobject.rs b/pyo3-ffi/src/boolobject.rs index 71efcd52db3..eec9da707a1 100644 --- a/pyo3-ffi/src/boolobject.rs +++ b/pyo3-ffi/src/boolobject.rs @@ -6,7 +6,7 @@ use std::ptr::addr_of_mut; #[inline] pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyBool_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyBool_Type)) as c_int } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -42,12 +42,12 @@ pub unsafe fn Py_True() -> *mut PyObject { #[inline] pub unsafe fn Py_IsTrue(x: *mut PyObject) -> c_int { - unsafe { Py_Is(x, Py_True()) } + Py_Is(x, Py_True()) } #[inline] pub unsafe fn Py_IsFalse(x: *mut PyObject) -> c_int { - unsafe { Py_Is(x, Py_False()) } + Py_Is(x, Py_False()) } // skipped Py_RETURN_TRUE diff --git a/pyo3-ffi/src/bytearrayobject.rs b/pyo3-ffi/src/bytearrayobject.rs index db543b7fd3d..24a97bcc31b 100644 --- a/pyo3-ffi/src/bytearrayobject.rs +++ b/pyo3-ffi/src/bytearrayobject.rs @@ -29,12 +29,12 @@ extern "C" { #[inline] pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyByteArray_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyByteArray_Type)) } #[inline] pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyByteArray_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyByteArray_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/bytesobject.rs b/pyo3-ffi/src/bytesobject.rs index 05709e828fa..0fd327b6fca 100644 --- a/pyo3-ffi/src/bytesobject.rs +++ b/pyo3-ffi/src/bytesobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) } #[inline] pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyBytes_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyBytes_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/ceval.rs b/pyo3-ffi/src/ceval.rs index 485b2a988e3..d1839a108cb 100644 --- a/pyo3-ffi/src/ceval.rs +++ b/pyo3-ffi/src/ceval.rs @@ -38,10 +38,8 @@ extern "C" { #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { - unsafe { - #[allow(deprecated)] - PyEval_CallObjectWithKeywords(func, arg, std::ptr::null_mut()) - } + #[allow(deprecated)] + PyEval_CallObjectWithKeywords(func, arg, std::ptr::null_mut()) } extern "C" { diff --git a/pyo3-ffi/src/compat/py_3_10.rs b/pyo3-ffi/src/compat/py_3_10.rs index d528a74bbc4..c6e8c2cb5ca 100644 --- a/pyo3-ffi/src/compat/py_3_10.rs +++ b/pyo3-ffi/src/compat/py_3_10.rs @@ -2,18 +2,18 @@ compat_function!( originally_defined_for(Py_3_10); #[inline] - pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { + pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { crate::Py_INCREF(obj); obj - }} + } ); compat_function!( originally_defined_for(Py_3_10); #[inline] - pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { + pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject { crate::Py_XINCREF(obj); obj - }} + } ); diff --git a/pyo3-ffi/src/compat/py_3_13.rs b/pyo3-ffi/src/compat/py_3_13.rs index 8ff46e4991a..59289cb76ae 100644 --- a/pyo3-ffi/src/compat/py_3_13.rs +++ b/pyo3-ffi/src/compat/py_3_13.rs @@ -6,7 +6,7 @@ compat_function!( dp: *mut crate::PyObject, key: *mut crate::PyObject, result: *mut *mut crate::PyObject, - ) -> std::os::raw::c_int { unsafe { + ) -> std::os::raw::c_int { use crate::{compat::Py_NewRef, PyDict_GetItemWithError, PyErr_Occurred}; let item = PyDict_GetItemWithError(dp, key); @@ -19,7 +19,7 @@ compat_function!( return 0; // not found } -1 - }} + } ); compat_function!( @@ -29,13 +29,13 @@ compat_function!( pub unsafe fn PyList_GetItemRef( arg1: *mut crate::PyObject, arg2: crate::Py_ssize_t, - ) -> *mut crate::PyObject { unsafe { + ) -> *mut crate::PyObject { use crate::{PyList_GetItem, Py_XINCREF}; let item = PyList_GetItem(arg1, arg2); Py_XINCREF(item); item - }} + } ); compat_function!( @@ -44,11 +44,11 @@ compat_function!( #[inline] pub unsafe fn PyImport_AddModuleRef( name: *const std::os::raw::c_char, - ) -> *mut crate::PyObject { unsafe { + ) -> *mut crate::PyObject { use crate::{compat::Py_XNewRef, PyImport_AddModule}; Py_XNewRef(PyImport_AddModule(name)) - }} + } ); compat_function!( @@ -58,7 +58,7 @@ compat_function!( pub unsafe fn PyWeakref_GetRef( reference: *mut crate::PyObject, pobj: *mut *mut crate::PyObject, - ) -> std::os::raw::c_int { unsafe { + ) -> std::os::raw::c_int { use crate::{ compat::Py_NewRef, PyErr_SetString, PyExc_TypeError, PyWeakref_Check, PyWeakref_GetObject, Py_None, @@ -81,7 +81,7 @@ compat_function!( } *pobj = Py_NewRef(obj); 1 - }} + } ); compat_function!( @@ -91,16 +91,16 @@ compat_function!( pub unsafe fn PyList_Extend( list: *mut crate::PyObject, iterable: *mut crate::PyObject, - ) -> std::os::raw::c_int { unsafe { + ) -> std::os::raw::c_int { crate::PyList_SetSlice(list, crate::PY_SSIZE_T_MAX, crate::PY_SSIZE_T_MAX, iterable) - }} + } ); compat_function!( originally_defined_for(Py_3_13); #[inline] - pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> std::os::raw::c_int { unsafe { + pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> std::os::raw::c_int { crate::PyList_SetSlice(list, 0, crate::PY_SSIZE_T_MAX, std::ptr::null_mut()) - }} + } ); diff --git a/pyo3-ffi/src/compat/py_3_9.rs b/pyo3-ffi/src/compat/py_3_9.rs index b903f40823d..285f2b2ae7e 100644 --- a/pyo3-ffi/src/compat/py_3_9.rs +++ b/pyo3-ffi/src/compat/py_3_9.rs @@ -6,16 +6,16 @@ compat_function!( )); #[inline] - pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { + pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { crate::PyObject_CallObject(obj, std::ptr::null_mut()) - }} + } ); compat_function!( originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy)))); #[inline] - pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { unsafe { + pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { crate::PyObject_CallMethodObjArgs(obj, name, std::ptr::null_mut::()) - }} + } ); diff --git a/pyo3-ffi/src/complexobject.rs b/pyo3-ffi/src/complexobject.rs index 33f7c9b072d..283bacf6e84 100644 --- a/pyo3-ffi/src/complexobject.rs +++ b/pyo3-ffi/src/complexobject.rs @@ -10,12 +10,12 @@ extern "C" { #[inline] pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyComplex_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyComplex_Type)) } #[inline] pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int { - unsafe { Py_IS_TYPE(op, addr_of_mut!(PyComplex_Type)) } + Py_IS_TYPE(op, addr_of_mut!(PyComplex_Type)) } extern "C" { diff --git a/pyo3-ffi/src/context.rs b/pyo3-ffi/src/context.rs index 265a410cedc..210d6e21f04 100644 --- a/pyo3-ffi/src/context.rs +++ b/pyo3-ffi/src/context.rs @@ -13,17 +13,17 @@ extern "C" { #[inline] pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyContext_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyContext_Type)) as c_int } #[inline] pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyContextVar_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyContextVar_Type)) as c_int } #[inline] pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyContextToken_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyContextToken_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/cpython/abstract_.rs b/pyo3-ffi/src/cpython/abstract_.rs index 9f22800169f..6ada1a754ef 100644 --- a/pyo3-ffi/src/cpython/abstract_.rs +++ b/pyo3-ffi/src/cpython/abstract_.rs @@ -55,18 +55,16 @@ pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t { #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] #[inline(always)] pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option { - unsafe { - assert!(!callable.is_null()); - let tp = crate::Py_TYPE(callable); - if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 { - return None; - } - assert!(PyCallable_Check(callable) > 0); - let offset = (*tp).tp_vectorcall_offset; - assert!(offset > 0); - let ptr = callable.cast::().offset(offset).cast(); - *ptr + assert!(!callable.is_null()); + let tp = crate::Py_TYPE(callable); + if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 { + return None; } + assert!(PyCallable_Check(callable) > 0); + let offset = (*tp).tp_vectorcall_offset; + assert!(offset > 0); + let ptr = callable.cast::().offset(offset).cast(); + *ptr } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] @@ -78,19 +76,17 @@ pub unsafe fn _PyObject_VectorcallTstate( nargsf: size_t, kwnames: *mut PyObject, ) -> *mut PyObject { - unsafe { - assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0); - assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0); - - match PyVectorcall_Function(callable) { - None => { - let nargs = PyVectorcall_NARGS(nargsf); - _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames) - } - Some(func) => { - let res = func(callable, args, nargsf, kwnames); - _Py_CheckFunctionResult(tstate, callable, res, std::ptr::null_mut()) - } + assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0); + assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0); + + match PyVectorcall_Function(callable) { + None => { + let nargs = PyVectorcall_NARGS(nargsf); + _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames) + } + Some(func) => { + let res = func(callable, args, nargsf, kwnames); + _Py_CheckFunctionResult(tstate, callable, res, std::ptr::null_mut()) } } } @@ -139,7 +135,7 @@ pub unsafe fn _PyObject_FastCallTstate( args: *const *mut PyObject, nargs: Py_ssize_t, ) -> *mut PyObject { - unsafe { _PyObject_VectorcallTstate(tstate, func, args, nargs as size_t, std::ptr::null_mut()) } + _PyObject_VectorcallTstate(tstate, func, args, nargs as size_t, std::ptr::null_mut()) } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] @@ -149,21 +145,19 @@ pub unsafe fn _PyObject_FastCall( args: *const *mut PyObject, nargs: Py_ssize_t, ) -> *mut PyObject { - unsafe { _PyObject_FastCallTstate(PyThreadState_GET(), func, args, nargs) } + _PyObject_FastCallTstate(PyThreadState_GET(), func, args, nargs) } #[cfg(all(Py_3_8, not(any(PyPy, GraalPy))))] #[inline(always)] pub unsafe fn _PyObject_CallNoArg(func: *mut PyObject) -> *mut PyObject { - unsafe { - _PyObject_VectorcallTstate( - PyThreadState_GET(), - func, - std::ptr::null_mut(), - 0, - std::ptr::null_mut(), - ) - } + _PyObject_VectorcallTstate( + PyThreadState_GET(), + func, + std::ptr::null_mut(), + 0, + std::ptr::null_mut(), + ) } extern "C" { @@ -177,10 +171,10 @@ extern "C" { pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { assert!(!arg.is_null()); let args_array = [std::ptr::null_mut(), arg]; - let args = unsafe { args_array.as_ptr().offset(1) }; // For PY_VECTORCALL_ARGUMENTS_OFFSET - let tstate = unsafe { PyThreadState_GET() }; + let args = args_array.as_ptr().offset(1); // For PY_VECTORCALL_ARGUMENTS_OFFSET + let tstate = PyThreadState_GET(); let nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; - unsafe { _PyObject_VectorcallTstate(tstate, func, args, nargsf, std::ptr::null_mut()) } + _PyObject_VectorcallTstate(tstate, func, args, nargsf, std::ptr::null_mut()) } #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] @@ -189,14 +183,12 @@ pub unsafe fn PyObject_CallMethodNoArgs( self_: *mut PyObject, name: *mut PyObject, ) -> *mut PyObject { - unsafe { - crate::PyObject_VectorcallMethod( - name, - &self_, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, - std::ptr::null_mut(), - ) - } + crate::PyObject_VectorcallMethod( + name, + &self_, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, + std::ptr::null_mut(), + ) } #[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))] @@ -208,14 +200,12 @@ pub unsafe fn PyObject_CallMethodOneArg( ) -> *mut PyObject { let args = [self_, arg]; assert!(!arg.is_null()); - unsafe { - crate::PyObject_VectorcallMethod( - name, - args.as_ptr(), - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, - std::ptr::null_mut(), - ) - } + crate::PyObject_VectorcallMethod( + name, + args.as_ptr(), + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + std::ptr::null_mut(), + ) } // skipped _PyObject_VectorcallMethodId @@ -236,10 +226,8 @@ extern "C" { #[cfg(not(any(Py_3_9, PyPy)))] #[inline] pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int { - unsafe { - let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer; - (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int - } + let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer; + (!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int } #[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11 diff --git a/pyo3-ffi/src/cpython/code.rs b/pyo3-ffi/src/cpython/code.rs index 81ecf0fd5de..230096ca378 100644 --- a/pyo3-ffi/src/cpython/code.rs +++ b/pyo3-ffi/src/cpython/code.rs @@ -244,7 +244,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyCode_Type)) as c_int } #[inline] diff --git a/pyo3-ffi/src/cpython/floatobject.rs b/pyo3-ffi/src/cpython/floatobject.rs index 6d5ac33d1fc..e7caa441c5d 100644 --- a/pyo3-ffi/src/cpython/floatobject.rs +++ b/pyo3-ffi/src/cpython/floatobject.rs @@ -11,14 +11,14 @@ pub struct PyFloatObject { #[inline] pub unsafe fn _PyFloat_CAST(op: *mut PyObject) -> *mut PyFloatObject { - debug_assert_eq!(unsafe { PyFloat_Check(op) }, 1); + debug_assert_eq!(PyFloat_Check(op), 1); op.cast() } #[inline] pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double { #[cfg(not(GraalPy))] - return unsafe { (*_PyFloat_CAST(op)).ob_fval }; + return (*_PyFloat_CAST(op)).ob_fval; #[cfg(GraalPy)] return PyFloat_AsDouble(op); } diff --git a/pyo3-ffi/src/cpython/frameobject.rs b/pyo3-ffi/src/cpython/frameobject.rs index c2e273f0769..e9b9c183f37 100644 --- a/pyo3-ffi/src/cpython/frameobject.rs +++ b/pyo3-ffi/src/cpython/frameobject.rs @@ -66,7 +66,7 @@ extern "C" { #[inline] pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyFrame_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyFrame_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/cpython/funcobject.rs b/pyo3-ffi/src/cpython/funcobject.rs index bccc07474d9..25de30d57f7 100644 --- a/pyo3-ffi/src/cpython/funcobject.rs +++ b/pyo3-ffi/src/cpython/funcobject.rs @@ -70,7 +70,7 @@ extern "C" { #[cfg(not(all(PyPy, not(Py_3_8))))] #[inline] pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { - unsafe { (crate::Py_TYPE(op) == addr_of_mut!(PyFunction_Type)) as c_int } + (crate::Py_TYPE(op) == addr_of_mut!(PyFunction_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/cpython/genobject.rs b/pyo3-ffi/src/cpython/genobject.rs index 4170953debe..c9d419e3782 100644 --- a/pyo3-ffi/src/cpython/genobject.rs +++ b/pyo3-ffi/src/cpython/genobject.rs @@ -42,12 +42,12 @@ extern "C" { #[inline] pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyGen_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyGen_Type)) } #[inline] pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyGen_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyGen_Type)) as c_int } extern "C" { @@ -72,7 +72,7 @@ extern "C" { #[inline] pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyCoro_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyCoro_Type)) } // skipped _PyCoro_GetAwaitableIter @@ -92,7 +92,7 @@ extern "C" { #[inline] pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyAsyncGen_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyAsyncGen_Type)) } // skipped _PyAsyncGenValueWrapperNew diff --git a/pyo3-ffi/src/cpython/listobject.rs b/pyo3-ffi/src/cpython/listobject.rs index 803fb9c835e..694e6bc4290 100644 --- a/pyo3-ffi/src/cpython/listobject.rs +++ b/pyo3-ffi/src/cpython/listobject.rs @@ -23,20 +23,18 @@ pub struct PyListObject { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - unsafe { *(*(op as *mut PyListObject)).ob_item.offset(i) } + *(*(op as *mut PyListObject)).ob_item.offset(i) } /// Macro, *only* to be used to fill in brand new lists #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - unsafe { - *(*(op as *mut PyListObject)).ob_item.offset(i) = v; - } + *(*(op as *mut PyListObject)).ob_item.offset(i) = v; } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { - unsafe { Py_SIZE(op) } + Py_SIZE(op) } diff --git a/pyo3-ffi/src/cpython/methodobject.rs b/pyo3-ffi/src/cpython/methodobject.rs index 5d4fd0ec352..97ad9ce35f0 100644 --- a/pyo3-ffi/src/cpython/methodobject.rs +++ b/pyo3-ffi/src/cpython/methodobject.rs @@ -17,61 +17,55 @@ extern "C" { #[inline] pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyCMethod_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyCMethod_Type)) as c_int } #[inline] pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyCMethod_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyCMethod_Type)) } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer { - unsafe { - debug_assert_eq!(PyCMethod_Check(func), 1); + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - (*(*func).m_ml).ml_meth - } + let func = func.cast::(); + (*(*func).m_ml).ml_meth } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject { - unsafe { - debug_assert_eq!(PyCMethod_Check(func), 1); + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - if (*(*func).m_ml).ml_flags & METH_STATIC != 0 { - std::ptr::null_mut() - } else { - (*func).m_self - } + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_STATIC != 0 { + std::ptr::null_mut() + } else { + (*func).m_self } } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int { - debug_assert_eq!(unsafe { PyCMethod_Check(func) }, 1); + debug_assert_eq!(PyCMethod_Check(func), 1); let func = func.cast::(); - unsafe { (*(*func).m_ml).ml_flags } + (*(*func).m_ml).ml_flags } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject { - unsafe { - debug_assert_eq!(PyCMethod_Check(func), 1); + debug_assert_eq!(PyCMethod_Check(func), 1); - let func = func.cast::(); - if (*(*func).m_ml).ml_flags & METH_METHOD != 0 { - let func = func.cast::(); - (*func).mm_class - } else { - std::ptr::null_mut() - } + let func = func.cast::(); + if (*(*func).m_ml).ml_flags & METH_METHOD != 0 { + let func = func.cast::(); + (*func).mm_class + } else { + std::ptr::null_mut() } } diff --git a/pyo3-ffi/src/cpython/object.rs b/pyo3-ffi/src/cpython/object.rs index 4dd462ed3d5..4e6932da789 100644 --- a/pyo3-ffi/src/cpython/object.rs +++ b/pyo3-ffi/src/cpython/object.rs @@ -326,11 +326,9 @@ impl Default for PyHeapTypeObject { #[inline] #[cfg(not(Py_3_11))] pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef { - unsafe { - let py_type = object::Py_TYPE(etype as *mut object::PyObject); - let ptr = etype.offset((*py_type).tp_basicsize); - ptr as *mut PyMemberDef - } + let py_type = object::Py_TYPE(etype as *mut object::PyObject); + let ptr = etype.offset((*py_type).tp_basicsize); + ptr as *mut PyMemberDef } // skipped private _PyType_Name diff --git a/pyo3-ffi/src/cpython/objimpl.rs b/pyo3-ffi/src/cpython/objimpl.rs index 7044c7c2ea0..14f7121a202 100644 --- a/pyo3-ffi/src/cpython/objimpl.rs +++ b/pyo3-ffi/src/cpython/objimpl.rs @@ -45,13 +45,11 @@ extern "C" { #[inline] #[cfg(not(Py_3_9))] pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int { - unsafe { - (crate::PyType_IS_GC(Py_TYPE(o)) != 0 - && match (*Py_TYPE(o)).tp_is_gc { - Some(tp_is_gc) => tp_is_gc(o) != 0, - None => true, - }) as c_int - } + (crate::PyType_IS_GC(Py_TYPE(o)) != 0 + && match (*Py_TYPE(o)).tp_is_gc { + Some(tp_is_gc) => tp_is_gc(o) != 0, + None => true, + }) as c_int } #[cfg(not(Py_3_11))] @@ -62,15 +60,13 @@ extern "C" { #[inline] pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int { - unsafe { ((*t).tp_weaklistoffset > 0) as c_int } + ((*t).tp_weaklistoffset > 0) as c_int } #[inline] pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject { - unsafe { - let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset; - o.offset(weaklistoffset) as *mut *mut PyObject - } + let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset; + o.offset(weaklistoffset) as *mut *mut PyObject } // skipped PyUnstable_Object_GC_NewWithExtraData diff --git a/pyo3-ffi/src/cpython/pydebug.rs b/pyo3-ffi/src/cpython/pydebug.rs index 2dc27401ddc..a42848e8fdb 100644 --- a/pyo3-ffi/src/cpython/pydebug.rs +++ b/pyo3-ffi/src/cpython/pydebug.rs @@ -63,12 +63,10 @@ extern "C" { #[cfg(not(Py_3_11))] #[inline(always)] pub unsafe fn Py_GETENV(name: *const c_char) -> *mut c_char { - unsafe { - #[allow(deprecated)] - if Py_IgnoreEnvironmentFlag != 0 { - std::ptr::null_mut() - } else { - libc::getenv(name) - } + #[allow(deprecated)] + if Py_IgnoreEnvironmentFlag != 0 { + std::ptr::null_mut() + } else { + libc::getenv(name) } } diff --git a/pyo3-ffi/src/cpython/pythonrun.rs b/pyo3-ffi/src/cpython/pythonrun.rs index 9edeaceef6a..fe78f55ca07 100644 --- a/pyo3-ffi/src/cpython/pythonrun.rs +++ b/pyo3-ffi/src/cpython/pythonrun.rs @@ -137,7 +137,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { - unsafe { Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1) } + Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1) } #[inline] @@ -148,7 +148,7 @@ pub unsafe fn Py_CompileStringFlags( s: c_int, f: *mut PyCompilerFlags, ) -> *mut PyObject { - unsafe { Py_CompileStringExFlags(string, p, s, f, -1) } + Py_CompileStringExFlags(string, p, s, f, -1) } // skipped _Py_SourceAsString diff --git a/pyo3-ffi/src/cpython/tupleobject.rs b/pyo3-ffi/src/cpython/tupleobject.rs index ef2df625ece..9616d4372cc 100644 --- a/pyo3-ffi/src/cpython/tupleobject.rs +++ b/pyo3-ffi/src/cpython/tupleobject.rs @@ -17,20 +17,20 @@ pub struct PyTupleObject { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { - unsafe { Py_SIZE(op) } + Py_SIZE(op) } #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - unsafe { *(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i) } + *(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i) } /// Macro, *only* to be used to fill in brand new tuples #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - unsafe { *(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v }; + *(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v; } // skipped _PyTuple_DebugMallocStats diff --git a/pyo3-ffi/src/cpython/unicodeobject.rs b/pyo3-ffi/src/cpython/unicodeobject.rs index d033443e0f9..3527a5aeadb 100644 --- a/pyo3-ffi/src/cpython/unicodeobject.rs +++ b/pyo3-ffi/src/cpython/unicodeobject.rs @@ -166,57 +166,51 @@ struct PyASCIIObjectState { impl PyASCIIObjectState { #[inline] unsafe fn interned(&self) -> c_uint { - unsafe { - std::mem::transmute( - self.bitfield - .get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32, - ) - } + std::mem::transmute( + self.bitfield + .get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32, + ) } #[inline] unsafe fn set_interned(&mut self, val: c_uint) { - let val: u32 = unsafe { std::mem::transmute(val) }; + let val: u32 = std::mem::transmute(val); self.bitfield .set(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH, val as u64) } #[inline] unsafe fn kind(&self) -> c_uint { - unsafe { std::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32) } + std::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32) } #[inline] unsafe fn set_kind(&mut self, val: c_uint) { - let val: u32 = unsafe { std::mem::transmute(val) }; + let val: u32 = std::mem::transmute(val); self.bitfield .set(STATE_KIND_INDEX, STATE_KIND_WIDTH, val as u64) } #[inline] unsafe fn compact(&self) -> c_uint { - unsafe { - std::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32) - } + std::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32) } #[inline] unsafe fn set_compact(&mut self, val: c_uint) { - let val: u32 = unsafe { std::mem::transmute(val) }; + let val: u32 = std::mem::transmute(val); self.bitfield .set(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH, val as u64) } #[inline] unsafe fn ascii(&self) -> c_uint { - unsafe { - std::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32) - } + std::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32) } #[inline] unsafe fn set_ascii(&mut self, val: c_uint) { - let val: u32 = unsafe { std::mem::transmute(val) }; + let val: u32 = std::mem::transmute(val); self.bitfield .set(STATE_ASCII_INDEX, STATE_ASCII_WIDTH, val as u64) } @@ -224,19 +218,15 @@ impl PyASCIIObjectState { #[cfg(not(Py_3_12))] #[inline] unsafe fn ready(&self) -> c_uint { - unsafe { - std::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32) - } + std::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32) } #[cfg(not(Py_3_12))] #[inline] unsafe fn set_ready(&mut self, val: c_uint) { - unsafe { - let val: u32 = std::mem::transmute(val); - self.bitfield - .set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64) - } + let val: u32 = std::mem::transmute(val); + self.bitfield + .set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64) } } @@ -289,7 +279,7 @@ impl PyASCIIObject { /// [`SSTATE_INTERNED_IMMORTAL`], or [`SSTATE_INTERNED_IMMORTAL_STATIC`]. #[inline] pub unsafe fn interned(&self) -> c_uint { - unsafe { PyASCIIObjectState::from(self.state).interned() } + PyASCIIObjectState::from(self.state).interned() } #[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12 @@ -301,7 +291,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_interned(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - unsafe { state.set_interned(val) }; + state.set_interned(val); self.state = u32::from(state); } @@ -312,7 +302,7 @@ impl PyASCIIObject { /// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`]. #[inline] pub unsafe fn kind(&self) -> c_uint { - unsafe { PyASCIIObjectState::from(self.state).kind() } + PyASCIIObjectState::from(self.state).kind() } /// Set the `kind` field of the [`PyASCIIObject`] state bitfield. @@ -323,7 +313,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_kind(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - unsafe { state.set_kind(val) }; + state.set_kind(val); self.state = u32::from(state); } @@ -332,7 +322,7 @@ impl PyASCIIObject { /// Returns either `0` or `1`. #[inline] pub unsafe fn compact(&self) -> c_uint { - unsafe { PyASCIIObjectState::from(self.state).compact() } + PyASCIIObjectState::from(self.state).compact() } /// Set the `compact` flag of the [`PyASCIIObject`] state bitfield. @@ -341,7 +331,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_compact(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - unsafe { state.set_compact(val) }; + state.set_compact(val); self.state = u32::from(state); } @@ -350,7 +340,7 @@ impl PyASCIIObject { /// Returns either `0` or `1`. #[inline] pub unsafe fn ascii(&self) -> c_uint { - unsafe { PyASCIIObjectState::from(self.state).ascii() } + PyASCIIObjectState::from(self.state).ascii() } /// Set the `ascii` flag of the [`PyASCIIObject`] state bitfield. @@ -359,7 +349,7 @@ impl PyASCIIObject { #[inline] pub unsafe fn set_ascii(&mut self, val: c_uint) { let mut state = PyASCIIObjectState::from(self.state); - unsafe { state.set_ascii(val) }; + state.set_ascii(val); self.state = u32::from(state); } @@ -369,7 +359,7 @@ impl PyASCIIObject { #[cfg(not(Py_3_12))] #[inline] pub unsafe fn ready(&self) -> c_uint { - unsafe { PyASCIIObjectState::from(self.state).ready() } + PyASCIIObjectState::from(self.state).ready() } /// Set the `ready` flag of the [`PyASCIIObject`] state bitfield. @@ -378,11 +368,9 @@ impl PyASCIIObject { #[cfg(not(Py_3_12))] #[inline] pub unsafe fn set_ready(&mut self, val: c_uint) { - unsafe { - let mut state = PyASCIIObjectState::from(self.state); - state.set_ready(val); - self.state = u32::from(state); - } + let mut state = PyASCIIObjectState::from(self.state); + state.set_ready(val); + self.state = u32::from(state); } } @@ -428,27 +416,23 @@ pub const SSTATE_INTERNED_IMMORTAL_STATIC: c_uint = 3; #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint { - unsafe { - debug_assert!(crate::PyUnicode_Check(op) != 0); - #[cfg(not(Py_3_12))] - debug_assert!(PyUnicode_IS_READY(op) != 0); + debug_assert!(crate::PyUnicode_Check(op) != 0); + #[cfg(not(Py_3_12))] + debug_assert!(PyUnicode_IS_READY(op) != 0); - (*(op as *mut PyASCIIObject)).ascii() - } + (*(op as *mut PyASCIIObject)).ascii() } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_COMPACT(op: *mut PyObject) -> c_uint { - unsafe { (*(op as *mut PyASCIIObject)).compact() } + (*(op as *mut PyASCIIObject)).compact() } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_IS_COMPACT_ASCII(op: *mut PyObject) -> c_uint { - (unsafe { (*(op as *mut PyASCIIObject)).ascii() != 0 } - && unsafe { PyUnicode_IS_COMPACT(op) != 0 }) - .into() + ((*(op as *mut PyASCIIObject)).ascii() != 0 && PyUnicode_IS_COMPACT(op) != 0).into() } #[cfg(not(Py_3_12))] @@ -462,64 +446,58 @@ pub const PyUnicode_4BYTE_KIND: c_uint = 4; #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_1BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS1 { - unsafe { PyUnicode_DATA(op) as *mut Py_UCS1 } + PyUnicode_DATA(op) as *mut Py_UCS1 } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_2BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS2 { - unsafe { PyUnicode_DATA(op) as *mut Py_UCS2 } + PyUnicode_DATA(op) as *mut Py_UCS2 } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_4BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS4 { - unsafe { PyUnicode_DATA(op) as *mut Py_UCS4 } + PyUnicode_DATA(op) as *mut Py_UCS4 } #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint { - debug_assert!(unsafe { crate::PyUnicode_Check(op) } != 0); + debug_assert!(crate::PyUnicode_Check(op) != 0); #[cfg(not(Py_3_12))] - debug_assert!(unsafe { PyUnicode_IS_READY(op) } != 0); + debug_assert!(PyUnicode_IS_READY(op) != 0); - unsafe { (*(op as *mut PyASCIIObject)).kind() } + (*(op as *mut PyASCIIObject)).kind() } #[cfg(not(GraalPy))] #[inline] pub unsafe fn _PyUnicode_COMPACT_DATA(op: *mut PyObject) -> *mut c_void { - unsafe { - if PyUnicode_IS_ASCII(op) != 0 { - (op as *mut PyASCIIObject).offset(1) as *mut c_void - } else { - (op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void - } + if PyUnicode_IS_ASCII(op) != 0 { + (op as *mut PyASCIIObject).offset(1) as *mut c_void + } else { + (op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void } } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn _PyUnicode_NONCOMPACT_DATA(op: *mut PyObject) -> *mut c_void { - unsafe { - debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null()); + debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null()); - (*(op as *mut PyUnicodeObject)).data.any - } + (*(op as *mut PyUnicodeObject)).data.any } #[cfg(not(any(GraalPy, PyPy)))] #[inline] pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { - unsafe { - debug_assert!(crate::PyUnicode_Check(op) != 0); + debug_assert!(crate::PyUnicode_Check(op) != 0); - if PyUnicode_IS_COMPACT(op) != 0 { - _PyUnicode_COMPACT_DATA(op) - } else { - _PyUnicode_NONCOMPACT_DATA(op) - } + if PyUnicode_IS_COMPACT(op) != 0 { + _PyUnicode_COMPACT_DATA(op) + } else { + _PyUnicode_NONCOMPACT_DATA(op) } } @@ -530,11 +508,11 @@ pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void { #[cfg(not(GraalPy))] #[inline] pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t { - debug_assert!(unsafe { crate::PyUnicode_Check(op) } != 0); + debug_assert!(crate::PyUnicode_Check(op) != 0); #[cfg(not(Py_3_12))] - debug_assert!(unsafe { PyUnicode_IS_READY(op) } != 0); + debug_assert!(PyUnicode_IS_READY(op) != 0); - unsafe { (*(op as *mut PyASCIIObject)).length } + (*(op as *mut PyASCIIObject)).length } #[cfg(any(Py_3_12, GraalPy))] @@ -547,7 +525,7 @@ pub unsafe fn PyUnicode_IS_READY(_op: *mut PyObject) -> c_uint { #[cfg(not(any(GraalPy, Py_3_12)))] #[inline] pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint { - unsafe { (*(op as *mut PyASCIIObject)).ready() } + (*(op as *mut PyASCIIObject)).ready() } #[cfg(any(Py_3_12, GraalPy))] @@ -559,14 +537,12 @@ pub unsafe fn PyUnicode_READY(_op: *mut PyObject) -> c_int { #[cfg(not(any(Py_3_12, GraalPy)))] #[inline] pub unsafe fn PyUnicode_READY(op: *mut PyObject) -> c_int { - unsafe { - debug_assert!(crate::PyUnicode_Check(op) != 0); + debug_assert!(crate::PyUnicode_Check(op) != 0); - if PyUnicode_IS_READY(op) != 0 { - 0 - } else { - _PyUnicode_Ready(op) - } + if PyUnicode_IS_READY(op) != 0 { + 0 + } else { + _PyUnicode_Ready(op) } } diff --git a/pyo3-ffi/src/datetime.rs b/pyo3-ffi/src/datetime.rs index f70ea93607a..7f2d7958364 100644 --- a/pyo3-ffi/src/datetime.rs +++ b/pyo3-ffi/src/datetime.rs @@ -118,7 +118,7 @@ pub struct PyDateTime_DateTime { /// Returns a signed integer greater than 0. pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { // This should work for Date or DateTime - let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; + let data = (*(o as *mut PyDateTime_Date)).data; (c_int::from(data[0]) << 8) | c_int::from(data[1]) } @@ -127,7 +127,7 @@ pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int { /// Retrieve the month component of a `PyDateTime_Date` or `PyDateTime_DateTime`. /// Returns a signed integer in the range `[1, 12]`. pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { - let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; + let data = (*(o as *mut PyDateTime_Date)).data; c_int::from(data[2]) } @@ -136,7 +136,7 @@ pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int { /// Retrieve the day component of a `PyDateTime_Date` or `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[1, 31]`. pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int { - let data = unsafe { (*(o as *mut PyDateTime_Date)).data }; + let data = (*(o as *mut PyDateTime_Date)).data; c_int::from(data[3]) } @@ -181,10 +181,10 @@ macro_rules! _PyDateTime_GET_FOLD { #[cfg(not(any(PyPy, GraalPy)))] macro_rules! _PyDateTime_GET_TZINFO { ($o: expr) => { - if unsafe { (*$o).hastzinfo } != 0 { - unsafe { (*$o).tzinfo } + if (*$o).hastzinfo != 0 { + (*$o).tzinfo } else { - unsafe { $crate::Py_None() } + $crate::Py_None() } }; } @@ -195,7 +195,7 @@ macro_rules! _PyDateTime_GET_TZINFO { /// Retrieve the hour component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 23]` pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } + _PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } #[inline] @@ -203,7 +203,7 @@ pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int { /// Retrieve the minute component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } + _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } #[inline] @@ -211,7 +211,7 @@ pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int { /// Retrieve the second component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } + _PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } #[inline] @@ -219,9 +219,7 @@ pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int { /// Retrieve the microsecond component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 999999]` pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { - unsafe { - _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) - } + _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) } #[inline] @@ -229,7 +227,7 @@ pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int { /// Retrieve the fold component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 1]` pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar { - unsafe { _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) } + _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) } #[inline] @@ -247,7 +245,7 @@ pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { /// Retrieve the hour component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 23]` pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0) } + _PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0) } #[inline] @@ -255,7 +253,7 @@ pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int { /// Retrieve the minute component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0) } + _PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0) } #[inline] @@ -263,7 +261,7 @@ pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int { /// Retrieve the second component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 59]` pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0) } + _PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0) } #[inline] @@ -271,7 +269,7 @@ pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int { /// Retrieve the microsecond component of a `PyDateTime_DateTime`. /// Returns a signed integer in the interval `[0, 999999]` pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { - unsafe { _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) } + _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) } #[cfg(not(any(PyPy, GraalPy)))] @@ -279,7 +277,7 @@ pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int { /// Retrieve the fold component of a `PyDateTime_Time`. /// Returns a signed integer in the interval `[0, 1]` pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar { - unsafe { _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) } + _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) } #[inline] @@ -295,7 +293,7 @@ pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { #[cfg(not(any(PyPy, GraalPy)))] macro_rules! _access_field { ($obj:expr, $type: ident, $field:ident) => { - unsafe { (*($obj as *mut $type)).$field } + (*($obj as *mut $type)).$field }; } @@ -597,7 +595,7 @@ pub const PyDateTime_CAPSULE_NAME: &CStr = c_str!("datetime.datetime_CAPI"); /// `PyDateTime_IMPORT` is called #[inline] pub unsafe fn PyDateTimeAPI() -> *mut PyDateTime_CAPI { - unsafe { *PyDateTimeAPI_impl.ptr.get() } + *PyDateTimeAPI_impl.ptr.get() } /// Populates the `PyDateTimeAPI` object @@ -609,9 +607,8 @@ pub unsafe fn PyDateTime_IMPORT() { let py_datetime_c_api = PyDateTime_Import(); #[cfg(not(PyPy))] - let py_datetime_c_api = unsafe { - PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI - }; + let py_datetime_c_api = + PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI; if py_datetime_c_api.is_null() { return; @@ -620,7 +617,7 @@ pub unsafe fn PyDateTime_IMPORT() { // Protect against race conditions when the datetime API is concurrently // initialized in multiple threads. UnsafeCell.get() cannot panic so this // won't panic either. - PyDateTimeAPI_impl.once.call_once(|| unsafe { + PyDateTimeAPI_impl.once.call_once(|| { *PyDateTimeAPI_impl.ptr.get() = py_datetime_c_api; }); } @@ -628,7 +625,7 @@ pub unsafe fn PyDateTime_IMPORT() { #[inline] pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject { - unsafe { (*PyDateTimeAPI()).TimeZone_UTC } + (*PyDateTimeAPI()).TimeZone_UTC } /// Type Check macros @@ -639,61 +636,61 @@ pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject { #[inline] /// Check if `op` is a `PyDateTimeAPI.DateType` or subtype. pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int } + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`. pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DateType) as c_int } + (Py_TYPE(op) == (*PyDateTimeAPI()).DateType) as c_int } #[inline] /// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype. pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int } + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`. pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DateTimeType) as c_int } + (Py_TYPE(op) == (*PyDateTimeAPI()).DateTimeType) as c_int } #[inline] /// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype. pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int } + PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`. pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).TimeType) as c_int } + (Py_TYPE(op) == (*PyDateTimeAPI()).TimeType) as c_int } #[inline] /// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype. pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int } + PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`. pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).DeltaType) as c_int } + (Py_TYPE(op) == (*PyDateTimeAPI()).DeltaType) as c_int } #[inline] /// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype. pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int } + PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int } #[inline] /// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`. pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == (*PyDateTimeAPI()).TZInfoType) as c_int } + (Py_TYPE(op) == (*PyDateTimeAPI()).TZInfoType) as c_int } // skipped non-limited PyDate_FromDate @@ -704,30 +701,26 @@ pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int { // skipped non-limited PyDelta_FromDSU pub unsafe fn PyTimeZone_FromOffset(offset: *mut PyObject) -> *mut PyObject { - unsafe { ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, std::ptr::null_mut()) } + ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, std::ptr::null_mut()) } pub unsafe fn PyTimeZone_FromOffsetAndName( offset: *mut PyObject, name: *mut PyObject, ) -> *mut PyObject { - unsafe { ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name) } + ((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name) } #[cfg(not(PyPy))] pub unsafe fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject { - unsafe { - let f = (*PyDateTimeAPI()).DateTime_FromTimestamp; - f((*PyDateTimeAPI()).DateTimeType, args, std::ptr::null_mut()) - } + let f = (*PyDateTimeAPI()).DateTime_FromTimestamp; + f((*PyDateTimeAPI()).DateTimeType, args, std::ptr::null_mut()) } #[cfg(not(PyPy))] pub unsafe fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject { - unsafe { - let f = (*PyDateTimeAPI()).Date_FromTimestamp; - f((*PyDateTimeAPI()).DateType, args) - } + let f = (*PyDateTimeAPI()).Date_FromTimestamp; + f((*PyDateTimeAPI()).DateType, args) } #[cfg(PyPy)] diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index b3d3ba02756..710be80243f 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -11,12 +11,12 @@ extern "C" { #[inline] pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) } #[inline] pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyDict_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyDict_Type)) as c_int } extern "C" { @@ -85,22 +85,22 @@ extern "C" { #[inline] pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictKeys_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyDictKeys_Type)) as c_int } #[inline] pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictValues_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyDictValues_Type)) as c_int } #[inline] pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyDictItems_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyDictItems_Type)) as c_int } #[inline] pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int { - unsafe { (PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int } + (PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int } #[cfg_attr(windows, link(name = "pythonXY"))] diff --git a/pyo3-ffi/src/floatobject.rs b/pyo3-ffi/src/floatobject.rs index 16c5927a23f..65fc1d4c316 100644 --- a/pyo3-ffi/src/floatobject.rs +++ b/pyo3-ffi/src/floatobject.rs @@ -14,12 +14,12 @@ extern "C" { #[inline] pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyFloat_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyFloat_Type)) } #[inline] pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyFloat_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyFloat_Type)) as c_int } // skipped Py_RETURN_NAN diff --git a/pyo3-ffi/src/import.rs b/pyo3-ffi/src/import.rs index 02a9b5d89de..e15a37b0a72 100644 --- a/pyo3-ffi/src/import.rs +++ b/pyo3-ffi/src/import.rs @@ -62,7 +62,7 @@ pub unsafe fn PyImport_ImportModuleEx( locals: *mut PyObject, fromlist: *mut PyObject, ) -> *mut PyObject { - unsafe { PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) } + PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0) } extern "C" { diff --git a/pyo3-ffi/src/iterobject.rs b/pyo3-ffi/src/iterobject.rs index fae92d5ef42..aa0c7b26db1 100644 --- a/pyo3-ffi/src/iterobject.rs +++ b/pyo3-ffi/src/iterobject.rs @@ -10,7 +10,7 @@ extern "C" { #[inline] pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PySeqIter_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PySeqIter_Type)) as c_int } extern "C" { @@ -20,7 +20,7 @@ extern "C" { #[inline] pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyCallIter_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyCallIter_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/lib.rs b/pyo3-ffi/src/lib.rs index 8218d4f83c4..b14fe1e8611 100644 --- a/pyo3-ffi/src/lib.rs +++ b/pyo3-ffi/src/lib.rs @@ -1,5 +1,4 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] // necessary for MSRV 1.63 to build //! Raw FFI declarations for Python's C API. //! //! PyO3 can be used to write native Python modules or run Python code and modules from Rust. @@ -331,6 +330,11 @@ clippy::missing_safety_doc )] #![warn(elided_lifetimes_in_paths, unused_lifetimes)] +// This crate is a hand-maintained translation of CPython's headers, so requiring "unsafe" +// blocks within those translations increases maintenance burden without providing any +// additional safety. The safety of the functions in this crate is determined by the +// original CPython headers +#![allow(unsafe_op_in_unsafe_fn)] // Until `extern type` is stabilized, use the recommended approach to // model opaque types: diff --git a/pyo3-ffi/src/listobject.rs b/pyo3-ffi/src/listobject.rs index 70179afaf9f..881a8a8707b 100644 --- a/pyo3-ffi/src/listobject.rs +++ b/pyo3-ffi/src/listobject.rs @@ -13,12 +13,12 @@ extern "C" { #[inline] pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) } #[inline] pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyList_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyList_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/longobject.rs b/pyo3-ffi/src/longobject.rs index b018ac6db11..68b4ecba540 100644 --- a/pyo3-ffi/src/longobject.rs +++ b/pyo3-ffi/src/longobject.rs @@ -8,12 +8,12 @@ opaque_struct!(PyLongObject); #[inline] pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) } #[inline] pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyLong_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyLong_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/memoryobject.rs b/pyo3-ffi/src/memoryobject.rs index 6371ec6b326..b7ef9e2ef1d 100644 --- a/pyo3-ffi/src/memoryobject.rs +++ b/pyo3-ffi/src/memoryobject.rs @@ -14,7 +14,7 @@ extern "C" { #[inline] pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyMemoryView_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyMemoryView_Type)) as c_int } // skipped non-limited PyMemoryView_GET_BUFFER diff --git a/pyo3-ffi/src/methodobject.rs b/pyo3-ffi/src/methodobject.rs index 25226b3172f..3dfbbb5a208 100644 --- a/pyo3-ffi/src/methodobject.rs +++ b/pyo3-ffi/src/methodobject.rs @@ -24,19 +24,19 @@ extern "C" { #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } + (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, ptr::addr_of_mut!(PyCFunction_Type)) } + PyObject_TypeCheck(op, ptr::addr_of_mut!(PyCFunction_Type)) } #[cfg(not(Py_3_9))] #[inline] pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } + (Py_TYPE(op) == ptr::addr_of_mut!(PyCFunction_Type)) as c_int } pub type PyCFunction = @@ -224,7 +224,7 @@ extern "C" { #[cfg(Py_3_9)] #[inline] pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject { - unsafe { PyCFunction_NewEx(ml, slf, std::ptr::null_mut()) } + PyCFunction_NewEx(ml, slf, std::ptr::null_mut()) } #[cfg(Py_3_9)] @@ -234,7 +234,7 @@ pub unsafe fn PyCFunction_NewEx( slf: *mut PyObject, module: *mut PyObject, ) -> *mut PyObject { - unsafe { PyCMethod_New(ml, slf, module, std::ptr::null_mut()) } + PyCMethod_New(ml, slf, module, std::ptr::null_mut()) } #[cfg(Py_3_9)] diff --git a/pyo3-ffi/src/modsupport.rs b/pyo3-ffi/src/modsupport.rs index 814612cf1d4..4a18d30f97c 100644 --- a/pyo3-ffi/src/modsupport.rs +++ b/pyo3-ffi/src/modsupport.rs @@ -120,29 +120,25 @@ pub unsafe fn PyModule_FromDefAndSpec2( #[inline] pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject { - unsafe { - PyModule_Create2( - module, - if cfg!(Py_LIMITED_API) { - PYTHON_ABI_VERSION - } else { - PYTHON_API_VERSION - }, - ) - } + PyModule_Create2( + module, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) } #[inline] pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject) -> *mut PyObject { - unsafe { - PyModule_FromDefAndSpec2( - def, - spec, - if cfg!(Py_LIMITED_API) { - PYTHON_ABI_VERSION - } else { - PYTHON_API_VERSION - }, - ) - } + PyModule_FromDefAndSpec2( + def, + spec, + if cfg!(Py_LIMITED_API) { + PYTHON_ABI_VERSION + } else { + PYTHON_API_VERSION + }, + ) } diff --git a/pyo3-ffi/src/moduleobject.rs b/pyo3-ffi/src/moduleobject.rs index 46a8509d9d8..2417664a421 100644 --- a/pyo3-ffi/src/moduleobject.rs +++ b/pyo3-ffi/src/moduleobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(PyModule_Type)) } + PyObject_TypeCheck(op, addr_of_mut!(PyModule_Type)) } #[inline] pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyModule_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyModule_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/object.rs b/pyo3-ffi/src/object.rs index be81326328f..087cd32920c 100644 --- a/pyo3-ffi/src/object.rs +++ b/pyo3-ffi/src/object.rs @@ -159,7 +159,7 @@ extern "C" { #[inline] pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { #[cfg(Py_GIL_DISABLED)] - unsafe { + { let local = (*ob).ob_ref_local.load(Relaxed); if local == _Py_IMMORTAL_REFCNT_LOCAL { return _Py_IMMORTAL_REFCNT; @@ -170,26 +170,26 @@ pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t { #[cfg(all(not(Py_GIL_DISABLED), Py_3_12))] { - unsafe { (*ob).ob_refcnt.ob_refcnt } + (*ob).ob_refcnt.ob_refcnt } #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), not(GraalPy)))] { - unsafe { (*ob).ob_refcnt } + (*ob).ob_refcnt } #[cfg(all(not(Py_GIL_DISABLED), not(Py_3_12), GraalPy))] { - unsafe { _Py_REFCNT(ob) } + _Py_REFCNT(ob) } } #[inline] pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject { #[cfg(not(GraalPy))] - return unsafe { (*ob).ob_type }; + return (*ob).ob_type; #[cfg(GraalPy)] - return unsafe { _Py_TYPE(ob) }; + return _Py_TYPE(ob); } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -203,34 +203,32 @@ extern "C" { #[inline] pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t { #[cfg(not(GraalPy))] - unsafe { + { debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyLong_Type)); debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyBool_Type)); (*ob.cast::()).ob_size } #[cfg(GraalPy)] - unsafe { - _Py_SIZE(ob) - } + _Py_SIZE(ob) } #[inline(always)] #[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int { #[cfg(target_pointer_width = "64")] - unsafe { + { (((*op).ob_refcnt.ob_refcnt as crate::PY_INT32_T) < 0) as c_int } #[cfg(target_pointer_width = "32")] - unsafe { + { ((*op).ob_refcnt.ob_refcnt == _Py_IMMORTAL_REFCNT) as c_int } } #[inline] pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { - unsafe { (Py_TYPE(ob) == tp) as c_int } + (Py_TYPE(ob) == tp) as c_int } // skipped _Py_SetRefCnt @@ -381,7 +379,7 @@ extern "C" { #[inline] pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int { - unsafe { (Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int } + (Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int } #[cfg_attr(windows, link(name = "pythonXY"))] @@ -623,62 +621,60 @@ extern "C" { #[inline(always)] pub unsafe fn Py_INCREF(op: *mut PyObject) { - unsafe { - // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting - // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. - #[cfg(any( - Py_GIL_DISABLED, - Py_LIMITED_API, - py_sys_config = "Py_REF_DEBUG", - GraalPy - ))] + // On limited API, the free-threaded build, or with refcount debugging, let the interpreter do refcounting + // TODO: reimplement the logic in the header in the free-threaded build, for a little bit of performance. + #[cfg(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + ))] + { + // _Py_IncRef was added to the ABI in 3.10; skips null checks + #[cfg(all(Py_3_10, not(PyPy)))] { - // _Py_IncRef was added to the ABI in 3.10; skips null checks - #[cfg(all(Py_3_10, not(PyPy)))] - { - _Py_IncRef(op); - } - - #[cfg(any(not(Py_3_10), PyPy))] - { - Py_IncRef(op); - } + _Py_IncRef(op); } - // version-specific builds are allowed to directly manipulate the reference count - #[cfg(not(any( - Py_GIL_DISABLED, - Py_LIMITED_API, - py_sys_config = "Py_REF_DEBUG", - GraalPy - )))] + #[cfg(any(not(Py_3_10), PyPy))] { - #[cfg(all(Py_3_12, target_pointer_width = "64"))] - { - let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; - let new_refcnt = cur_refcnt.wrapping_add(1); - if new_refcnt == 0 { - return; - } - (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt; - } + Py_IncRef(op); + } + } - #[cfg(all(Py_3_12, target_pointer_width = "32"))] - { - if _Py_IsImmortal(op) != 0 { - return; - } - (*op).ob_refcnt.ob_refcnt += 1 + // version-specific builds are allowed to directly manipulate the reference count + #[cfg(not(any( + Py_GIL_DISABLED, + Py_LIMITED_API, + py_sys_config = "Py_REF_DEBUG", + GraalPy + )))] + { + #[cfg(all(Py_3_12, target_pointer_width = "64"))] + { + let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN]; + let new_refcnt = cur_refcnt.wrapping_add(1); + if new_refcnt == 0 { + return; } + (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt; + } - #[cfg(not(Py_3_12))] - { - (*op).ob_refcnt += 1 + #[cfg(all(Py_3_12, target_pointer_width = "32"))] + { + if _Py_IsImmortal(op) != 0 { + return; } + (*op).ob_refcnt.ob_refcnt += 1 + } - // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue - // or submit a PR supporting Py_STATS build option and pystats.h + #[cfg(not(Py_3_12))] + { + (*op).ob_refcnt += 1 } + + // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue + // or submit a PR supporting Py_STATS build option and pystats.h } } @@ -697,7 +693,7 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), GraalPy ))] - unsafe { + { // _Py_DecRef was added to the ABI in 3.10; skips null checks #[cfg(all(Py_3_10, not(PyPy)))] { @@ -716,7 +712,7 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)), GraalPy )))] - unsafe { + { #[cfg(Py_3_12)] if _Py_IsImmortal(op) != 0 { return; @@ -757,26 +753,24 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) { #[inline] pub unsafe fn Py_CLEAR(op: *mut *mut PyObject) { - unsafe { - let tmp = *op; - if !tmp.is_null() { - *op = ptr::null_mut(); - Py_DECREF(tmp) - }; + let tmp = *op; + if !tmp.is_null() { + *op = ptr::null_mut(); + Py_DECREF(tmp); } } #[inline] pub unsafe fn Py_XINCREF(op: *mut PyObject) { if !op.is_null() { - unsafe { Py_INCREF(op) } + Py_INCREF(op) } } #[inline] pub unsafe fn Py_XDECREF(op: *mut PyObject) { if !op.is_null() { - unsafe { Py_DECREF(op) } + Py_DECREF(op) } } @@ -796,7 +790,7 @@ extern "C" { #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] #[inline] pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject { - unsafe { Py_INCREF(obj) }; + Py_INCREF(obj); obj } @@ -804,7 +798,7 @@ pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject { #[cfg_attr(docsrs, doc(cfg(Py_3_10)))] #[inline] pub unsafe fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject { - unsafe { Py_XINCREF(obj) }; + Py_XINCREF(obj); obj } @@ -862,7 +856,7 @@ pub unsafe fn Py_None() -> *mut PyObject { #[inline] pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int { - unsafe { Py_Is(x, Py_None()) } + Py_Is(x, Py_None()) } // skipped Py_RETURN_NONE @@ -880,13 +874,13 @@ extern "C" { #[inline] pub unsafe fn Py_NotImplemented() -> *mut PyObject { #[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))] - return unsafe { Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED) }; + return Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED); #[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))] return ptr::addr_of_mut!(_Py_NotImplementedStruct); #[cfg(GraalPy)] - return unsafe { _Py_NotImplementedStructReference }; + return _Py_NotImplementedStructReference; } // skipped Py_RETURN_NOTIMPLEMENTED @@ -912,35 +906,33 @@ pub enum PySendResult { #[inline] pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int { - unsafe { - #[cfg(Py_LIMITED_API)] - let flags = PyType_GetFlags(ty); + #[cfg(Py_LIMITED_API)] + let flags = PyType_GetFlags(ty); - #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] - let flags = (*ty).tp_flags.load(std::sync::atomic::Ordering::Relaxed); + #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))] + let flags = (*ty).tp_flags.load(std::sync::atomic::Ordering::Relaxed); - #[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))] - let flags = (*ty).tp_flags; + #[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))] + let flags = (*ty).tp_flags; - ((flags & feature) != 0) as c_int - } + ((flags & feature) != 0) as c_int } #[inline] pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int { - unsafe { PyType_HasFeature(t, f) } + PyType_HasFeature(t, f) } #[inline] pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) } // skipped _PyType_CAST #[inline] pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int { - unsafe { Py_IS_TYPE(op, ptr::addr_of_mut!(PyType_Type)) } + Py_IS_TYPE(op, ptr::addr_of_mut!(PyType_Type)) } extern "C" { diff --git a/pyo3-ffi/src/objimpl.rs b/pyo3-ffi/src/objimpl.rs index 9dd29f3899d..76835a6d158 100644 --- a/pyo3-ffi/src/objimpl.rs +++ b/pyo3-ffi/src/objimpl.rs @@ -61,7 +61,7 @@ extern "C" { #[inline] pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int { - unsafe { PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC) } + PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC) } extern "C" { diff --git a/pyo3-ffi/src/pycapsule.rs b/pyo3-ffi/src/pycapsule.rs index 8496245fb71..5b77841c23c 100644 --- a/pyo3-ffi/src/pycapsule.rs +++ b/pyo3-ffi/src/pycapsule.rs @@ -12,7 +12,7 @@ pub type PyCapsule_Destructor = unsafe extern "C" fn(o: *mut PyObject); #[inline] pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(ob) == addr_of_mut!(PyCapsule_Type)) as c_int } + (Py_TYPE(ob) == addr_of_mut!(PyCapsule_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/pyerrors.rs b/pyo3-ffi/src/pyerrors.rs index 23419e29a97..d341239a07b 100644 --- a/pyo3-ffi/src/pyerrors.rs +++ b/pyo3-ffi/src/pyerrors.rs @@ -73,22 +73,20 @@ extern "C" { #[inline] pub unsafe fn PyExceptionClass_Check(x: *mut PyObject) -> c_int { - unsafe { - (PyType_Check(x) != 0 - && PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0) - as c_int - } + (PyType_Check(x) != 0 + && PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0) + as c_int } #[inline] pub unsafe fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject { - unsafe { Py_TYPE(x) as *mut PyObject } + Py_TYPE(x) as *mut PyObject } // ported from cpython exception.c (line 2096) diff --git a/pyo3-ffi/src/pystate.rs b/pyo3-ffi/src/pystate.rs index dab802094d5..a6caf421ff6 100644 --- a/pyo3-ffi/src/pystate.rs +++ b/pyo3-ffi/src/pystate.rs @@ -52,7 +52,7 @@ extern "C" { #[inline] pub unsafe fn PyThreadState_GET() -> *mut PyThreadState { - unsafe { PyThreadState_Get() } + PyThreadState_Get() } extern "C" { @@ -105,7 +105,7 @@ impl Drop for HangThread { // pthread_exit from PyGILState_Ensure (https://github.com/python/cpython/issues/87135). mod raw { #[cfg(all(not(Py_3_14), rustc_has_extern_c_unwind))] - unsafe extern "C-unwind" { + extern "C-unwind" { #[cfg_attr(PyPy, link_name = "PyPyGILState_Ensure")] pub fn PyGILState_Ensure() -> super::PyGILState_STATE; } @@ -138,7 +138,7 @@ pub unsafe extern "C" fn PyGILState_Ensure() -> PyGILState_STATE { // and therefore will cause unsafety if there are pinned objects on the stack. AFAICT there's // nothing we can do it other than waiting for Python 3.14 or not using Windows. At least, // if there is nothing pinned on the stack, it won't cause the process to crash. - let ret: PyGILState_STATE = unsafe { raw::PyGILState_Ensure() }; + let ret: PyGILState_STATE = raw::PyGILState_Ensure(); std::mem::forget(guard); ret } diff --git a/pyo3-ffi/src/pythonrun.rs b/pyo3-ffi/src/pythonrun.rs index 3b510710b6e..e7ea2d2efd0 100644 --- a/pyo3-ffi/src/pythonrun.rs +++ b/pyo3-ffi/src/pythonrun.rs @@ -60,20 +60,16 @@ opaque_struct!(_node); #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseString(s: *const c_char, b: c_int) -> *mut _node { - unsafe { - #[allow(deprecated)] - crate::PyParser_SimpleParseStringFlags(s, b, 0) - } + #[allow(deprecated)] + crate::PyParser_SimpleParseStringFlags(s, b, 0) } #[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))] #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseFile(fp: *mut FILE, s: *const c_char, b: c_int) -> *mut _node { - unsafe { - #[allow(deprecated)] - crate::PyParser_SimpleParseFileFlags(fp, s, b, 0) - } + #[allow(deprecated)] + crate::PyParser_SimpleParseFileFlags(fp, s, b, 0) } extern "C" { diff --git a/pyo3-ffi/src/rangeobject.rs b/pyo3-ffi/src/rangeobject.rs index 81d2a5b9f69..408b5cdc5a4 100644 --- a/pyo3-ffi/src/rangeobject.rs +++ b/pyo3-ffi/src/rangeobject.rs @@ -12,5 +12,5 @@ extern "C" { #[inline] pub unsafe fn PyRange_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyRange_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyRange_Type)) as c_int } diff --git a/pyo3-ffi/src/setobject.rs b/pyo3-ffi/src/setobject.rs index adecc5e0f8e..9d5351fc798 100644 --- a/pyo3-ffi/src/setobject.rs +++ b/pyo3-ffi/src/setobject.rs @@ -34,11 +34,9 @@ pub struct PySetObject { #[inline] #[cfg(all(not(any(PyPy, GraalPy)), not(Py_LIMITED_API)))] pub unsafe fn PySet_GET_SIZE(so: *mut PyObject) -> Py_ssize_t { - unsafe { - debug_assert_eq!(PyAnySet_Check(so), 1); - let so = so.cast::(); - (*so).used - } + debug_assert_eq!(PyAnySet_Check(so), 1); + let so = so.cast::(); + (*so).used } #[cfg(not(Py_LIMITED_API))] @@ -96,7 +94,7 @@ extern "C" { #[inline] #[cfg(not(any(PyPy, GraalPy)))] pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) as c_int } + (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) as c_int } extern "C" { @@ -108,10 +106,8 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int { - unsafe { - (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type) - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int - } + (Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type) + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int } extern "C" { @@ -123,25 +119,21 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int { - unsafe { - (Py_TYPE(ob) == addr_of_mut!(PySet_Type) || Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) - as c_int - } + (Py_TYPE(ob) == addr_of_mut!(PySet_Type) || Py_TYPE(ob) == addr_of_mut!(PyFrozenSet_Type)) + as c_int } #[inline] pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int { - unsafe { - (PyAnySet_CheckExact(ob) != 0 - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0 - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int - } + (PyAnySet_CheckExact(ob) != 0 + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0 + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PyFrozenSet_Type)) != 0) as c_int } #[inline] #[cfg(Py_3_10)] pub unsafe fn PySet_CheckExact(op: *mut PyObject) -> c_int { - unsafe { crate::Py_IS_TYPE(op, addr_of_mut!(PySet_Type)) } + crate::Py_IS_TYPE(op, addr_of_mut!(PySet_Type)) } extern "C" { @@ -153,8 +145,6 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int { - unsafe { - (Py_TYPE(ob) == addr_of_mut!(PySet_Type) - || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0) as c_int - } + (Py_TYPE(ob) == addr_of_mut!(PySet_Type) + || PyType_IsSubtype(Py_TYPE(ob), addr_of_mut!(PySet_Type)) != 0) as c_int } diff --git a/pyo3-ffi/src/sliceobject.rs b/pyo3-ffi/src/sliceobject.rs index 5747ab8cd39..a3ea153987c 100644 --- a/pyo3-ffi/src/sliceobject.rs +++ b/pyo3-ffi/src/sliceobject.rs @@ -42,7 +42,7 @@ extern "C" { #[inline] pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PySlice_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PySlice_Type)) as c_int } extern "C" { @@ -75,14 +75,12 @@ pub unsafe fn PySlice_GetIndicesEx( step: *mut Py_ssize_t, slicelength: *mut Py_ssize_t, ) -> c_int { - unsafe { - if PySlice_Unpack(slice, start, stop, step) < 0 { - *slicelength = 0; - -1 - } else { - *slicelength = PySlice_AdjustIndices(length, start, stop, *step); - 0 - } + if PySlice_Unpack(slice, start, stop, step) < 0 { + *slicelength = 0; + -1 + } else { + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); + 0 } } diff --git a/pyo3-ffi/src/structseq.rs b/pyo3-ffi/src/structseq.rs index 0d62c99df2d..f8566787b51 100644 --- a/pyo3-ffi/src/structseq.rs +++ b/pyo3-ffi/src/structseq.rs @@ -45,13 +45,13 @@ pub type PyStructSequence = crate::PyTupleObject; #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] #[inline] pub unsafe fn PyStructSequence_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) { - unsafe { crate::PyTuple_SET_ITEM(op, i, v) } + crate::PyTuple_SET_ITEM(op, i, v) } #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] #[inline] pub unsafe fn PyStructSequence_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject { - unsafe { crate::PyTuple_GET_ITEM(op, i) } + crate::PyTuple_GET_ITEM(op, i) } extern "C" { diff --git a/pyo3-ffi/src/traceback.rs b/pyo3-ffi/src/traceback.rs index d58ac40a448..432b6980ef5 100644 --- a/pyo3-ffi/src/traceback.rs +++ b/pyo3-ffi/src/traceback.rs @@ -23,5 +23,5 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyTraceBack_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyTraceBack_Type)) as c_int } diff --git a/pyo3-ffi/src/tupleobject.rs b/pyo3-ffi/src/tupleobject.rs index 145038c1e64..d265c91a4b1 100644 --- a/pyo3-ffi/src/tupleobject.rs +++ b/pyo3-ffi/src/tupleobject.rs @@ -12,12 +12,12 @@ extern "C" { #[inline] pub unsafe fn PyTuple_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) } #[inline] pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyTuple_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyTuple_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/unicodeobject.rs b/pyo3-ffi/src/unicodeobject.rs index 9dc0c641d79..1e0425ce2a2 100644 --- a/pyo3-ffi/src/unicodeobject.rs +++ b/pyo3-ffi/src/unicodeobject.rs @@ -34,13 +34,13 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int { - unsafe { PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) } + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(PyUnicode_Type)) as c_int } + (Py_TYPE(op) == addr_of_mut!(PyUnicode_Type)) as c_int } pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD; diff --git a/pyo3-ffi/src/weakrefobject.rs b/pyo3-ffi/src/weakrefobject.rs index 0d9685e2270..305dc290fa8 100644 --- a/pyo3-ffi/src/weakrefobject.rs +++ b/pyo3-ffi/src/weakrefobject.rs @@ -31,27 +31,25 @@ extern "C" { #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int { - unsafe { PyObject_TypeCheck(op, addr_of_mut!(_PyWeakref_RefType)) } + PyObject_TypeCheck(op, addr_of_mut!(_PyWeakref_RefType)) } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int { - unsafe { (Py_TYPE(op) == addr_of_mut!(_PyWeakref_RefType)) as c_int } + (Py_TYPE(op) == addr_of_mut!(_PyWeakref_RefType)) as c_int } #[inline] #[cfg(not(PyPy))] pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int { - unsafe { - ((Py_TYPE(op) == addr_of_mut!(_PyWeakref_ProxyType)) - || (Py_TYPE(op) == addr_of_mut!(_PyWeakref_CallableProxyType))) as c_int - } + ((Py_TYPE(op) == addr_of_mut!(_PyWeakref_ProxyType)) + || (Py_TYPE(op) == addr_of_mut!(_PyWeakref_CallableProxyType))) as c_int } #[inline] pub unsafe fn PyWeakref_Check(op: *mut PyObject) -> c_int { - unsafe { (PyWeakref_CheckRef(op) != 0 || PyWeakref_CheckProxy(op) != 0) as c_int } + (PyWeakref_CheckRef(op) != 0 || PyWeakref_CheckProxy(op) != 0) as c_int } extern "C" { From 2367cddb061c4bc8cb25af4210e04530e41f50c4 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Thu, 20 Mar 2025 20:11:33 +0000 Subject: [PATCH 13/13] fix tests on MSRV --- tests/test_buffer.rs | 1 + tests/test_buffer_protocol.rs | 1 + tests/test_gc.rs | 1 + tests/test_pyfunction.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/tests/test_buffer.rs b/tests/test_buffer.rs index 5da434ec581..8591b6a0e1f 100644 --- a/tests/test_buffer.rs +++ b/tests/test_buffer.rs @@ -1,5 +1,6 @@ #![cfg(feature = "macros")] #![cfg(any(not(Py_LIMITED_API), Py_3_11))] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] use pyo3::{buffer::PyBuffer, exceptions::PyBufferError, ffi, prelude::*}; use std::{ diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index b3b2144cc32..f3c316d50c7 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -1,5 +1,6 @@ #![cfg(feature = "macros")] #![cfg(any(not(Py_LIMITED_API), Py_3_11))] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] use pyo3::buffer::PyBuffer; use pyo3::exceptions::PyBufferError; diff --git a/tests/test_gc.rs b/tests/test_gc.rs index 234481962d4..8bc1e53cadb 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -1,4 +1,5 @@ #![cfg(feature = "macros")] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] use pyo3::class::PyTraverseError; use pyo3::class::PyVisit; diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 03bc096519e..822e0200a89 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -1,4 +1,5 @@ #![cfg(feature = "macros")] +#![cfg_attr(not(cargo_toml_lints), warn(unsafe_op_in_unsafe_fn))] use std::collections::HashMap;