Skip to content

Commit 4e39ff2

Browse files
jimmodpgeorge
authored andcommitted
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 adafruit#5677.
1 parent 14b853e commit 4e39ff2

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

py/runtime.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
284284
return result;
285285
}
286286
}
287+
if (op == MP_UNARY_OP_BOOL) {
288+
// Type doesn't have unary_op (or didn't handle MP_UNARY_OP_BOOL),
289+
// so is implicitly True as this code path is impossible to reach
290+
// if arg==mp_const_none.
291+
return mp_const_true;
292+
}
287293
// With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int().
288294
// In this case provide a more focused error message to not confuse, e.g. chr(1.0)
289295
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE

tests/basics/unary_op.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,12 @@ class A: pass
2323
# check user instances derived from builtins
2424
class B(int): pass
2525
print(not B())
26+
print(True if B() else False)
2627
class C(list): pass
2728
print(not C())
29+
print(True if C() else False)
30+
# type doesn't define unary_op
31+
class D(type): pass
32+
d = D("foo", (), {})
33+
print(not d)
34+
print(True if d else False)

0 commit comments

Comments
 (0)