Skip to content

Commit 60749e5

Browse files
committed
py/objtype: Implement fallback for instance inplace special methods.
If __iop__ is not defined, call __op__ instead. This is desired behavior for immutable types, __iop__ needs to be defined only for mutable types.
1 parent 77a48e8 commit 60749e5

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

py/objtype.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ STATIC mp_obj_t instance_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t
460460
// Note: For ducktyping, CPython does not look in the instance members or use
461461
// __getattr__ or __getattribute__. It only looks in the class dictionary.
462462
mp_obj_instance_t *lhs = MP_OBJ_TO_PTR(lhs_in);
463+
retry:;
463464
qstr op_name = mp_binary_op_method_name[op];
464465
/* Still try to lookup native slot
465466
if (op_name == 0) {
@@ -483,6 +484,14 @@ STATIC mp_obj_t instance_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t
483484
dest[2] = rhs_in;
484485
res = mp_call_method_n_kw(1, 0, dest);
485486
} else {
487+
// If this was an inplace method, fallback to normal method
488+
// https://docs.python.org/3/reference/datamodel.html#object.__iadd__ :
489+
// "If a specific method is not defined, the augmented assignment
490+
// falls back to the normal methods."
491+
if (op >= MP_BINARY_OP_INPLACE_OR && op <= MP_BINARY_OP_INPLACE_POWER) {
492+
op -= MP_BINARY_OP_INPLACE_OR - MP_BINARY_OP_OR;
493+
goto retry;
494+
}
486495
return MP_OBJ_NULL; // op not supported
487496
}
488497

0 commit comments

Comments
 (0)