On Tue, Apr 3, 2018 at 7:34 PM Ethan Furman <ethan@stoneleaf.us> wrote:
This behavior was recently brought to my attention [1]:

--> 1 in 'hello'
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not int

However, in any other collection (set, dict, list, tuple, etc), the answer would be False.

Does anyone remember the reason why an exception is raised in the string instance instead of returning False?

If I had to hazard a guess, I'd say it's because strings by definition, in the sense that they are a container, can only contain strings of length 1, whereas the other containers you listed can contain a wide variety of Python objects (in some cases, any Python object). Thus it's easy to detect and raise the TypeError.

Note that `[] in set()` also raises TypeError, so it's consistent: values of types that are impossible for the container to contain generally raise TypeError (in this case, an unhashable type and a container that only accepts hashable types).

(I may be oversimplifying this a bit, but I think the basic idea is right.)