Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mypy: Correct way of type-annotating list of multiple types

I have a list of lists that each contain a file object and a list of strings:

sample = [
    [fileobject1, ['hello', 'world']],
    [fileobject2, ['something', 'else']]
]

I type annotated sample like this:

List[List[Union[IO, List[str]]]]

Further in my code I call some methods on the first (0) and second (1) entry of the inner list.

For example like this to clear the most inner list:

entry[1].clear()

The code runs fine, but mypy rightly complains that:

Item "IO[Any]" of "Union[IO[Any], List[str]]" has no attribute "clear"

How would I type-annotate this correctly? Maybe use a different data structure all together?

like image 679
user1683766 Avatar asked Sep 27 '18 19:09

user1683766


1 Answers

Rather then using lists, you should use tuples. For example:

sample: List[Tuple[IO, List[str]]] = [
   (fileobject1, ['hello', 'world']),
   (fileobject2, ['something', 'else']),
]

Mypy assumes that lists are homogeneous: they will only ever contain one kind of type. Tuples are meant to contain heterogeneous data: each item is allowed to have a different type.

Note that tuples aren't the only types you could use here -- you could create and use a custom class, or used NamedTuples... But switching to tuples would likely be the simplest fix here.

like image 158
Michael0x2a Avatar answered Oct 01 '22 16:10

Michael0x2a