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) { ...@@ -447,7 +447,7 @@ Box* isinstance_func(Box* obj, Box* cls) {
} }
Box* issubclass_func(Box* child, Box* parent) { 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"); raiseExcHelper(TypeError, "issubclass() arg 1 must be a class");
RELEASE_ASSERT(parent->cls != tuple_cls, "unsupported"); RELEASE_ASSERT(parent->cls != tuple_cls, "unsupported");
...@@ -459,7 +459,7 @@ Box* issubclass_func(Box* child, Box* parent) { ...@@ -459,7 +459,7 @@ Box* issubclass_func(Box* child, Box* parent) {
return boxBool(classobjIssubclass(static_cast<BoxedClassobj*>(child), static_cast<BoxedClassobj*>(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) if (parent->cls != type_cls)
return False; return False;
......
...@@ -35,7 +35,7 @@ static Box* memberGet(BoxedMemberDescriptor* self, Box* inst, Box* owner) { ...@@ -35,7 +35,7 @@ static Box* memberGet(BoxedMemberDescriptor* self, Box* inst, Box* owner) {
} }
static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) { 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* fdel = args[0];
Box* doc = args[1]; Box* doc = args[1];
...@@ -49,7 +49,7 @@ static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) { ...@@ -49,7 +49,7 @@ static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) {
} }
static Box* propertyGet(Box* self, Box* obj, Box* type) { 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); BoxedProperty* prop = static_cast<BoxedProperty*>(self);
if (obj == NULL || obj == None) { if (obj == NULL || obj == None) {
...@@ -64,7 +64,7 @@ static Box* propertyGet(Box* self, Box* obj, Box* type) { ...@@ -64,7 +64,7 @@ static Box* propertyGet(Box* self, Box* obj, Box* type) {
} }
static Box* propertySet(Box* self, Box* obj, Box* val) { 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); BoxedProperty* prop = static_cast<BoxedProperty*>(self);
Box* func; Box* func;
...@@ -106,19 +106,19 @@ static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) { ...@@ -106,19 +106,19 @@ static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) {
} }
static Box* propertyGetter(Box* self, Box* obj) { 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); BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, obj, NULL, NULL); return property_copy(prop, obj, NULL, NULL);
} }
static Box* propertySetter(Box* self, Box* obj) { 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); BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, obj, NULL); return property_copy(prop, NULL, obj, NULL);
} }
static Box* propertyDeleter(Box* self, Box* obj) { 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); BoxedProperty* prop = static_cast<BoxedProperty*>(self);
return property_copy(prop, NULL, NULL, obj); return property_copy(prop, NULL, NULL, obj);
} }
......
...@@ -2001,14 +2001,28 @@ extern "C" void dump(void* p) { ...@@ -2001,14 +2001,28 @@ extern "C" void dump(void* p) {
if (al->kind_id == gc::GCKind::PYTHON) { if (al->kind_id == gc::GCKind::PYTHON) {
printf("Python object\n"); printf("Python object\n");
Box* b = (Box*)p; 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) { if (b->cls == bool_cls) {
printf("The %s object\n", b == True ? "True" : "False"); printf("The %s object\n", b == True ? "True" : "False");
} }
if (isSubclass(b->cls, type_cls)) { 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)) { if (isSubclass(b->cls, str_cls)) {
...@@ -3571,7 +3585,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) { ...@@ -3571,7 +3585,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
RELEASE_ASSERT(bases->elts.size() == 1, ""); RELEASE_ASSERT(bases->elts.size() == 1, "");
Box* _base = bases->elts[0]; Box* _base = bases->elts[0];
RELEASE_ASSERT(_base->cls == type_cls, ""); RELEASE_ASSERT(isSubclass(_base->cls, type_cls), "");
base = static_cast<BoxedClass*>(_base); base = static_cast<BoxedClass*>(_base);
if ((base->tp_flags & Py_TPFLAGS_BASETYPE) == 0) if ((base->tp_flags & Py_TPFLAGS_BASETYPE) == 0)
......
...@@ -146,8 +146,12 @@ extern "C" void abort() { ...@@ -146,8 +146,12 @@ extern "C" void abort() {
// that object, _printStackTrace will hang waiting for the first construction // that object, _printStackTrace will hang waiting for the first construction
// to finish.) // to finish.)
alarm(1); alarm(1);
_printStacktrace(); _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(); 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