Python type annotation for sequences of strings, but not for strings?
Question:
Is there a Python type hint that matches lists, tuples and possibly other sequential types, but does not match strings?
The issue is that strings are at the same time sequences of strings of length 1 (e.g. individual characters), so they technically match the Sequence[str]
, but providing a string to a function expecting a list of strings is an error in maybe 100% cases.
Is there a way to exclude strings from type annotation to make it something similar to non-existent And[Sequence[str], Not[str]]
?
As for the purpose, I would like to annotate this function:
PathType = Union[str, os.PathLike]
def escape_cmdline(argv: Union[List[PathType], Tuple[PathType]]) -> str: ...
But existing signature looks bloated to me, and does not cover any custom types that are list and tuple compatible. Is there any better way?
Answers:
I couldn’t find anything about the type exclusion or the type negation, seems like it’s not supported in current version of Python 3. So the only distinctive feature of strings that crossed my mind is that strings are immutable. Maybe it’ll help:
from typing import Union
from collections.abc import MutableSequence
MySequenceType = Union[MutableSequence, tuple, set]
def foo(a: MySequenceType):
pass
foo(["09485", "kfjg", "kfjg"]) # passed
foo(("09485", "kfjg", "kfjg")) # passed
foo({"09485", "kfjg", "kfjg"}) # passed
foo("qwerty") # not passed
I might not fully understand your questions but to me it looks like you’re in search for the following shortcut:
for object in data:
if not isinstance(object, type):
your code functions + list...
.... etc.
wherease type is str
and object
an variable from your raw data provided through a list
or tuple
of items. If I misunderstood your question deepening your question with more details may perhaps help? Or was the above answer enough to get you going? Then a little feedback wound be nice 😉
Apparently, this is not possible with type hints. PEP 484 can not distinguish between Sequence[str]
, Iterable[str]
and str
according to Guido van Rossum.
Source: https://github.com/python/mypy/issues/1965 and https://github.com/python/typing/issues/256
Is there a Python type hint that matches lists, tuples and possibly other sequential types, but does not match strings?
The issue is that strings are at the same time sequences of strings of length 1 (e.g. individual characters), so they technically match the Sequence[str]
, but providing a string to a function expecting a list of strings is an error in maybe 100% cases.
Is there a way to exclude strings from type annotation to make it something similar to non-existent And[Sequence[str], Not[str]]
?
As for the purpose, I would like to annotate this function:
PathType = Union[str, os.PathLike]
def escape_cmdline(argv: Union[List[PathType], Tuple[PathType]]) -> str: ...
But existing signature looks bloated to me, and does not cover any custom types that are list and tuple compatible. Is there any better way?
I couldn’t find anything about the type exclusion or the type negation, seems like it’s not supported in current version of Python 3. So the only distinctive feature of strings that crossed my mind is that strings are immutable. Maybe it’ll help:
from typing import Union
from collections.abc import MutableSequence
MySequenceType = Union[MutableSequence, tuple, set]
def foo(a: MySequenceType):
pass
foo(["09485", "kfjg", "kfjg"]) # passed
foo(("09485", "kfjg", "kfjg")) # passed
foo({"09485", "kfjg", "kfjg"}) # passed
foo("qwerty") # not passed
I might not fully understand your questions but to me it looks like you’re in search for the following shortcut:
for object in data:
if not isinstance(object, type):
your code functions + list...
.... etc.
wherease type is str
and object
an variable from your raw data provided through a list
or tuple
of items. If I misunderstood your question deepening your question with more details may perhaps help? Or was the above answer enough to get you going? Then a little feedback wound be nice 😉
Apparently, this is not possible with type hints. PEP 484 can not distinguish between Sequence[str]
, Iterable[str]
and str
according to Guido van Rossum.
Source: https://github.com/python/mypy/issues/1965 and https://github.com/python/typing/issues/256