diff options
| author | Jim Mussared <jim.mussared@gmail.com> | 2020-02-20 22:30:49 +1100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2021-07-23 12:40:00 +1000 |
| commit | 4e39ff221abff9d1d7d7fc654da67a89a7543112 (patch) | |
| tree | 6c26ab519d0a9fac8d3f6e7776d65031421ba3fa | |
| parent | 14b853eae052f6d8ef285931336ca1212af76716 (diff) | |
py/runtime: Fix bool unary op for subclasses of native types.
Previously a subclass of a type that didn't implement unary_op, or didn't
handle MP_UNARY_OP_BOOL, would raise TypeError on bool conversion.
Fixes #5677.
| -rw-r--r-- | py/runtime.c | 6 | ||||
| -rw-r--r-- | tests/basics/unary_op.py | 7 |
2 files changed, 13 insertions, 0 deletions
diff --git a/py/runtime.c b/py/runtime.c index 19686c310..27e5bc13e 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -284,6 +284,12 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { return result; } } + if (op == MP_UNARY_OP_BOOL) { + // Type doesn't have unary_op (or didn't handle MP_UNARY_OP_BOOL), + // so is implicitly True as this code path is impossible to reach + // if arg==mp_const_none. + return mp_const_true; + } // With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int(). // In this case provide a more focused error message to not confuse, e.g. chr(1.0) #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE diff --git a/tests/basics/unary_op.py b/tests/basics/unary_op.py index bd78a20d0..2239e2b20 100644 --- a/tests/basics/unary_op.py +++ b/tests/basics/unary_op.py @@ -23,5 +23,12 @@ print(not A()) # check user instances derived from builtins class B(int): pass print(not B()) +print(True if B() else False) class C(list): pass print(not C()) +print(True if C() else False) +# type doesn't define unary_op +class D(type): pass +d = D("foo", (), {}) +print(not d) +print(True if d else False) |
