Skip to content

Commit 192476c

Browse files
committed
[mypyc] Fixing condition for handling user-defined __del__.
1 parent 68233f6 commit 192476c

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

mypyc/codegen/emitclass.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,14 @@ def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None:
214214
if not cl.builtin_base:
215215
fields["tp_new"] = new_name
216216

217-
if generate_full:
217+
# Populate .tp_finalize and generate a finalize method only if __del__ is defined for this class.
218+
del_method = next((e.method for e in cl.vtable_entries if e.name == "__del__"), None)
219+
# Del method is called from dealloc method. So, dealloc should be generated whenever there is a del method.
220+
if generate_full or del_method:
218221
fields["tp_dealloc"] = f"(destructor){name_prefix}_dealloc"
222+
if generate_full:
219223
fields["tp_traverse"] = f"(traverseproc){name_prefix}_traverse"
220224
fields["tp_clear"] = f"(inquiry){name_prefix}_clear"
221-
# Populate .tp_finalize and generate a finalize method only if __del__ is defined for this class.
222-
del_method = next((e.method for e in cl.vtable_entries if e.name == "__del__"), None)
223225
if del_method:
224226
fields["tp_finalize"] = f"(destructor){finalize_name}"
225227
if needs_getseters:
@@ -300,13 +302,6 @@ def emit_line() -> None:
300302
emit_line()
301303
generate_traverse_for_class(cl, traverse_name, emitter)
302304
emit_line()
303-
generate_clear_for_class(cl, clear_name, emitter)
304-
emit_line()
305-
generate_dealloc_for_class(cl, dealloc_name, clear_name, bool(del_method), emitter)
306-
emit_line()
307-
if del_method:
308-
generate_finalize_for_class(del_method, finalize_name, emitter)
309-
emit_line()
310305

311306
if cl.allow_interpreted_subclasses:
312307
shadow_vtable_name: str | None = generate_vtables(
@@ -317,6 +312,14 @@ def emit_line() -> None:
317312
shadow_vtable_name = None
318313
vtable_name = generate_vtables(cl, vtable_setup_name, vtable_name, emitter, shadow=False)
319314
emit_line()
315+
if generate_full or del_method:
316+
generate_clear_for_class(cl, clear_name, emitter)
317+
emit_line()
318+
generate_dealloc_for_class(cl, dealloc_name, clear_name, bool(del_method), emitter)
319+
emit_line()
320+
if del_method:
321+
generate_finalize_for_class(del_method, finalize_name, emitter)
322+
emit_line()
320323
if needs_getseters:
321324
generate_getseter_declarations(cl, emitter)
322325
emit_line()

mypyc/test-data/run-classes.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2754,6 +2754,18 @@ def test_function():
27542754
assert(isinstance(d.fitem, ForwardDefinedClass))
27552755
assert(isinstance(d.fitems, ForwardDefinedClass))
27562756

2757+
[case testDelForDictSubclass]
2758+
class DictSubclass(dict):
2759+
def __del__(self):
2760+
print("deleting DictSubclass...")
2761+
2762+
[file driver.py]
2763+
import native
2764+
native.DictSubclass()
2765+
2766+
[out]
2767+
deleting DictSubclass...
2768+
27572769
[case testDel]
27582770
class A:
27592771
def __del__(self):

0 commit comments

Comments
 (0)