Commit 53c223d3 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix a number of issues around class creation

Mostly, what happens if class-creation fails.
parent ce4fe4f9
......@@ -915,7 +915,18 @@ BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base,
assert(!made->tp_bases);
made->tp_bases = incref(bases);
made->finishInitialization();
try {
made->finishInitialization();
} catch (ExcInfo e) {
// XXX hack -- see comment in createUserClass
if (isSubclass(made->cls, type_cls)) {
RELEASE_ASSERT(classes.back() == made, "");
classes.pop_back();
}
Py_DECREF(made);
throw e;
}
assert(made->tp_mro);
return made;
......
......@@ -1452,6 +1452,7 @@ extern "C" Box* createUserClass(BoxedString* name, Box* _bases, Box* _attr_dict)
// But for classes created from Python, we don't have this extra untracked reference.
// Rather than fix up the plumbing for now, just reach into the other system and remove this
// class from the list.
// This hack also exists in BoxedHeapClass::create
if (isSubclass(r->cls, type_cls)) {
RELEASE_ASSERT(classes.back() == r, "");
classes.pop_back();
......@@ -1467,16 +1468,22 @@ extern "C" Box* createUserClass(BoxedString* name, Box* _bases, Box* _attr_dict)
if (isSubclass(e.value->cls, BaseException)) {
static BoxedString* message_str = getStaticString("message");
msg = getattr(e.value, message_str);
} else {
incref(msg);
}
if (PyString_Check(msg)) {
auto newmsg = PyString_FromFormat("Error when calling the metaclass bases\n"
" %s",
PyString_AS_STRING(msg));
if (newmsg)
if (newmsg) {
Py_DECREF(e.value);
e.value = newmsg;
}
}
Py_DECREF(msg);
// Go through these routines since they do some normalization:
PyErr_Restore(e.type, e.value, e.traceback);
throwCAPIException();
......@@ -3875,6 +3882,9 @@ void BoxedClass::dealloc(Box* b) noexcept {
if (PyObject_IS_GC(type))
_PyObject_GC_UNTRACK(type);
PyObject_ClearWeakRefs((PyObject *)type);
type->clearAttrsForDealloc();
Py_XDECREF(type->tp_dict);
......
......@@ -154,7 +154,8 @@ extern "C" void dumpEx(void* p, int levels) {
if (b->cls->instancesHaveHCAttrs()) {
printf("Object has hcattrs:\n");
HCAttrs* attrs = b->getHCAttrsPtr();
attrs->hcls->dump();
if (attrs->hcls)
attrs->hcls->dump();
// attrs->dump();
}
......
# expected: refstatfail
# skip-if: '-O' in EXTRA_JIT_ARGS
# statcheck: 4 <= noninit_count('num_deopt') < 50
# statcheck: 1 <= stats["num_osr_exits"] <= 2
......
# expected: reffail
# Test a relatively-obscure corner case of multiple inheritance:
# the metaclass is normally the first base's metaclass, but type_new
# will specifically delegate to a later base's metaclass if it is more
......
# expected: reffail
# Testing the basic multiple-inheritance rules and functionality:
class C(object):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment