def f(arg: Sequence[str]):
if isinstance(arg, str):
raise TypeError("arg should be a sequance of str, not str")
for string in arg:
print(string)
If a str value is passed to this function, an error would raise.
However, the IDE would not mark this as error. Because, str is a kind of Sequence[str] indeed.
Expected result:
f("dummy") # should get a type-hint warning
f(["aaa", "bbb"]) # should be ok
class MySequence(Sequence):
...
f(MySequence("aaa", "bbb")) # should be ok
So how shall I type-hint this argument to solve this problem?
It is not possible to create a type hint like “Type A except subtype B”. Your only option is to create a union of the types you do in fact support, and optionally alias it.
In your case, a Sequence can be one of list, tuple, str, range, bytes, bytearray or memoryview. The only Sequence[str] types that make sense are list[str] and tuple[str], so why not use list[str] | tuple[str]?
Edit: Sorry, I missed that you wanted to create your own Sequence type. In that case, create an alias for a union of list, tuple, and your own type:
Note that tuple[str] means “a tuple of length 1, where the sole element is of type str”. You’ll usually want to use tuple[str, ...] (meaning “a tuple of arbitrary length, where all elements are of type str”) rather than tuple[str].