Is it possible to negate in type annotations?

Sometimes I want to allow that you can pass to a parameter any kind of iterable, except str. Is there a way to annotate it with a type hint?

Hm, maybe two overloads, the first one taking a str and returning Never, and the second one taking everything else?

Otherwise, maybe something like useful_types/useful_types/__init__.py at 305c66f860117ea41e0dd1f951f2fc3b4786c57e · hauntsaninja/useful_types · GitHub ?

2 Likes

That doesn’t work, because a str value is also a value of type Iterable[str]. The str -> Never overload will just never be taken.

This is currently only somewhat possible. In general, negating types has been brought up several times in the typing forum, but it is a very complicated idea to get right and there currently is no PEP under consideration or something similar. However, the particular case of sequences that aren’t str has a tricky solution that doesn’t rely on negating types but on the exact defintion of their __contains__ dunder. You can find it in this github discussion. You might be able to use the same idea to write a protocol that allows iterables of strings but not str itself.

1 Like