Skip to content

Commit 1284203

Browse files
committed
py/objdict: Implement bool and len unary ops for dict views.
Currently, dict views (eg `dict.keys()`, `dict.values()`) do not implement the `bool` or `len` unary operations. That may seem like a reasonable omission for MicroPython to keep code size down, but it actually leads to silently incorrect bool operations, because by default things are true. Eg we currently have: >>> bool(dict().keys()) True which is wrong, it should be `False` because the dict is empty. This commit implements `bool` and `len` unary operations on dict views by simply delegating to the existing dict unary op function. Fixes issue micropython#12385. Signed-off-by: Damien George <damien@micropython.org>
1 parent 4593843 commit 1284203

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

py/objdict.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@ static mp_obj_t dict_view_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
521521
if (op == MP_UNARY_OP_HASH && o->kind == MP_DICT_VIEW_VALUES) {
522522
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)o_in);
523523
}
524-
return MP_OBJ_NULL;
524+
// delegate all other ops to dict unary op handler
525+
return dict_unary_op(op, o->dict);
525526
}
526527

527528
static mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {

tests/basics/dict_views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
# print a view with more than one item
77
print({1:1, 2:1}.values())
88

9+
# `bool` and `len` unary ops
10+
for d in ({}, {1: 2}, {1: 2, 3: 4}):
11+
for op in (bool, len):
12+
print(op(d.keys()), op(d.values()), op(d.items()))
13+
914
# unsupported binary op on a dict values view
1015
try:
1116
{1:1}.values() + 1

0 commit comments

Comments
 (0)