Combining PEPs 637 & 655 to define inline TypedDicts
Hi there, It's fairly common within our code bases to define throwaway dicts for adding logging context or generating keyword arguments dynamically, e.g.: kwargs = {} if foo: kwargs["something"] = foo if bar: kwargs["another_thing"] = [1, 2, 3] cool_function(**kwargs) Defining TypedDict subclasses for these throwaway dicts can be tiresome, so these often get annotated with dict[str, Any], which opens a door for errors that a type checker would catch if we did define TypedDicts for them. I've been following the progress of PEPs 637 & 655 and had a thought this morning that they could be combined to generate a not-horrifically-ugly way to define TypedDicts inline. For the example above: kwargs: TypedDict[something=Required[str], another_thing=NotRequired[list[int]]] = {} if foo: ... Is it worth pursuing this thought further, or are there blockers on this that I'm oblivious to? Cheers, Andrew
I don't see any technical reason to avoid this. I would suggest an even more concise syntax that doesn't rely on PEP 637, modeled on TypeScript: kwargs: {"something": Required[str], "another_thing": NotRequired[list[int]]} = {} You could also define a named TypedDict type that way (using PEP 613): TwoThings: TypeAlias = {"something": Required[str], "another_thing": NotRequired[list[int]]} kwargs: TwoThings = {} And do inheritance: ThreeThings: TypeAlias = {**TwoThings, "third_thing": int} El vie, 12 mar 2021 a las 7:41, Andrew Taumoefolau (<zenbot@gmail.com>) escribió:
Hi there,
It's fairly common within our code bases to define throwaway dicts for adding logging context or generating keyword arguments dynamically, e.g.:
kwargs = {} if foo: kwargs["something"] = foo if bar: kwargs["another_thing"] = [1, 2, 3] cool_function(**kwargs)
Defining TypedDict subclasses for these throwaway dicts can be tiresome, so these often get annotated with dict[str, Any], which opens a door for errors that a type checker would catch if we did define TypedDicts for them.
I've been following the progress of PEPs 637 & 655 and had a thought this morning that they could be combined to generate a not-horrifically-ugly way to define TypedDicts inline. For the example above:
kwargs: TypedDict[something=Required[str], another_thing=NotRequired[list[int]]] = {} if foo: ...
Is it worth pursuing this thought further, or are there blockers on this that I'm oblivious to?
Cheers,
Andrew _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: jelle.zijlstra@gmail.com
I agree that it's an idea worth exploring further. I'll point out that the following statement would be flagged as an error, however, because the assigned value doesn't contain the required keys. ```python kwargs: TypedDict[a=Required[str], b=NotRequired[list[int]]] = {} ``` One potential complexity with Jelle's TypeAlias idea is if it were to also support generics (which I presume it would, for consistency with other type aliases). This would probably require more changes to existing type checkers. ```python T1 = TypeVar("T1") T2 = TypeVar("T2") TwoThings: TypeAlias = {"a": T1, "b": NotRequired[list[T2]]} ThreeThings: TypeAlias = {**TwoThings[T1, T2], "c": int} ``` -- Eric Traut Contributor to Pyright & Pylance Microsoft Corp.
participants (3)
-
Andrew Taumoefolau
-
Eric Traut
-
Jelle Zijlstra