py/runtime: Fix self arg passed to classmethod when accessed via super.
Thanks to @AJMansfield for the original test case. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
07bf3179f6
commit
233f5ce661
@ -1153,6 +1153,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).
|
// base type (which is what is passed in the `type` argument to this function).
|
||||||
if (self != MP_OBJ_NULL) {
|
if (self != MP_OBJ_NULL) {
|
||||||
type = mp_obj_get_type(self);
|
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[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun;
|
||||||
dest[1] = MP_OBJ_FROM_PTR(type);
|
dest[1] = MP_OBJ_FROM_PTR(type);
|
||||||
|
|||||||
@ -35,3 +35,34 @@ class B(A):
|
|||||||
B.bar() # class calling classmethod
|
B.bar() # class calling classmethod
|
||||||
B().bar() # instance calling classmethod
|
B().bar() # instance calling classmethod
|
||||||
B().baz() # instance calling normal method
|
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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user