'Are Python Multi-Level Generics losing type information?
I use Type Annotations to allow my IDE PyCharm to provide me with autocomplete and typechecking.
For my current project i built a multi-level generic class hierarchy, however, at some point, some of the type information seems to get lost.
I am not sure if this is my fault, a problem of the python type annotation/generics mechanisms, a problem of the IDE or intended behaviour.
Let me explain this with a short example:
L = TypeVar("L")
class List(Generic[L]):
# rather generic list implementation
def get(self) -> L:
return None
T = TypeVar("T")
class ListList(Generic[T], List[list[T]]):
# generic implementation of a list of lists
pass
class A(ListList[str]):
# actual implementation of a list of lists of a specific type
pass
ll = A()
l = ll.get()
e = l[0]
Here, pycharm shows the type of l as list[T] and the type of e as T
whereas i would expect it to be list[str] and str respectively.
Am I using the Generics wrong, is this behaviour a bug in the typing/generics mechanism of python, a bug in the pyCharm IDE or is this intended behaviour?
If it is intended, can someone explain the reasons behind it, or point me to such explanations?
And regardless of the cause of this, can anyone show me a way how to make pycharm recognise the types of l and e correctly and thus provide me with useful autocomplete and stuff like that.
Solution 1:[1]
This behavior appears to be a bug: https://youtrack.jetbrains.com/issue/PY-53082
Using mypy's reveal_type on the last line confirms the type you expected is correct.
ll = A()
l = ll.get()
e = l[0]
reveal_type(l)
reveal_type(e)
$ mypy sample.py
sample.py:7: error: Incompatible return value type (got "None", expected "L")
sample.py:24: note: Revealed type is "builtins.list*[builtins.str*]"
sample.py:25: note: Revealed type is "builtins.str*"
In a pinch you can specify the correct type where the variable is created.
ll = A()
l: list[str] = ll.get()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
