Reputation: 11883
I've been trying to tighten up a few classes of code with type hinting. I'm struggling with a nesting problem. The parameter of a function of interest is an iterable container of objects with known types. I'm having trouble getting my IDE to recognize the inner types (which is a nice convenience.)
I'm using python 3.9 on PyCharm, but I'm getting similar auto-complete results in Ipython.
When using the Iterable
class out of typing
module, the IDE cannot "see through" to the inner types. Similarly for Collection
. But it can when using either list
or tuple
on the outer container.
Is this an IDE issue or is there another way to package this? It would be nice to be able to send this function any type of iterable, rather than hard code it...
from datetime import datetime
from typing import Iterable
Data_collection = Iterable[tuple[datetime, str]]
Data_list = list[tuple[datetime, str]]
def foo(bar: Data_collection):
bar[1][0]. # no type-hint on inner obj
def foo2(bar: Data_list):
bar[1][0]. # good type-hint on inner obj
Gets me (PyCharm) results like this:
Upvotes: 2
Views: 277
Reputation: 530882
You are using the wrong abstract base class. Iterable
only promises/requires __iter__
to be implemented, not __getitem__
. Statically speaking, bar[1]
isn't guaranteed to be defined.
To specify any type that supports indexing, use Sequence
instead.
from typing import Sequence
Data_collection = Sequence[tuple[datetime, str]]
Now, regardless of the runtime type of bar
, your IDE can assume that bar.__getitem__
is defined and returns a tuple
. (Whether your specific IDE does make that assumption depends on the IDE, not your code.)
Upvotes: 4