Open jstasiak opened 6 years ago
This is currently not possible. We will probably need the Const
type modifier for this to work, see https://github.com/python/mypy/issues/1214
We now have a Final
modified but that isn't enough, since we never implicitly infer TypedDict types from dict expressions.
Another4 request for this appeared, see https://github.com/python/mypy/issues/8186, so raising priority to normal.
(Just to clarify, we can start from only supporting final names for individual keys, which should be pretty easy.)
@ilevkivskyi I agree that we can just support final names for keys first, at least for NamedTuple, as stated at the end of PEP-591:
Type checkers should treat uses of a final name that was initialized with a literal as if it was replaced by the literal. For example, the following should be allowed:
X: Final = "x" Y: Final = "y" N = NamedTuple("N", [(X, int), (Y, int)])
It is sometimes useful to have different types on the same label as well:
X: Final = "x"
Y: Final = "y"
Position = NamedTuple("Position", [(X, int), (Y, int)])
DimensionName = NamedTuple("DimensionName", [(X, str), (Y, str)])
is there any update on this issue when Final is used? This seems last updated about two years ago
I would expect this to be legal:
In [3]: from typing import TypedDict, List, Final
In [6]: X: Final = "namespaces_read"
In [7]: Y: Final = "namespaces_write"
In [4]: Permissions = TypedDict(
...: "Permissions", {X: List[str], Y: List[str]}
...: )
In [8]: Z: Permissions = {X: [], Y: []}
Let me know if you'd like me to remove this and create a separate issue if it's off scope. This falls under the canopy of TypedDict
keys reuse, but it looks like this issue came to be about subsets, when I want reuse across keyed structures
Allow all "typed fields" / keyed data structures to reuse their typings.
e.g. typing.TypedDict
, typing.NamedTuple
and dataclasses.dataclass
.
Assume my case, I want to offer users ability to export a typed tuple and dict from my Details
dataclass, dataclasses.astuple
and dataclasses.asdict
#!/usr/bin/env python
import dataclasses
from typing import NamedTuple, TypedDict, get_type_hints
class DetailsDict(TypedDict):
name: str
age: int
address: str
class DetailsTuple(NamedTuple):
name: str
age: int
address: str
@dataclasses.dataclass
class Details:
name: str
age: int
address: str
def to_dict(self) -> DetailsDict:
# return dataclasses.asdict(self, dict_factory=DetailsDict)
return DetailsDict(**dataclasses.asdict(self))
def to_tuple(self) -> DetailsTuple:
# return dataclasses.astuple(self, tuple_factory=DetailsTuple)
return DetailsTuple(*dataclasses.astuple(self))
john = Details(name="John", age=25, address="123 Address St")
print(john)
print(john.to_dict())
print(john.to_tuple())
print(get_type_hints(john))
print(get_type_hints(john.to_dict))
print(get_type_hints(john.to_tuple))
Output:
Details(name='John', age=25, address='123 Address St')
{'name': 'John', 'age': 25, 'address': '123 Address St'}
DetailsTuple(name='John', age=25, address='123 Address St')
{'name': <class 'str'>, 'age': <class 'int'>, 'address': <class 'str'>}
{'return': <class '__main__.DetailsDict'>}
{'return': <class '__main__.DetailsTuple'>
strict = True
compliance
They have an open source library and want tuples / dicts to be available for downstream use.
*params
, **params
, e.g. loading dataargs
/kwargs
of function declarations, e.g. Details(*DetailsTuple(name='John', age=25, address='123 Address St'))
Details(**DetailsDict(**{'name': 'John', 'age': 25, 'address': '123 Address St'}))
We have to redeclare the same field annotations for dict, tuple, and dataclass
We need a way to reuse the field typings across the different keyed data structures.
Why would a user want to reuse dict/tuple/etc?
class CreateArgs(TypedDict):
first_name: str
last_name: str
external_id: str
address: str
city: str
phone: str
zip: str
email: str
state: str
class UpdateArgs(TypedDict, total=False):
first_name: str
last_name: str
external_id: str
address: str
city: str
phone: str
zip: str
email: str
state: str
type CreateArgs = {
first_name: string;
last_name: string;
external_id: string;
address: string;
city: string;
phone: string;
zip: string;
email: string;
state: string;
};
type UpdateArgs = Partial<CreateArgs>;
For me it's not about compliance, neither an open-source library. It's code repetition. I would like to define the keys only once.
I may be in a need of the following - two
TypeDict
s with the same keys, one of them created withtotal=False
:Is there a way to reuse the keys instead of having to repeat the
{'name': str, 'age': int, address: str}
fragment twice?I can't do
Because
(which is quite reasonable, tried that on the off chance it'd work)