Skip to content

Commit 0958568

Browse files
authored
Remove Copy and Clone derives from PyObject (#4434)
* Remove Copy and Clone derives from PyObject * add changelog entry
1 parent b520bc1 commit 0958568

12 files changed

+13
-28
lines changed

newsfragments/4434.changed.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
* The `PyO3::ffi` bindings for the C `PyObject` struct no longer derive from
2+
`Copy` and `Clone`. If you use the ffi directly you will need to remove `Copy`
3+
and `Clone` from any derived types. Any cases where a PyObject struct was
4+
copied or cloned directly likely indicates a bug, it is not safe to allocate
5+
PyObject structs outside of the Python runtime.

pyo3-ffi/src/bytearrayobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::ptr::addr_of_mut;
55

66
#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
77
#[repr(C)]
8-
#[derive(Copy, Clone)]
98
pub struct PyByteArrayObject {
109
pub ob_base: PyVarObject,
1110
pub ob_alloc: Py_ssize_t,

pyo3-ffi/src/complexobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ extern "C" {
2626
}
2727

2828
#[repr(C)]
29-
#[derive(Copy, Clone)]
3029
// non-limited
3130
pub struct PyComplexObject {
3231
pub ob_base: PyObject,

pyo3-ffi/src/cpython/bytesobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::os::raw::c_int;
66

77
#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
88
#[repr(C)]
9-
#[derive(Copy, Clone)]
109
pub struct PyBytesObject {
1110
pub ob_base: PyVarObject,
1211
pub ob_shash: crate::Py_hash_t,

pyo3-ffi/src/cpython/code.rs

-4
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ opaque_struct!(PyCodeObject);
8282

8383
#[cfg(all(not(any(PyPy, GraalPy)), Py_3_7, not(Py_3_8)))]
8484
#[repr(C)]
85-
#[derive(Copy, Clone)]
8685
pub struct PyCodeObject {
8786
pub ob_base: PyObject,
8887
pub co_argcount: c_int,
@@ -111,7 +110,6 @@ opaque_struct!(_PyExecutorArray);
111110

112111
#[cfg(all(not(any(PyPy, GraalPy)), Py_3_8, not(Py_3_11)))]
113112
#[repr(C)]
114-
#[derive(Copy, Clone)]
115113
pub struct PyCodeObject {
116114
pub ob_base: PyObject,
117115
pub co_argcount: c_int,
@@ -145,7 +143,6 @@ pub struct PyCodeObject {
145143

146144
#[cfg(all(not(any(PyPy, GraalPy)), Py_3_11))]
147145
#[repr(C)]
148-
#[derive(Copy, Clone)]
149146
pub struct PyCodeObject {
150147
pub ob_base: PyVarObject,
151148
pub co_consts: *mut PyObject,
@@ -198,7 +195,6 @@ pub struct PyCodeObject {
198195

199196
#[cfg(PyPy)]
200197
#[repr(C)]
201-
#[derive(Copy, Clone)]
202198
pub struct PyCodeObject {
203199
pub ob_base: PyObject,
204200
pub co_name: *mut PyObject,

pyo3-ffi/src/cpython/frameobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub struct PyTryBlock {
2121
}
2222

2323
#[repr(C)]
24-
#[derive(Copy, Clone)]
2524
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
2625
pub struct PyFrameObject {
2726
pub ob_base: PyVarObject,

pyo3-ffi/src/cpython/genobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::ptr::addr_of_mut;
99

1010
#[cfg(not(any(PyPy, GraalPy)))]
1111
#[repr(C)]
12-
#[derive(Copy, Clone)]
1312
pub struct PyGenObject {
1413
pub ob_base: PyObject,
1514
#[cfg(not(Py_3_11))]

pyo3-ffi/src/cpython/listobject.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::pyport::Py_ssize_t;
44

55
#[cfg(not(any(PyPy, GraalPy)))]
66
#[repr(C)]
7-
#[derive(Copy, Clone)]
87
pub struct PyListObject {
98
pub ob_base: PyVarObject,
109
pub ob_item: *mut *mut PyObject,

pyo3-ffi/src/cpython/object.rs

-2
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ pub type printfunc =
205205
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int;
206206

207207
#[repr(C)]
208-
#[derive(Debug, Copy, Clone)]
209208
pub struct PyTypeObject {
210209
#[cfg(all(PyPy, not(Py_3_9)))]
211210
pub ob_refcnt: Py_ssize_t,
@@ -301,7 +300,6 @@ pub struct _specialization_cache {
301300
}
302301

303302
#[repr(C)]
304-
#[derive(Clone)]
305303
pub struct PyHeapTypeObject {
306304
pub ht_type: PyTypeObject,
307305
pub as_async: PyAsyncMethods,

pyo3-ffi/src/datetime.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ const _PyDateTime_TIME_DATASIZE: usize = 6;
2727
const _PyDateTime_DATETIME_DATASIZE: usize = 10;
2828

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

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

5856
#[repr(C)]
59-
#[derive(Debug, Copy, Clone)]
6057
/// Structure representing a `datetime.time`.
6158
pub struct PyDateTime_Time {
6259
pub ob_base: PyObject,
@@ -77,7 +74,6 @@ pub struct PyDateTime_Time {
7774
}
7875

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

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

10398
#[repr(C)]
104-
#[derive(Debug, Copy, Clone)]
10599
/// Structure representing a `datetime.datetime`.
106100
pub struct PyDateTime_DateTime {
107101
pub ob_base: PyObject,
@@ -130,26 +124,26 @@ pub struct PyDateTime_DateTime {
130124
/// Returns a signed integer greater than 0.
131125
pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int {
132126
// This should work for Date or DateTime
133-
let d = *(o as *mut PyDateTime_Date);
134-
c_int::from(d.data[0]) << 8 | c_int::from(d.data[1])
127+
let data = (*(o as *mut PyDateTime_Date)).data;
128+
c_int::from(data[0]) << 8 | c_int::from(data[1])
135129
}
136130

137131
#[inline]
138132
#[cfg(not(any(PyPy, GraalPy)))]
139133
/// Retrieve the month component of a `PyDateTime_Date` or `PyDateTime_DateTime`.
140134
/// Returns a signed integer in the range `[1, 12]`.
141135
pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int {
142-
let d = *(o as *mut PyDateTime_Date);
143-
c_int::from(d.data[2])
136+
let data = (*(o as *mut PyDateTime_Date)).data;
137+
c_int::from(data[2])
144138
}
145139

146140
#[inline]
147141
#[cfg(not(any(PyPy, GraalPy)))]
148142
/// Retrieve the day component of a `PyDateTime_Date` or `PyDateTime_DateTime`.
149143
/// Returns a signed integer in the interval `[1, 31]`.
150144
pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int {
151-
let d = *(o as *mut PyDateTime_Date);
152-
c_int::from(d.data[3])
145+
let data = (*(o as *mut PyDateTime_Date)).data;
146+
c_int::from(data[3])
153147
}
154148

155149
// Accessor macros for times

pyo3-ffi/src/moduleobject.rs

-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ extern "C" {
5252
}
5353

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

10099
#[repr(C)]
101-
#[derive(Copy, Clone)]
102100
pub struct PyModuleDef {
103101
pub m_base: PyModuleDef_Base,
104102
pub m_name: *const c_char,

pyo3-ffi/src/object.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl std::fmt::Debug for PyObjectObRefcnt {
6161
pub type PyObjectObRefcnt = Py_ssize_t;
6262

6363
#[repr(C)]
64-
#[derive(Copy, Clone, Debug)]
64+
#[derive(Debug)]
6565
pub struct PyObject {
6666
#[cfg(py_sys_config = "Py_TRACE_REFS")]
6767
pub _ob_next: *mut PyObject,
@@ -76,7 +76,7 @@ pub struct PyObject {
7676
// skipped _PyObject_CAST
7777

7878
#[repr(C)]
79-
#[derive(Debug, Copy, Clone)]
79+
#[derive(Debug)]
8080
pub struct PyVarObject {
8181
pub ob_base: PyObject,
8282
#[cfg(not(GraalPy))]

0 commit comments

Comments
 (0)