summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-05-10 02:03:43 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-05-10 16:56:20 +0300
commitd86020ac4f6379fa14e1086b1d28e9e080c2a934 (patch)
tree1b85c7430cf8e9dd8b16c99a0ed6b4b0e331e9b0
parentd0a5bf34f746276550aef9c8519160c033611571 (diff)
objtype: Don't treat inheritance from "object" as from native type.
"object" type in MicroPython currently doesn't implement any methods, and hopefully, we'll try to stay like that for as long as possible. Even if we have to add something eventually, look up from there might be handled in adhoc manner, as last resort (that's not compliant with Python3 MRO, but we're already non-compliant). Hence: 1) no need to spend type trying to lookup anything in object; 2) no need to allocate subobject when explicitly inheriting from object; 3) and having multiple bases inheriting from object is not a case of incompatible multiple inheritance.
-rw-r--r--py/objtype.c18
-rw-r--r--tests/basics/subclass-native5.py12
2 files changed, 28 insertions, 2 deletions
diff --git a/py/objtype.c b/py/objtype.c
index 5324e7cdf..f43c92d35 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -67,7 +67,12 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
int count = 0;
for (uint i = 0; i < len; i++) {
assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
- if (is_native_type((const mp_obj_type_t *)items[i])) {
+ const mp_obj_type_t *bt = (const mp_obj_type_t *)items[i];
+ if (bt == &mp_type_object) {
+ // Not a "real" type
+ continue;
+ }
+ if (is_native_type(bt)) {
*last_native_base = items[i];
count++;
} else {
@@ -144,7 +149,12 @@ STATIC void mp_obj_class_lookup(mp_obj_instance_t *o, const mp_obj_type_t *type,
}
for (uint i = 0; i < len - 1; i++) {
assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
- mp_obj_class_lookup(o, (mp_obj_type_t*)items[i], attr, meth_offset, dest);
+ mp_obj_type_t *bt = (mp_obj_type_t*)items[i];
+ if (bt == &mp_type_object) {
+ // Not a "real" type
+ continue;
+ }
+ mp_obj_class_lookup(o, bt, attr, meth_offset, dest);
if (dest[0] != MP_OBJ_NULL) {
return;
}
@@ -153,6 +163,10 @@ STATIC void mp_obj_class_lookup(mp_obj_instance_t *o, const mp_obj_type_t *type,
// search last base (simple tail recursion elimination)
assert(MP_OBJ_IS_TYPE(items[len - 1], &mp_type_type));
type = (mp_obj_type_t*)items[len - 1];
+ if (type == &mp_type_object) {
+ // Not a "real" type
+ return;
+ }
}
}
diff --git a/tests/basics/subclass-native5.py b/tests/basics/subclass-native5.py
new file mode 100644
index 000000000..6127dae33
--- /dev/null
+++ b/tests/basics/subclass-native5.py
@@ -0,0 +1,12 @@
+# Subclass from 2 bases explicitly subclasses from object
+
+class Base1(object):
+ pass
+
+class Base2(object):
+ pass
+
+class Sub(Base1, Base2):
+ pass
+
+o = Sub()