Dictionaries and TypedDict#

Dictionary inputs can be specified using either a standard Dict[K, V] annotation, or a TypedDict subclass.

For configuring TypedDict, we also support total={True/False}, typing.Required, and typing.NotRequired.

 1from typing import TypedDict
 2
 3from typing_extensions import NotRequired
 4
 5import tyro
 6
 7
 8class DictionarySchemaA(
 9    TypedDict,
10    # Setting `total=False` specifies that not all keys need to exist.
11    total=False,
12):
13    learning_rate: float
14    betas: tuple[float, float]
15
16
17class DictionarySchemaB(TypedDict):
18    learning_rate: NotRequired[float]
19    """NotRequired[] specifies that a particular key doesn't need to exist."""
20    betas: tuple[float, float]
21
22
23def main(
24    typed_dict_a: DictionarySchemaA,
25    typed_dict_b: DictionarySchemaB,
26    standard_dict: dict[str, float] = {
27        "learning_rate": 3e-4,
28        "beta1": 0.9,
29        "beta2": 0.999,
30    },
31) -> None:
32    assert isinstance(typed_dict_a, dict)
33    assert isinstance(typed_dict_b, dict)
34    assert isinstance(standard_dict, dict)
35    print("Typed dict A:", typed_dict_a)
36    print("Typed dict B:", typed_dict_b)
37    print("Standard dict:", standard_dict)
38
39
40if __name__ == "__main__":
41    tyro.cli(main)

python 04_additional/02_dictionaries.py --help
usage: 02_dictionaries.py [-h] [OPTIONS]

╭─ options ──────────────────────────────────────────────────────────────────╮
│ -h, --help        show this help message and exit                          │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ typed-dict-a options ─────────────────────────────────────────────────────╮
│ --typed-dict-a.learning-rate FLOAT                                         │
│                   (unset by default)                                       │
│ --typed-dict-a.betas FLOAT FLOAT                                           │
│                   (unset by default)                                       │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ typed-dict-b options ─────────────────────────────────────────────────────╮
│ --typed-dict-b.learning-rate FLOAT                                         │
│                   NotRequired[] specifies that a particular key doesn't    │
│                   need to exist. (unset by default)                        │
│ --typed-dict-b.betas FLOAT FLOAT                                           │
│                   (required)                                               │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ standard-dict options ────────────────────────────────────────────────────╮
│ --standard-dict.learning-rate FLOAT                                        │
│                   (default: 0.0003)                                        │
│ --standard-dict.beta1 FLOAT                                                │
│                   (default: 0.9)                                           │
│ --standard-dict.beta2 FLOAT                                                │
│                   (default: 0.999)                                         │
╰────────────────────────────────────────────────────────────────────────────╯

python 04_additional/02_dictionaries.py --typed-dict-a.learning-rate 3e-4 --typed-dict-b.betas 0.9 0.999
Typed dict A: {'learning_rate': 0.0003}
Typed dict B: {'betas': (0.9, 0.999)}
Standard dict: {'learning_rate': 0.0003, 'beta1': 0.9, 'beta2': 0.999}

python 04_additional/02_dictionaries.py --typed-dict-b.betas 0.9 0.999
Typed dict A: {}
Typed dict B: {'betas': (0.9, 0.999)}
Standard dict: {'learning_rate': 0.0003, 'beta1': 0.9, 'beta2': 0.999}