Skip to content

Commit 2ac1364

Browse files
committed
py/objset: Check that RHS of a binary op is a set/frozenset.
CPython docs explicitly state that the RHS of a set/frozenset binary op must be a set to prevent user errors. It also preserves commutativity of the ops, eg: "abc" & set() is a TypeError, and so should be set() & "abc". This change actually decreases unix (x64) code by 160 bytes; it increases stm32 by 4 bytes and esp8266 by 28 bytes (but previous patch already introduced a much large saving).
1 parent 0197864 commit 2ac1364

4 files changed

Lines changed: 16 additions & 14 deletions

File tree

py/objset.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ STATIC mp_obj_t set_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
463463
#else
464464
bool update = true;
465465
#endif
466+
if (op != MP_BINARY_OP_IN && !is_set_or_frozenset(rhs)) {
467+
// For all ops except containment the RHS must be a set/frozenset
468+
return MP_OBJ_NULL;
469+
}
466470
switch (op) {
467471
case MP_BINARY_OP_OR:
468472
return set_union(lhs, rhs);

tests/basics/set_binop.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@
4747
s1 -= set('ad')
4848
print(s1 is s2, len(s1))
4949

50+
# RHS must be a set
51+
try:
52+
print(set('12') >= '1')
53+
except TypeError:
54+
print('TypeError')
55+
56+
# RHS must be a set
57+
try:
58+
print(set('12') <= '123')
59+
except TypeError:
60+
print('TypeError')
61+
5062
# unsupported operator
5163
try:
5264
set('abc') * 2

tests/misc/non_compliant.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,6 @@
3939
except NotImplementedError:
4040
print('NotImplementedError')
4141

42-
# should raise type error
43-
try:
44-
print(set('12') >= '1')
45-
except TypeError:
46-
print('TypeError')
47-
48-
# should raise type error
49-
try:
50-
print(set('12') <= '123')
51-
except TypeError:
52-
print('TypeError')
53-
5442
# uPy raises TypeError, shold be ValueError
5543
try:
5644
'%c' % b'\x01\x02'

tests/misc/non_compliant.py.exp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ AttributeError
33
TypeError
44
NotImplementedError
55
NotImplementedError
6-
True
7-
True
86
TypeError, ValueError
97
NotImplementedError
108
NotImplementedError

0 commit comments

Comments
 (0)