In python, how can I make a dict/typeddict that has a default type and type hints for known keys (additionalProperties implementation)?
Question:
In python, how can I make a dict that has type hints for know keys and a default type for unknown keys?
I have tried using a typing.TypeDict but I do not see how to set the type on the unknown key type.
import typing
class SomeDict(typing.Typeddict):
a: str
b: int
some_dict = SomeDict({"a": "a", "b": 0, "c": 3.14})
val_a = some_dict.get("a")
val_b = some_dict.get("b")
val_c = some_dict.get("c")
This would be especially helpful if an IDE like pycharm or vscode could correctly see the type of the value stored in the dict.
Answers:
This is possible today in visual studio code (vscode).
See the below working example.
import typing
class SomeDict(dict):
@typing.overload
def __getitem__(self, name: typing.Literal["a"]) -> str: ...
@typing.overload
def __getitem__(self, name: typing.Literal["b"]) -> int: ...
@typing.overload
def __getitem__(self, name: str) -> float: ...
def __getitem__(self, name):
return super().__getitem__(name)
...
some_dict = SomeDict({"a": "a", "b": 0, "hi there": 1.234})
val_a = some_dict["a"] # str
val_b = some_dict["b"] # bool
another_val = some_dict["hi there"] # float
Validating those inputs is left up to the developer
One could implement that in __new__
or __init__
.
Hopefully pycharm will support this soon in https://youtrack.jetbrains.com/issue/PY-42137/PyCharm-type-hinting-doesnt-work-well-with-overload-decorator
And with the soon to be added python 3.11 PEP 675 addition of typing.LiteralString one could
- require that only string literals are passed in, and that generic strings are not passed in (if one wanted)
- or set the type hint on str to include all of the overloaded types because that would happen when a non-literal string is passed in
But this is only for retrieval of properties, it is not for assigning properties to the dict 🙁
In python, how can I make a dict that has type hints for know keys and a default type for unknown keys?
I have tried using a typing.TypeDict but I do not see how to set the type on the unknown key type.
import typing
class SomeDict(typing.Typeddict):
a: str
b: int
some_dict = SomeDict({"a": "a", "b": 0, "c": 3.14})
val_a = some_dict.get("a")
val_b = some_dict.get("b")
val_c = some_dict.get("c")
This would be especially helpful if an IDE like pycharm or vscode could correctly see the type of the value stored in the dict.
This is possible today in visual studio code (vscode).
See the below working example.
import typing
class SomeDict(dict):
@typing.overload
def __getitem__(self, name: typing.Literal["a"]) -> str: ...
@typing.overload
def __getitem__(self, name: typing.Literal["b"]) -> int: ...
@typing.overload
def __getitem__(self, name: str) -> float: ...
def __getitem__(self, name):
return super().__getitem__(name)
...
some_dict = SomeDict({"a": "a", "b": 0, "hi there": 1.234})
val_a = some_dict["a"] # str
val_b = some_dict["b"] # bool
another_val = some_dict["hi there"] # float
Validating those inputs is left up to the developer
One could implement that in __new__
or __init__
.
Hopefully pycharm will support this soon in https://youtrack.jetbrains.com/issue/PY-42137/PyCharm-type-hinting-doesnt-work-well-with-overload-decorator
And with the soon to be added python 3.11 PEP 675 addition of typing.LiteralString one could
- require that only string literals are passed in, and that generic strings are not passed in (if one wanted)
- or set the type hint on str to include all of the overloaded types because that would happen when a non-literal string is passed in
But this is only for retrieval of properties, it is not for assigning properties to the dict 🙁