AirSquid
AirSquid

Reputation: 11883

Nested Type Hinting Differing Results

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:

enter image description here

enter image description here

Upvotes: 2

Views: 277

Answers (1)

chepner
chepner

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

Related Questions