Skip to content

Commit 3ff259a

Browse files
committed
py: Fix calling of parent classmethod from instance of subclass.
Addresses issue adafruit#1697.
1 parent 1be0fde commit 3ff259a

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

py/runtime.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,11 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
934934
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
935935
} else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
936936
// return a bound method, with self being the type of this object
937+
// this type should be the type of the original instance, not the base
938+
// type (which is what is passed in the 'type' argument to this function)
939+
if (self != MP_OBJ_NULL) {
940+
type = mp_obj_get_type(self);
941+
}
937942
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
938943
dest[1] = MP_OBJ_FROM_PTR(type);
939944
} else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) {

tests/basics/subclass_classmethod.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,22 @@ class Sub(Base):
1010

1111

1212
Sub.foo()
13+
14+
# overriding a member and accessing it via a classmethod
15+
16+
class A(object):
17+
foo = 0
18+
19+
@classmethod
20+
def bar(cls):
21+
print(cls.foo)
22+
23+
def baz(self):
24+
print(self.foo)
25+
26+
class B(A):
27+
foo = 1
28+
29+
B.bar() # class calling classmethod
30+
B().bar() # instance calling classmethod
31+
B().baz() # instance calling normal method

0 commit comments

Comments
 (0)