Commit 1458a514 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Allow more subclassing from property/type

parent 79b2e9cc
......@@ -447,7 +447,7 @@ Box* isinstance_func(Box* obj, Box* cls) {
}
Box* issubclass_func(Box* child, Box* parent) {
if (child->cls != type_cls && child->cls != classobj_cls)
if (!isSubclass(child->cls, type_cls) && child->cls != classobj_cls)
raiseExcHelper(TypeError, "issubclass() arg 1 must be a class");
RELEASE_ASSERT(parent->cls != tuple_cls, "unsupported");
......@@ -459,7 +459,7 @@ Box* issubclass_func(Box* child, Box* parent) {
return boxBool(classobjIssubclass(static_cast<BoxedClassobj*>(child), static_cast<BoxedClassobj*>(parent)));
}
assert(child->cls == type_cls);
assert(isSubclass(child->cls, type_cls));
if (parent->cls != type_cls)
return False;
......
......@@ -35,7 +35,7 @@ static Box* memberGet(BoxedMemberDescriptor* self, Box* inst, Box* owner) {
}
static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) {
RELEASE_ASSERT(_self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(_self->cls, property_cls), "");
Box* fdel = args[0];
Box* doc = args[1];
......@@ -49,7 +49,7 @@ static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) {
}
static Box* propertyGet(Box* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
if (obj == NULL || obj == None) {
......@@ -64,7 +64,7 @@ static Box* propertyGet(Box* self, Box* obj, Box* type) {
}
static Box* propertySet(Box* self, Box* obj, Box* val) {
RELEASE_ASSERT(self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
Box* func;
......@@ -106,19 +106,19 @@ static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) {
}
static Box* propertyGetter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, obj, NULL, NULL);
}
static Box* propertySetter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, obj, NULL);
}
static Box* propertyDeleter(Box* self, Box* obj) {
RELEASE_ASSERT(self->cls == property_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, property_cls), "");
BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, NULL, obj);
}
......
......@@ -2001,14 +2001,28 @@ extern "C" void dump(void* p) {
if (al->kind_id == gc::GCKind::PYTHON) {
printf("Python object\n");
Box* b = (Box*)p;
printf("Class: %s\n", getFullTypeName(b).c_str());
printf("Class: %s", getFullTypeName(b).c_str());
if (b->cls->cls != type_cls) {
printf(" (metaclass: %s)\n", getFullTypeName(b->cls).c_str());
} else {
printf("\n");
}
if (b->cls == bool_cls) {
printf("The %s object\n", b == True ? "True" : "False");
}
if (isSubclass(b->cls, type_cls)) {
printf("Type name: %s\n", getFullNameOfClass(static_cast<BoxedClass*>(b)).c_str());
auto cls = static_cast<BoxedClass*>(b);
printf("Type name: %s\n", getFullNameOfClass(cls).c_str());
printf("MRO: %s", getFullNameOfClass(cls).c_str());
while (cls->tp_base) {
printf(" -> %s", getFullNameOfClass(cls->tp_base).c_str());
cls = cls->tp_base;
}
printf("\n");
}
if (isSubclass(b->cls, str_cls)) {
......@@ -3571,7 +3585,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
RELEASE_ASSERT(bases->elts.size() == 1, "");
Box* _base = bases->elts[0];
RELEASE_ASSERT(_base->cls == type_cls, "");
RELEASE_ASSERT(isSubclass(_base->cls, type_cls), "");
base = static_cast<BoxedClass*>(_base);
if ((base->tp_flags & Py_TPFLAGS_BASETYPE) == 0)
......
......@@ -146,8 +146,12 @@ extern "C" void abort() {
// that object, _printStackTrace will hang waiting for the first construction
// to finish.)
alarm(1);
_printStacktrace();
// Cancel the alarm.
// This is helpful for when running in a debugger, since the debugger will catch the
// abort and let you investigate, but the alarm will still come back to kill the program.
alarm(0);
}
libc_abort();
......
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