Fix incorrect binding of classmethod when called on instance of subclass
This commit is contained in:
parent
ea443f11df
commit
dc361af48b
5
src/vm.c
5
src/vm.c
@ -910,6 +910,7 @@ KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod) {
|
|||||||
* Works for managed and native method calls.
|
* Works for managed and native method calls.
|
||||||
*/
|
*/
|
||||||
int krk_bindMethod(KrkClass * _class, KrkString * name) {
|
int krk_bindMethod(KrkClass * _class, KrkString * name) {
|
||||||
|
KrkClass * originalClass = _class;
|
||||||
KrkValue method, out;
|
KrkValue method, out;
|
||||||
while (_class) {
|
while (_class) {
|
||||||
if (krk_tableGet_fast(&_class->methods, name, &method)) break;
|
if (krk_tableGet_fast(&_class->methods, name, &method)) break;
|
||||||
@ -920,7 +921,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
|
|||||||
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) {
|
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) {
|
||||||
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
|
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
|
||||||
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD) {
|
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD) {
|
||||||
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(_class), AS_OBJECT(method)));
|
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(originalClass), AS_OBJECT(method)));
|
||||||
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_STATIC_METHOD) {
|
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_STATIC_METHOD) {
|
||||||
out = method;
|
out = method;
|
||||||
} else {
|
} else {
|
||||||
@ -928,7 +929,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
|
|||||||
}
|
}
|
||||||
} else if (IS_CLOSURE(method)) {
|
} else if (IS_CLOSURE(method)) {
|
||||||
if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD) {
|
if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD) {
|
||||||
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(_class), AS_OBJECT(method)));
|
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(originalClass), AS_OBJECT(method)));
|
||||||
} else if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_STATIC_METHOD) {
|
} else if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_STATIC_METHOD) {
|
||||||
out = method;
|
out = method;
|
||||||
} else {
|
} else {
|
||||||
|
10
test/testClassMethodInherited.krk
Normal file
10
test/testClassMethodInherited.krk
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo:
|
||||||
|
@classmethod
|
||||||
|
def doThing(cls):
|
||||||
|
print("Called from a",cls)
|
||||||
|
class Bar(Foo):
|
||||||
|
pass
|
||||||
|
Foo.doThing()
|
||||||
|
Foo().doThing()
|
||||||
|
Bar.doThing()
|
||||||
|
Bar().doThing()
|
4
test/testClassMethodInherited.krk.expect
Normal file
4
test/testClassMethodInherited.krk.expect
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Called from a <class '__main__.Foo'>
|
||||||
|
Called from a <class '__main__.Foo'>
|
||||||
|
Called from a <class '__main__.Bar'>
|
||||||
|
Called from a <class '__main__.Bar'>
|
Loading…
Reference in New Issue
Block a user