Skip to content

Commit

Permalink
workaround BaseException issue on Python versions before 3.11
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Sep 9, 2023
1 parent 0b87297 commit def175e
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/pycell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ use crate::type_object::{PyLayout, PySizedLayout};
use crate::types::PyAny;
use crate::{
conversion::{AsPyPointer, FromPyPointer, ToPyObject},
ffi::PyBaseObject_Type,
type_object::get_tp_free,
PyTypeInfo,
};
Expand Down Expand Up @@ -967,15 +966,23 @@ where
{
fn ensure_threadsafe(&self) {}
unsafe fn tp_dealloc(py: Python<'_>, slf: *mut ffi::PyObject) {
let type_obj = T::type_object_raw(py);
// For `#[pyclass]` types which inherit from PyAny, we can just call tp_free
if T::type_object_raw(py) == &mut PyBaseObject_Type {
if type_obj == std::ptr::addr_of_mut!(ffi::PyBaseObject_Type) {
return get_tp_free(ffi::Py_TYPE(slf))(slf as _);
}

// More complex native types (e.g. `extends=PyDict`) require calling the base's dealloc.
#[cfg(not(Py_LIMITED_API))]
{
if let Some(dealloc) = (*T::type_object_raw(py)).tp_dealloc {
if let Some(dealloc) = (*type_obj).tp_dealloc {
// Before Python 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(Py_3_11))]
if ffi::PyType_FastSubclass(type_obj, ffi::Py_TPFLAGS_BASE_EXC_SUBCLASS) == 1 {
ffi::PyObject_GC_Track(slf.cast());
}
dealloc(slf as _);
} else {
get_tp_free(ffi::Py_TYPE(slf))(slf as _);
Expand Down

0 comments on commit def175e

Please sign in to comment.