Browse Source

py/objtype: Convert result of user __contains__ method to bool.

Per https://docs.python.org/3/reference/expressions.html#membership-test-operations

    For user-defined classes which define the contains() method, x in y
    returns True if y.contains(x) returns a true value, and False
    otherwise.

Fixes issue #7884.
pull/8563/head
Jon Bjarni Bjarnason 3 years ago
committed by Damien George
parent
commit
1ded8a2977
  1. 1
      py/objtype.c
  2. 24
      tests/basics/class_contains.py

1
py/objtype.c

@ -549,6 +549,7 @@ retry:;
} else if (dest[0] != MP_OBJ_NULL) { } else if (dest[0] != MP_OBJ_NULL) {
dest[2] = rhs_in; dest[2] = rhs_in;
res = mp_call_method_n_kw(1, 0, dest); res = mp_call_method_n_kw(1, 0, dest);
res = op == MP_BINARY_OP_CONTAINS ? mp_obj_new_bool(mp_obj_is_true(res)) : res;
} else { } else {
// If this was an inplace method, fallback to normal method // If this was an inplace method, fallback to normal method
// https://docs.python.org/3/reference/datamodel.html#object.__iadd__ : // https://docs.python.org/3/reference/datamodel.html#object.__iadd__ :

24
tests/basics/class_contains.py

@ -21,3 +21,27 @@ b = B([1, 2])
print(1 in b) print(1 in b)
print(2 in b) print(2 in b)
print(3 in b) print(3 in b)
class C:
def __contains__(self, arg):
return arg
print(C().__contains__(0))
print(C().__contains__(1))
print(C().__contains__(''))
print(C().__contains__('foo'))
print(C().__contains__(None))
print(0 in C())
print(1 in C())
print('' in C())
print('foo' in C())
print(None in C())
print(0 not in C())
print(1 not in C())
print('' not in C())
print('foo' not in C())
print(None not in C())

Loading…
Cancel
Save