[Python-ideas] __iter__ implies __contains__?

Chris Rebert pyideas at rebertia.com
Sat Oct 1 22:24:18 CEST 2011


On Sat, Oct 1, 2011 at 11:27 AM, Masklinn <masklinn at masklinn.net> wrote:
> On 2011-10-01, at 20:13 , Antoine Pitrou wrote:
>> Hello,
>>
>> I honestly didn't know we exposed such semantics, and I'm wondering if
>> the functionality is worth the astonishement:
>>
>>>>> "abc" in io.StringIO("abc\ndef\n")
>> False
>>>>> "abc\n" in io.StringIO("abc\ndef\n")
>> True
>>
>> Basically, io.StringIO provides iteration (it yields lines of text) and
>> containment is apparently inferred from that.

For comparison, it's interesting to note that
collections.abc.{Iterable, Iterator} don't implement or require a
__contains__() method.

> There's a second fallback: Python will also try to iterate using
> __getitem__ and integer indexes __iter__ is not defined.

Again, for comparison, collections.abc.Sequence /does/ define default
__contains__() and __iter__() methods, in terms of __len__() and
__getitem__().

<snip>
> the latter kicks in any time an object with no __iter__ and a __getitem__
> is tentatively iterated, I've made that error a few times with
> insufficiently defined dict-like objects finding themselves (rightly
> or wrongly) being iterated.

Requiring the explicit marking of a class as a sequence by inheriting
from the Sequence ABC in order to get such default behavior "for free"
seems quite reasonable. And having containment defined by default on
potentially-infinite iterators seems unwise. +1 on the suggested
removals.

Cheers,
Chris



More information about the Python-ideas mailing list