Custom Constructors#
For additional flexibility, tyro.conf.arg()
accepts a constructor
argument,
which makes it easier to load complex objects.
1import json as json_
2
3from typing_extensions import Annotated
4
5import tyro
6
7
8def dict_json_constructor(json: str) -> dict:
9 """Construct a dictionary from a JSON string. Raises a ValueError if the result is
10 not a dictionary."""
11 out = json_.loads(json)
12 if not isinstance(out, dict):
13 raise ValueError(f"{json} is not a dictionary!")
14 return out
15
16
17# A dictionary type, but `tyro` will expect a JSON string from the CLI.
18JsonDict = Annotated[dict, tyro.conf.arg(constructor=dict_json_constructor)]
19
20
21def main(
22 dict1: JsonDict,
23 dict2: JsonDict = {"default": None},
24) -> None:
25 print(f"{dict1=}")
26 print(f"{dict2=}")
27
28
29if __name__ == "__main__":
30 tyro.cli(main)
python 04_additional/11_custom_constructors.py --help
usage: 11_custom_constructors.py [-h] --dict1.json STR [--dict2.json STR] ╭─ options ──────────────────────────────────────────────────────────────────╮ │ -h, --help show this help message and exit │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭─ dict1 options ────────────────────────────────────────────────────────────╮ │ Construct a dictionary from a JSON string. Raises a ValueError if the │ │ result is │ │ not a dictionary. │ │ ────────────────────────────────────────────────────────────────────────── │ │ --dict1.json STR (required) │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭─ dict2 options ────────────────────────────────────────────────────────────╮ │ Construct a dictionary from a JSON string. Raises a ValueError if the │ │ result is │ │ not a dictionary. │ │ │ │ Default: {'default': None} │ │ ────────────────────────────────────────────────────────────────────────── │ │ --dict2.json STR (optional) │ ╰────────────────────────────────────────────────────────────────────────────╯
python 04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}'
dict1={'hello': 'world'} dict2={'default': None}
python 04_additional/11_custom_constructors.py --dict1.json '{"hello": "world"}`' --dict2.json '{"hello": "world"}'
╭─ Value error ────────────────────────────────────────────────────────────────╮ │ Error parsing dict1: Extra data: line 1 column 19 (char 18) │ ╰──────────────────────────────────────────────────────────────────────────────╯