Skip to content

Commit

Permalink
Merge pull request #9926 from dhalbert/micropython-pr-15333
Browse files Browse the repository at this point in the history
py/runtime: Fix self arg passed to classmethod when accessed via super (micropython PR 15333)
  • Loading branch information
dhalbert authored Dec 29, 2024
2 parents 27beb0e + 8824995 commit 075feef
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
4 changes: 4 additions & 0 deletions py/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,10 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
// 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);
if (type == &mp_type_type) {
// `self` is already a type, so use `self` directly.
type = MP_OBJ_TO_PTR(self);
}
}
dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun;
dest[1] = MP_OBJ_FROM_PTR(type);
Expand Down
31 changes: 31 additions & 0 deletions tests/basics/subclass_classmethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,34 @@ class B(A):
B.bar() # class calling classmethod
B().bar() # instance calling classmethod
B().baz() # instance calling normal method

# super inside a classmethod
# ensure the argument of the super method that is called is the child type


class C:
@classmethod
def f(cls):
print("C.f", cls.__name__) # cls should be D

@classmethod
def g(cls):
print("C.g", cls.__name__) # cls should be D


class D(C):
@classmethod
def f(cls):
print("D.f", cls.__name__)
super().f()

@classmethod
def g(cls):
print("D.g", cls.__name__)
super(D, cls).g()


D.f()
D.g()
D().f()
D().g()

0 comments on commit 075feef

Please sign in to comment.