summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-12-09 17:30:01 +0000
committerDamien George <damien.p.george@gmail.com>2015-12-09 17:30:01 +0000
commit3ff259a262a6619325211909bbf3781538232b6f (patch)
treed87d2a2d6af086b098872806783123fd463aa7f1
parent1be0fde45c8d84eaf04851af96f06aad8171b2b2 (diff)
downloadmicropython-3ff259a262a6619325211909bbf3781538232b6f.tar.gz
micropython-3ff259a262a6619325211909bbf3781538232b6f.zip
py: Fix calling of parent classmethod from instance of subclass.
Addresses issue #1697.
-rw-r--r--py/runtime.c5
-rw-r--r--tests/basics/subclass_classmethod.py19
2 files changed, 24 insertions, 0 deletions
diff --git a/py/runtime.c b/py/runtime.c
index c6a85bb01e..58b5a5dd13 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -934,6 +934,11 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
// return a bound method, with self being the type of this object
+ // this type should be the type of the original instance, not the base
+ // type (which is what is passed in the 'type' argument to this function)
+ if (self != MP_OBJ_NULL) {
+ type = mp_obj_get_type(self);
+ }
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
dest[1] = MP_OBJ_FROM_PTR(type);
} else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) {
diff --git a/tests/basics/subclass_classmethod.py b/tests/basics/subclass_classmethod.py
index 01deffba47..ae5fbd1aa3 100644
--- a/tests/basics/subclass_classmethod.py
+++ b/tests/basics/subclass_classmethod.py
@@ -10,3 +10,22 @@ class Sub(Base):
Sub.foo()
+
+# overriding a member and accessing it via a classmethod
+
+class A(object):
+ foo = 0
+
+ @classmethod
+ def bar(cls):
+ print(cls.foo)
+
+ def baz(self):
+ print(self.foo)
+
+class B(A):
+ foo = 1
+
+B.bar() # class calling classmethod
+B().bar() # instance calling classmethod
+B().baz() # instance calling normal method