Skip to content

Commit

Permalink
Remove Copy and Clone derives from PyObject (#4434)
Browse files Browse the repository at this point in the history
* Remove Copy and Clone derives from PyObject

* add changelog entry
  • Loading branch information
ngoldbaum committed Aug 12, 2024
1 parent b520bc1 commit 0958568
Show file tree
Hide file tree
Showing 12 changed files with 13 additions and 28 deletions.
5 changes: 5 additions & 0 deletions newsfragments/4434.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* The `PyO3::ffi` bindings for the C `PyObject` struct no longer derive from
`Copy` and `Clone`. If you use the ffi directly you will need to remove `Copy`
and `Clone` from any derived types. Any cases where a PyObject struct was
copied or cloned directly likely indicates a bug, it is not safe to allocate
PyObject structs outside of the Python runtime.
1 change: 0 additions & 1 deletion pyo3-ffi/src/bytearrayobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::ptr::addr_of_mut;

#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyByteArrayObject {
pub ob_base: PyVarObject,
pub ob_alloc: Py_ssize_t,
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/complexobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ extern "C" {
}

#[repr(C)]
#[derive(Copy, Clone)]
// non-limited
pub struct PyComplexObject {
pub ob_base: PyObject,
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/bytesobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::os::raw::c_int;

#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyBytesObject {
pub ob_base: PyVarObject,
pub ob_shash: crate::Py_hash_t,
Expand Down
4 changes: 0 additions & 4 deletions pyo3-ffi/src/cpython/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ opaque_struct!(PyCodeObject);

#[cfg(all(not(any(PyPy, GraalPy)), Py_3_7, not(Py_3_8)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_argcount: c_int,
Expand Down Expand Up @@ -111,7 +110,6 @@ opaque_struct!(_PyExecutorArray);

#[cfg(all(not(any(PyPy, GraalPy)), Py_3_8, not(Py_3_11)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_argcount: c_int,
Expand Down Expand Up @@ -145,7 +143,6 @@ pub struct PyCodeObject {

#[cfg(all(not(any(PyPy, GraalPy)), Py_3_11))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyVarObject,
pub co_consts: *mut PyObject,
Expand Down Expand Up @@ -198,7 +195,6 @@ pub struct PyCodeObject {

#[cfg(PyPy)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_name: *mut PyObject,
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/frameobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ pub struct PyTryBlock {
}

#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
pub struct PyFrameObject {
pub ob_base: PyVarObject,
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/genobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::ptr::addr_of_mut;

#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyGenObject {
pub ob_base: PyObject,
#[cfg(not(Py_3_11))]
Expand Down
1 change: 0 additions & 1 deletion pyo3-ffi/src/cpython/listobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::pyport::Py_ssize_t;

#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyListObject {
pub ob_base: PyVarObject,
pub ob_item: *mut *mut PyObject,
Expand Down
2 changes: 0 additions & 2 deletions pyo3-ffi/src/cpython/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ pub type printfunc =
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PyTypeObject {
#[cfg(all(PyPy, not(Py_3_9)))]
pub ob_refcnt: Py_ssize_t,
Expand Down Expand Up @@ -301,7 +300,6 @@ pub struct _specialization_cache {
}

#[repr(C)]
#[derive(Clone)]
pub struct PyHeapTypeObject {
pub ht_type: PyTypeObject,
pub as_async: PyAsyncMethods,
Expand Down
18 changes: 6 additions & 12 deletions pyo3-ffi/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const _PyDateTime_TIME_DATASIZE: usize = 6;
const _PyDateTime_DATETIME_DATASIZE: usize = 10;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.timedelta`.
pub struct PyDateTime_Delta {
pub ob_base: PyObject,
Expand All @@ -46,7 +45,6 @@ pub struct PyDateTime_Delta {

#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.time` without a `tzinfo` member.
pub struct _PyDateTime_BaseTime {
pub ob_base: PyObject,
Expand All @@ -56,7 +54,6 @@ pub struct _PyDateTime_BaseTime {
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.time`.
pub struct PyDateTime_Time {
pub ob_base: PyObject,
Expand All @@ -77,7 +74,6 @@ pub struct PyDateTime_Time {
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.date`
pub struct PyDateTime_Date {
pub ob_base: PyObject,
Expand All @@ -91,7 +87,6 @@ pub struct PyDateTime_Date {

#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.datetime` without a `tzinfo` member.
pub struct _PyDateTime_BaseDateTime {
pub ob_base: PyObject,
Expand All @@ -101,7 +96,6 @@ pub struct _PyDateTime_BaseDateTime {
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.datetime`.
pub struct PyDateTime_DateTime {
pub ob_base: PyObject,
Expand Down Expand Up @@ -130,26 +124,26 @@ 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 d = *(o as *mut PyDateTime_Date);
c_int::from(d.data[0]) << 8 | c_int::from(d.data[1])
let data = (*(o as *mut PyDateTime_Date)).data;
c_int::from(data[0]) << 8 | c_int::from(data[1])
}

#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// 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 d = *(o as *mut PyDateTime_Date);
c_int::from(d.data[2])
let data = (*(o as *mut PyDateTime_Date)).data;
c_int::from(data[2])
}

#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// 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 d = *(o as *mut PyDateTime_Date);
c_int::from(d.data[3])
let data = (*(o as *mut PyDateTime_Date)).data;
c_int::from(data[3])
}

// Accessor macros for times
Expand Down
2 changes: 0 additions & 2 deletions pyo3-ffi/src/moduleobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ extern "C" {
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyModuleDef_Base {
pub ob_base: PyObject,
pub m_init: Option<extern "C" fn() -> *mut PyObject>,
Expand Down Expand Up @@ -98,7 +97,6 @@ pub const Py_MOD_PER_INTERPRETER_GIL_SUPPORTED: *mut c_void = 2 as *mut c_void;
// skipped non-limited _Py_mod_LAST_SLOT

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyModuleDef {
pub m_base: PyModuleDef_Base,
pub m_name: *const c_char,
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl std::fmt::Debug for PyObjectObRefcnt {
pub type PyObjectObRefcnt = Py_ssize_t;

#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[derive(Debug)]
pub struct PyObject {
#[cfg(py_sys_config = "Py_TRACE_REFS")]
pub _ob_next: *mut PyObject,
Expand All @@ -76,7 +76,7 @@ pub struct PyObject {
// skipped _PyObject_CAST

#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Debug)]
pub struct PyVarObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
Expand Down

0 comments on commit 0958568

Please sign in to comment.