@@ -311,7 +311,7 @@ def emit_line() -> None:
311311 emit_line ()
312312 generate_clear_for_class (cl , clear_name , emitter )
313313 emit_line ()
314- generate_dealloc_for_class (cl , dealloc_name , clear_name , emitter )
314+ generate_dealloc_for_class (cl , dealloc_name , clear_name , bool ( del_method ), emitter )
315315 emit_line ()
316316 if del_method :
317317 generate_finalize_for_class (del_method , finalize_name , emitter )
@@ -782,14 +782,15 @@ def generate_clear_for_class(cl: ClassIR, func_name: str, emitter: Emitter) -> N
782782
783783
784784def generate_dealloc_for_class (
785- cl : ClassIR , dealloc_func_name : str , clear_func_name : str , emitter : Emitter
785+ cl : ClassIR , dealloc_func_name : str , clear_func_name : str , has_tp_finalize : bool , emitter : Emitter
786786) -> None :
787787 emitter .emit_line ("static void" )
788788 emitter .emit_line (f"{ dealloc_func_name } ({ cl .struct_name (emitter .names )} *self)" )
789789 emitter .emit_line ("{" )
790- emitter .emit_line ("if (Py_TYPE(self)->tp_finalize) {" )
791- emitter .emit_line (" Py_TYPE(self)->tp_finalize((PyObject *)self);" )
792- emitter .emit_line ("}" )
790+ if has_tp_finalize :
791+ emitter .emit_line ("if (!PyObject_GC_IsFinalized((PyObject *)self)) {" )
792+ emitter .emit_line ("Py_TYPE(self)->tp_finalize((PyObject *)self);" )
793+ emitter .emit_line ("}" )
793794 emitter .emit_line ("PyObject_GC_UnTrack(self);" )
794795 # The trashcan is needed to handle deep recursive deallocations
795796 emitter .emit_line (f"CPy_TRASHCAN_BEGIN(self, { dealloc_func_name } )" )
@@ -805,13 +806,18 @@ def generate_finalize_for_class(
805806 emitter .emit_line ("static void" )
806807 emitter .emit_line (f"{ finalize_func_name } (PyObject *self)" )
807808 emitter .emit_line ("{" )
809+ emitter .emit_line ("PyObject *type, *value, *traceback;" )
810+ emitter .emit_line ("PyErr_Fetch(&type, &value, &traceback);" )
808811 emitter .emit_line (
809812 "{}{}{}(self);" .format (
810813 emitter .get_group_prefix (del_method .decl ),
811814 NATIVE_PREFIX ,
812815 del_method .cname (emitter .names ),
813816 )
814817 )
818+ emitter .emit_line ("if (type != NULL) {" )
819+ emitter .emit_line ("PyErr_Restore(type, value, traceback);" )
820+ emitter .emit_line ("}" )
815821 emitter .emit_line ("}" )
816822
817823
0 commit comments