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.
This commit is contained in:
Jon Bjarni Bjarnason 2022-04-12 22:17:38 +00:00 committed by Damien George
parent 52c2580a40
commit 1ded8a2977
2 changed files with 25 additions and 0 deletions

View File

@ -549,6 +549,7 @@ retry:;
} else if (dest[0] != MP_OBJ_NULL) {
dest[2] = rhs_in;
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 {
// If this was an inplace method, fallback to normal method
// https://docs.python.org/3/reference/datamodel.html#object.__iadd__ :

View File

@ -21,3 +21,27 @@ b = B([1, 2])
print(1 in b)
print(2 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())