Description
Crash Report
mypyc
generates code that triggers a CPython assertion when a subclass inherits __call__
from a superclass.
To Reproduce
$ cat test.py
class Base:
def __call__(self) -> None:
return None
class Derived(Base):
pass
$ mypyc test.py >/dev/null
$ python3-dbg -c 'import test'
../Objects/typeobject.c:5392: PyType_Ready: Assertion "type->tp_call != ((void *)0)" failed
This ends with a segfault as well, but the segfault isn't really interesting - _PyObject_ASSERT
on failure makes a call to _PyObject_Dump
, which calls into PyObject_Print
, which fails because we're in the middle of PyType_Ready
and tp_dict
hasn't been created yet.
The assertion error seems to be a genuine bug, though I'm not sure whether it's a bug in CPython or in mypyc. The failing assertion is:
if (type->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) {
_PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0);
_PyObject_ASSERT((PyObject *)type, type->tp_call != NULL);
}
The second of these two assertions fails (the first succeeds). I'm not sure whether the bug is in CPython (perhaps the assertion is wrong, and it's OK to have tp_call
set to NULL when Py_TPFLAGS_HAVE_VECTORCALL
is set if PyType_Ready
will inherit tp_call
from the parent class), or whether the bug is in mypyc (perhaps it's not legal to set Py_TPFLAGS_HAVE_VECTORCALL
when inheriting tp_call
).
Your Environment
- Mypy version used: mypy 0.942
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini
(and other config files): None - Python version used: python3.9-dbg, python3.10-dbg
- Operating system and version: RHEL 7, Debian Bullseye