8000 py/runtime: Implement dispatch for "reverse op" special methods. · rlucia/micropython@eb84a83 · GitHub
[go: up one dir, main page]

Skip to content

Commit eb84a83

Browse files
committed
py/runtime: Implement dispatch for "reverse op" special methods.
If, for class X, X.__add__(Y) doesn't exist (or returns NotImplemented), try Y.__radd__(X) instead. This patch could be simpler, but requires undoing operand swap and operation switch to get non-confusing error message in case __radd__ doesn't exist.
1 parent de98104 commit eb84a83

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

ports/unix/mpconfigport_coverage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
3636
#define MICROPY_ENABLE_SCHEDULER (1)
3737
#define MICROPY_PY_DELATTR_SETATTR (1)
38+
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
3839
#define MICROPY_PY_BUILTINS_HELP (1)
3940
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
4041
#define MICROPY_PY_SYS_GETSIZEOF (1)

py/mpconfig.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,11 +759,19 @@ typedef double mp_float_t;
759759
#endif
760760

761761
// Whether to support complete set of special methods
762-
// for user classes, otherwise only the most used
762+
// for user classes, or only the most used ones. "Reverse"
763+
// methods are controlled by MICROPY_PY_REVERSE_SPECIAL_METHODS
764+
// below.
763765
#ifndef MICROPY_PY_ALL_SPECIAL_METHODS
764766
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
765767
#endif
766768

769+
// Whether to support reverse arithmetic operarions methods
770+
// (__radd__, etc.)
771+
#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS
772+
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
773+
#endif
774+
767775
// Whether to support compile function
768776
#ifndef MICROPY_PY_BUILTINS_COMPILE
769777
#define MICROPY_PY_BUILTINS_COMPILE (0)

py/objtype.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,13 @@ const qstr mp_binary_op_method_name[] = {
441441
MP_BINARY_OP_INPLACE_TRUE_DIVIDE,
442442
MP_BINARY_OP_INPLACE_MODULO,
443443
MP_BINARY_OP_INPLACE_POWER,*/
444+
445+
#if MICROPY_PY_REVERSE_SPECIAL_METHODS
446+
[MP_BINARY_OP_REVERSE_ADD] = MP_QSTR___radd__,
447+
[MP_BINARY_OP_REVERSE_SUBTRACT] = MP_QSTR___rsub__,
448+
[MP_BINARY_OP_REVERSE_MULTIPLY] = MP_QSTR___rmul__,
449+
#endif
450+
444451
[MP_BINARY_OP_LESS] = MP_QSTR___lt__,
445452
[MP_BINARY_OP_MORE] = MP_QSTR___gt__,
446453
[MP_BINARY_OP_EQUAL] = MP_QSTR___eq__,

py/runtime.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,20 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
555555
}
556556
}
557557

558-
// TODO implement dispatch for reverse binary ops
558+
#if MICROPY_PY_REVERSE_SPECIAL_METHODS
559+
if (op >= MP_BINARY_OP_OR && op <= MP_BINARY_OP_REVERSE_POWER) {
560+
mp_obj_t t = rhs;
561+
rhs = lhs;
562+
lhs = t;
563+
if (op <= MP_BINARY_OP_POWER) {
564+
op += MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
565+
goto generic_binary_op;
566+
}
567+
568+
// Convert __rop__ back to __op__ for error message
569+
op -= MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
570+
}
571+
#endif
559572

560573
unsupported_op:
561574
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {

py/runtime0.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,23 @@ typedef enum {
101101
// Operations below this line don't appear in bytecode, they
102102
// just identify special methods.
103103

104+
// MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_*
105+
#if MICROPY_PY_REVERSE_SPECIAL_METHODS
106+
MP_BINARY_OP_REVERSE_OR,
107+
MP_BINARY_OP_REVERSE_XOR,
108+
MP_BINARY_OP_REVERSE_AND,
109+
MP_BINARY_OP_REVERSE_LSHIFT,
110+
MP_BINARY_OP_REVERSE_RSHIFT,
111+
MP_BINARY_OP_REVERSE_ADD,
112+
113+
MP_BINARY_OP_REVE 6E19 RSE_SUBTRACT,
114+
MP_BINARY_OP_REVERSE_MULTIPLY,
115+
MP_BINARY_OP_REVERSE_FLOOR_DIVIDE,
116+
MP_BINARY_OP_REVERSE_TRUE_DIVIDE,
117+
MP_BINARY_OP_REVERSE_MODULO,
118+
MP_BINARY_OP_REVERSE_POWER,
119+
#endif
120+
104121
MP_BINARY_OP_DIVMOD, // not emitted by the compiler but supported by the runtime
105122

106123
MP_BINARY_OP_LAST,

0 commit comments

Comments
 (0)
0