Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mypy/test/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ def clean_up(a: list[str]) -> list[str]:
for p in prefix, prefix.replace(os.sep, "/"):
if p != "/" and p != "//" and p != "\\" and p != "\\\\":
ss = ss.replace(p, "")
# Replace memory address with zeros
if "at 0x" in ss:
ss = re.sub(r"(at 0x)\w+>", r"\g<1>000000000000>", ss)
# Ignore spaces at end of line.
ss = re.sub(" +$", "", ss)
# Remove pwd from driver.py's path
Expand Down
35 changes: 16 additions & 19 deletions mypyc/codegen/emitclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,8 +843,21 @@ def generate_dealloc_for_class(
emitter.emit_line(f"{dealloc_func_name}({cl.struct_name(emitter.names)} *self)")
emitter.emit_line("{")
if has_tp_finalize:
emitter.emit_line("if (!PyObject_GC_IsFinalized((PyObject *)self)) {")
emitter.emit_line("Py_TYPE(self)->tp_finalize((PyObject *)self);")
emitter.emit_line("PyObject *type, *value, *traceback;")
emitter.emit_line("PyErr_Fetch(&type, &value, &traceback);")
emitter.emit_line("int res = PyObject_CallFinalizerFromDealloc((PyObject *)self);")
# CPython interpreter uses PyErr_WriteUnraisable: https://docs.python.org/3/c-api/exceptions.html#c.PyErr_WriteUnraisable
# However, the message is slightly different due to the way mypyc compiles classes.
# CPython interpreter prints: Exception ignored in: <function F.__del__ at 0x100aed940>
# mypyc prints: Exception ignored in: <slot wrapper '__del__' of 'F' objects>
emitter.emit_line("if (PyErr_Occurred() != NULL) {")
# Don't untrack instance if error occurred
emitter.emit_line("PyErr_WriteUnraisable((PyObject *)self);")
emitter.emit_line("res = -1;")
emitter.emit_line("}")
emitter.emit_line("PyErr_Restore(type, value, traceback);")
emitter.emit_line("if (res < 0) {")
emitter.emit_line("goto done;")
emitter.emit_line("}")
emitter.emit_line("PyObject_GC_UnTrack(self);")
if cl.reuse_freed_instance:
Expand All @@ -854,6 +867,7 @@ def generate_dealloc_for_class(
emitter.emit_line(f"{clear_func_name}(self);")
emitter.emit_line("Py_TYPE(self)->tp_free((PyObject *)self);")
emitter.emit_line("CPy_TRASHCAN_END(self)")
emitter.emit_line("done: ;")
emitter.emit_line("}")


Expand Down Expand Up @@ -884,30 +898,13 @@ def generate_finalize_for_class(
emitter.emit_line("static void")
emitter.emit_line(f"{finalize_func_name}(PyObject *self)")
emitter.emit_line("{")
emitter.emit_line("PyObject *type, *value, *traceback;")
emitter.emit_line("PyErr_Fetch(&type, &value, &traceback);")
emitter.emit_line(
"{}{}{}(self);".format(
emitter.get_group_prefix(del_method.decl),
NATIVE_PREFIX,
del_method.cname(emitter.names),
)
)
emitter.emit_line("if (PyErr_Occurred() != NULL) {")
emitter.emit_line('PyObject *del_str = PyUnicode_FromString("__del__");')
emitter.emit_line(
"PyObject *del_method = (del_str == NULL) ? NULL : _PyType_Lookup(Py_TYPE(self), del_str);"
)
# CPython interpreter uses PyErr_WriteUnraisable: https://docs.python.org/3/c-api/exceptions.html#c.PyErr_WriteUnraisable
# However, the message is slightly different due to the way mypyc compiles classes.
# CPython interpreter prints: Exception ignored in: <function F.__del__ at 0x100aed940>
# mypyc prints: Exception ignored in: <slot wrapper '__del__' of 'F' objects>
emitter.emit_line("PyErr_WriteUnraisable(del_method);")
emitter.emit_line("Py_XDECREF(del_method);")
emitter.emit_line("Py_XDECREF(del_str);")
emitter.emit_line("}")
# PyErr_Restore also clears exception raised in __del__.
emitter.emit_line("PyErr_Restore(type, value, traceback);")
emitter.emit_line("}")


Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/run-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -3035,7 +3035,7 @@ f = native.F()
del f

[out]
Exception ignored in: <slot wrapper '__del__' of 'F' objects>
Exception ignored in: <native.F object at 0x000000000000>
Traceback (most recent call last):
File "native.py", line 5, in __del__
raise Exception("e2")
Expand Down
Loading