On Tue, Apr 3, 2018 at 7:34 PM Ethan Furman email@example.com wrote:
This behavior was recently brought to my attention :
--> 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.
 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.)