Eric Lafontaine added the comment: Hi all, Here are the test I've made to understand the behavior : class Foo_42(object): def __contains__(self,item): return 42 class Foo_neg(object): def __contains__(self,item): return -42 class Foo_None(object): def __contains__(self,item): return class Foo_false(object): def __contains__(self,item): return False class Foo_true(object): def __contains__(self,item): return True for foo in [Foo_false(),Foo_None(),Foo_neg(),Foo_true(),Foo_42()]: print("3 in foo:" + str(3 in foo)) print("foo.__contains__(3)" + str(foo.__contains__(3))) which output this : 3 in foo:False foo.__contains__(3)False 3 in foo:False foo.__contains__(3)None 3 in foo:True foo.__contains__(3)-42 3 in foo:True foo.__contains__(3)True 3 in foo:True foo.__contains__(3)42 So as long as __contains__ return False or None, the 'in' operator will be False. Otherwise true. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue16011> _______________________________________