diff options
| author | Damien George <damien@micropython.org> | 2023-05-12 23:16:37 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-05-19 13:44:00 +1000 |
| commit | ea7031faff9efe6803d8a8f67ad2e3b4a6d390e3 (patch) | |
| tree | 71faadf644033b57a5e1339102148719ae20a155 /py | |
| parent | 4b57330465b98df30ef8a10e19a0e197b5797550 (diff) | |
py/runtime: If inplace binop fails then try corresponding normal binop.
The code that handles inplace-operator to normal-binary-operator fallback
is moved in this commit from py/objtype.c to py/runtime.c, making it apply
to all types, not just user classes.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py')
| -rw-r--r-- | py/objtype.c | 13 | ||||
| -rw-r--r-- | py/runtime.c | 9 |
2 files changed, 10 insertions, 12 deletions
diff --git a/py/objtype.c b/py/objtype.c index 88d1c8ebe..04bdf5acd 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -534,7 +534,6 @@ 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) { @@ -559,22 +558,12 @@ retry:; res = mp_call_method_n_kw(1, 0, dest); res = op == MP_BINARY_OP_CONTAINS ? mp_obj_new_bool(mp_obj_is_true(res)) : res; } 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 } #if MICROPY_PY_BUILTINS_NOTIMPLEMENTED // NotImplemented means "try other fallbacks (like calling __rop__ - // instead of __op__) and if nothing works, raise TypeError". As - // MicroPython doesn't implement any fallbacks, signal to raise - // TypeError right away. + // instead of __op__) and if nothing works, raise TypeError". if (res == mp_const_notimplemented) { return MP_OBJ_NULL; // op not supported } diff --git a/py/runtime.c b/py/runtime.c index 47e094763..3434d9cc4 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -625,6 +625,15 @@ generic_binary_op: } } + // If this was an inplace method, fallback to the corresponding 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_OR - MP_BINARY_OP_INPLACE_OR; + goto generic_binary_op; + } + #if MICROPY_PY_REVERSE_SPECIAL_METHODS if (op >= MP_BINARY_OP_OR && op <= MP_BINARY_OP_POWER) { mp_obj_t t = rhs; |
