-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Precise typing for TypedDict wrappers #7856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think the only current way is to use an overload for every key, which is obviously not great. |
A feature that would allow this (key types) was discussed a while ago at typing meetup (the primary goal for it was typing for pandas dataframes). We will likely support something like this at some point, but not in near future. |
Workaround that currently works, suggested by @JelleZijlstra , however, it will be cumbersome with more keys. from typing import Optional, overload
from typing_extensions import Literal
from mypy_extensions import TypedDict
class Test(TypedDict):
a: str
b: int
c: int
class Foo:
def __init__(self):
self._foo: Optional[Test] = None
def _set(self) -> None:
self._foo = {"a": "a", "b": 0, "c": 1}
@overload
def __getitem__(self, key: Literal["a"]) -> str:
...
@overload
def __getitem__(self, key: Literal["b", "c"]) -> int:
...
def __getitem__(self, key):
self._set()
assert self._foo is not None
return self._foo[key]
def a(self) -> str:
return self["a"]
def b(self) -> int:
return self["b"]
a = Foo().a()
a.find("a")
b = Foo().b()
b.find("a") # CORRECT: "int" has no attribute "find"
c = Foo()["a"]
c.find("a")
d = Foo()["b"]
d.find("a") # CORRECT: "int" has no attribute "find" Should I close this issue for now? |
No, I think it is useful to have this use case in mind while working on key types. |
Ideally you would want a way for |
What I have found is that the type given is usually the union across all possible keys even if it is a literal known before running. I wonder if a change could be made to refine this type if it is known. Like C++ |
Bug or feature request: feature request (I think)
I tried to use TypedDict for my codebase and ran into some issues. Consider the following code snippet:
(
Python 3.8.0
,mypy==0.740
,mypy-extensions==0.4.3
)I'm not sure what the correct return type signature for a wrapping
__getitem__
would be. BothAny
andUnion
seem to erase the actual type coming from theTypedDict
and lead to incorrect results. Is there currently a way to achieve the desired behavior here? Also, is there a way to specify Literals for the keys without manually copying them?Something like
would be cool if it worked.
The text was updated successfully, but these errors were encountered: