Skip to content

Commit 075feef

Browse files
authored
Merge pull request #9926 from dhalbert/micropython-pr-15333
py/runtime: Fix self arg passed to classmethod when accessed via super (micropython PR 15333)
2 parents 27beb0e + 8824995 commit 075feef

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

py/runtime.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,10 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
11771177
// base type (which is what is passed in the `type` argument to this function).
11781178
if (self != MP_OBJ_NULL) {
11791179
type = mp_obj_get_type(self);
1180+
if (type == &mp_type_type) {
1181+
// `self` is already a type, so use `self` directly.
1182+
type = MP_OBJ_TO_PTR(self);
1183+
}
11801184
}
11811185
dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun;
11821186
dest[1] = MP_OBJ_FROM_PTR(type);

tests/basics/subclass_classmethod.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,34 @@ class B(A):
3535
B.bar() # class calling classmethod
3636
B().bar() # instance calling classmethod
3737
B().baz() # instance calling normal method
38+
39+
# super inside a classmethod
40+
# ensure the argument of the super method that is called is the child type
41+
42+
43+
class C:
44+
@classmethod
45+
def f(cls):
46+
print("C.f", cls.__name__) # cls should be D
47+
48+
@classmethod
49+
def g(cls):
50+
print("C.g", cls.__name__) # cls should be D
51+
52+
53+
class D(C):
54+
@classmethod
55+
def f(cls):
56+
print("D.f", cls.__name__)
57+
super().f()
58+
59+
@classmethod
60+
def g(cls):
61+
print("D.g", cls.__name__)
62+
super(D, cls).g()
63+
64+
65+
D.f()
66+
D.g()
67+
D().f()
68+
D().g()

0 commit comments

Comments
 (0)