summaryrefslogtreecommitdiffstatshomepage
path: root/py/objtype.c
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2017-09-02 02:39:27 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2017-09-04 16:44:21 +0300
commit60749e57f24741c685d2ae125cfff27d021eb90d (patch)
tree0efba7434dbf3edfed4a883bce0f007fbb7911f1 /py/objtype.c
parent77a48e8cd493c0b0e0ca2d2ad58a110a23c6a232 (diff)
downloadmicropython-60749e57f24741c685d2ae125cfff27d021eb90d.tar.gz
micropython-60749e57f24741c685d2ae125cfff27d021eb90d.zip
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.
Diffstat (limited to 'py/objtype.c')
-rw-r--r--py/objtype.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/py/objtype.c b/py/objtype.c
index 68c1da7b8a..83a9836c31 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -460,6 +460,7 @@ STATIC mp_obj_t instance_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t
// Note: For ducktyping, CPython does not look in the instance members or use
// __getattr__ or __getattribute__. It only looks in the class dictionary.
mp_obj_instance_t *lhs = MP_OBJ_TO_PTR(lhs_in);
+retry:;
qstr op_name = mp_binary_op_method_name[op];
/* Still try to lookup native slot
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
dest[2] = rhs_in;
res = mp_call_method_n_kw(1, 0, dest);
} else {
+ // If this was an inplace method, fallback to normal method
+ // https://docs.python.org/3/reference/datamodel.html#object.__iadd__ :
+ // "If a specific method is not defined, the augmented assignment
+ // falls back to the normal methods."
+ if (op >= MP_BINARY_OP_INPLACE_OR && op <= MP_BINARY_OP_INPLACE_POWER) {
+ op -= MP_BINARY_OP_INPLACE_OR - MP_BINARY_OP_OR;
+ goto retry;
+ }
return MP_OBJ_NULL; // op not supported
}