.. Comment: this file is automatically generated by `update_example_docs.py`.
   It should not be modified manually.

.. _example-category-hierarchical_structures:

Hierarchical structures
=======================

In these examples, we show how :func:`tyro.cli` can be used to instantiate
hierarchical structures. This can enable modular, reusable, and composable CLI
interfaces.


.. _example-01_nesting:

Nested dataclasses
------------------

Structures (typically :py:func:`dataclasses.dataclass`) can be nested to build hierarchical configuration
objects. This helps with modularity and grouping in larger projects.


.. code-block:: python
    :linenos:

    # 01_nesting.py
    import dataclasses

    import tyro

    @dataclasses.dataclass
    class OptimizerConfig:
        learning_rate: float = 3e-4
        weight_decay: float = 1e-2

    @dataclasses.dataclass
    class Config:
        # Optimizer options.
        opt: OptimizerConfig

        # Random seed.
        seed: int = 0

    if __name__ == "__main__":
        config = tyro.cli(Config)
        print(dataclasses.asdict(config))




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./01_nesting.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./01_nesting.py [-h] [--seed <span style="font-weight: bold">INT</span>] [--opt.learning-rate <span style="font-weight: bold">FLOAT</span>] [--opt.weight-decay <span style="font-weight: bold">FLOAT</span>]
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help  <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --seed <span style="font-weight: bold">INT  </span><span style="font-weight: lighter">Random</span><span style="font-weight: lighter"> seed.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 0)      </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">opt</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> Optimizer options.                          <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────────────</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --opt.learning-rate <span style="font-weight: bold">FLOAT                  </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>             <span style="color: #008080">(default:</span><span style="color: #008080"> 0.0003)              </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --opt.weight-decay <span style="font-weight: bold">FLOAT                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>             <span style="color: #008080">(default:</span><span style="color: #008080"> 0.01)                </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./01_nesting.py --opt.learning-rate 1e-3</strong>
    {'opt': {'learning_rate': 0.001, 'weight_decay': 0.01}, 'seed': 0}
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./01_nesting.py --seed 4</strong>
    {'opt': {'learning_rate': 0.0003, 'weight_decay': 0.01}, 'seed': 4}
    </pre>
.. _example-02_nesting_in_func:

Structures as function arguments
--------------------------------

Structures can be used as input to functions.


.. code-block:: python
    :linenos:

    # 02_nesting_in_func.py
    import dataclasses
    import pathlib

    import tyro

    @dataclasses.dataclass
    class OptimizerConfig:
        learning_rate: float = 3e-4
        weight_decay: float = 1e-2

    @dataclasses.dataclass
    class Config:
        # Optimizer options.
        optimizer: OptimizerConfig

        # Random seed.
        seed: int = 0

    def train(
        out_dir: pathlib.Path,
        config: Config,
    ) -> None:
        """Train a model.

        Args:
            out_dir: Where to save logs and checkpoints.
            config: Experiment configuration.
        """
        print(f"Saving to: {out_dir}")
        print(f"Config: {config}")

    if __name__ == "__main__":
        tyro.cli(train)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./02_nesting_in_func.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./02_nesting_in_func.py [-h] [OPTIONS]
    
    Train a model.
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help         <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit               </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --out-dir <span style="font-weight: bold">PATH     </span><span style="font-weight: lighter">Where</span><span style="font-weight: lighter"> to</span><span style="font-weight: lighter"> save</span><span style="font-weight: lighter"> logs</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> checkpoints.</span> <span style="color: #e60000">(required)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> Experiment configuration.                                         <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────────────────────────</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.seed <span style="font-weight: bold">INT  </span><span style="font-weight: lighter">Random</span><span style="font-weight: lighter"> seed.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 0)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config.optimizer</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> Optimizer options.                                                <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────────────────────────</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.optimizer.learning-rate <span style="font-weight: bold">FLOAT                           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>                    <span style="color: #008080">(default:</span><span style="color: #008080"> 0.0003)                             </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.optimizer.weight-decay <span style="font-weight: bold">FLOAT                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>                    <span style="color: #008080">(default:</span><span style="color: #008080"> 0.01)                               </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./02_nesting_in_func.py --out-dir /tmp/test1</strong>
    Saving to: /tmp/test1
    Config: Config(optimizer=OptimizerConfig(learning_rate=0.0003, weight_decay=0.01), seed=0)
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./02_nesting_in_func.py --out-dir /tmp/test2 --config.seed 4</strong>
    Saving to: /tmp/test2
    Config: Config(optimizer=OptimizerConfig(learning_rate=0.0003, weight_decay=0.01), seed=4)
    </pre>
.. _example-03_nesting_containers:

Nesting in containers
---------------------

Structures can be nested inside of standard containers.

.. warning::

    When placing structures inside of containers like lists or tuples, the
    length of the container must be inferrable from the annotation or default
    value.


.. code-block:: python
    :linenos:

    # 03_nesting_containers.py
    import dataclasses

    import tyro

    @dataclasses.dataclass
    class RGB:
        r: int
        g: int
        b: int

    @dataclasses.dataclass
    class Args:
        color_tuple: tuple[RGB, RGB]
        color_dict: dict[str, RGB] = dataclasses.field(
            # We can't use mutable values as defaults directly.
            default_factory=lambda: {
                "red": RGB(255, 0, 0),
                "green": RGB(0, 255, 0),
                "blue": RGB(0, 0, 255),
            }
        )

    if __name__ == "__main__":
        args = tyro.cli(Args)
        print(args)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./03_nesting_containers.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./03_nesting_containers.py [-h] [OPTIONS]
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help                <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">color-tuple.0</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.0.r <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.0.g <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.0.b <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">color-tuple.1</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.1.r <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.1.g <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-tuple.1.b <span style="font-weight: bold">INT     </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">color-dict.red</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.red.r <span style="font-weight: bold">INT    </span><span style="color: #008080">(default:</span><span style="color: #008080"> 255)                 </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.red.g <span style="font-weight: bold">INT    </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.red.b <span style="font-weight: bold">INT    </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">color-dict.green</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.green.r <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.green.g <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 255)                 </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.green.b <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">color-dict.blue</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.blue.r <span style="font-weight: bold">INT   </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.blue.g <span style="font-weight: bold">INT   </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color-dict.blue.b <span style="font-weight: bold">INT   </span><span style="color: #008080">(default:</span><span style="color: #008080"> 255)                 </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>
.. _example-04_dictionaries:

Dictionaries and ``TypedDict``
------------------------------

Dictionary inputs can be specified using either a standard ``dict[K, V]``
annotation, or a :py:class:`TypedDict` subclass.

For configuring :py:class:`TypedDict`, we also support :code:`total={True/False}`,
:py:data:`typing.Required`, and :py:data:`typing.NotRequired`. See the `Python docs <https://docs.python.org/3/library/typing.html#typing.TypedDict>`_ for all :py:class:`TypedDict` features.


.. code-block:: python
    :linenos:

    # 04_dictionaries.py
    from typing import TypedDict

    from typing_extensions import NotRequired

    import tyro

    class DictionarySchemaA(
        TypedDict,
        # Setting `total=False` specifies that not all keys need to exist.
        total=False,
    ):
        learning_rate: float
        betas: tuple[float, float]

    class DictionarySchemaB(TypedDict):
        learning_rate: NotRequired[float]
        """NotRequired[] specifies that a particular key doesn't need to exist."""
        betas: tuple[float, float]

    def main(
        typed_dict_a: DictionarySchemaA,
        typed_dict_b: DictionarySchemaB,
        standard_dict: dict[str, float] = {
            "learning_rate": 3e-4,
            "beta1": 0.9,
            "beta2": 0.999,
        },
    ) -> None:
        assert isinstance(typed_dict_a, dict)
        assert isinstance(typed_dict_b, dict)
        assert isinstance(standard_dict, dict)
        print("Typed dict A:", typed_dict_a)
        print("Typed dict B:", typed_dict_b)
        print("Standard dict:", standard_dict)

    if __name__ == "__main__":
        tyro.cli(main)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./04_dictionaries.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./04_dictionaries.py [-h] [OPTIONS]
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help                                                                   <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit                                       </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">typed-dict-a</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --typed-dict-a.learning-rate <span style="font-weight: bold">FLOAT                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(unset</span><span style="color: #008080"> by</span><span style="color: #008080"> default)                                                    </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --typed-dict-a.betas <span style="font-weight: bold">FLOAT</span><span style="font-weight: bold"> FLOAT                                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(unset</span><span style="color: #008080"> by</span><span style="color: #008080"> default)                                                    </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">typed-dict-b</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --typed-dict-b.learning-rate <span style="font-weight: bold">FLOAT                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">NotRequired[]</span><span style="font-weight: lighter"> specifies</span><span style="font-weight: lighter"> that</span><span style="font-weight: lighter"> a</span><span style="font-weight: lighter"> particular</span><span style="font-weight: lighter"> key</span><span style="font-weight: lighter"> doesn't</span><span style="font-weight: lighter"> need</span><span style="font-weight: lighter"> to</span><span style="font-weight: lighter"> exist.</span>   <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(unset</span><span style="color: #008080"> by</span><span style="color: #008080"> default)                                                    </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --typed-dict-b.betas <span style="font-weight: bold">FLOAT</span><span style="font-weight: bold"> FLOAT                                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #e60000">(required)                                                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">standard-dict</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --standard-dict.learning-rate <span style="font-weight: bold">FLOAT                                         </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> 0.0003)                                                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --standard-dict.beta1 <span style="font-weight: bold">FLOAT                                                 </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> 0.9)                                                        </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --standard-dict.beta2 <span style="font-weight: bold">FLOAT                                                 </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> 0.999)                                                      </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./04_dictionaries.py --typed-dict-a.learning-rate 3e-4 --typed-dict-b.betas 0.9 0.999</strong>
    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}
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./04_dictionaries.py --typed-dict-b.betas 0.9 0.999</strong>
    Typed dict A: {}
    Typed dict B: {'betas': (0.9, 0.999)}
    Standard dict: {'learning_rate': 0.0003, 'beta1': 0.9, 'beta2': 0.999}
    </pre>
.. _example-05_tuples:

Tuples and ``NamedTuple``
-------------------------

Example using :func:`tyro.cli()` to instantiate tuple types. :py:class:`tuple`,
:py:data:`typing.Tuple`, and :py:class:`typing.NamedTuple` are all supported.


.. code-block:: python
    :linenos:

    # 05_tuples.py
    from typing import NamedTuple

    import tyro

    # Named tuples are interpreted as nested structures.
    class Color(NamedTuple):
        r: int
        g: int
        b: int

    class TupleType(NamedTuple):
        """Description.
        This should show up in the helptext!"""

        # Tuple types can contain raw values.
        color: tuple[int, int, int] = (255, 0, 0)

        # Tuple types can contain nested structures.
        two_colors: tuple[Color, Color] = (Color(255, 0, 0), Color(0, 255, 0))

    if __name__ == "__main__":
        x = tyro.cli(TupleType)
        assert isinstance(x, tuple)
        print(x)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./05_tuples.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./05_tuples.py [-h] [OPTIONS]
    
    Description. This should show up in the helptext!
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help            <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit                       </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --color <span style="font-weight: bold">INT</span><span style="font-weight: bold"> INT</span><span style="font-weight: bold"> INT   </span><span style="font-weight: lighter">Tuple</span><span style="font-weight: lighter"> types</span><span style="font-weight: lighter"> can</span><span style="font-weight: lighter"> contain</span><span style="font-weight: lighter"> raw</span><span style="font-weight: lighter"> values.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 255</span><span style="color: #008080"> 0</span><span style="color: #008080"> 0)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">two-colors.0</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.0.r <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 255)                                        </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.0.g <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.0.b <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">two-colors.1</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.1.r <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.1.g <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 255)                                        </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --two-colors.1.b <span style="font-weight: bold">INT  </span><span style="color: #008080">(default:</span><span style="color: #008080"> 0)                                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./05_tuples.py --color 127 127 127</strong>
    TupleType(color=(127, 127, 127), two_colors=(Color(r=255, g=0, b=0), Color(r=0, g=255, b=0)))
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./05_tuples.py --two-colors.1.r 127 --two-colors.1.g 0 --two-colors.1.b 0</strong>
    TupleType(color=(255, 0, 0), two_colors=(Color(r=255, g=0, b=0), Color(r=127, g=0, b=0)))
    </pre>
.. _example-06_pydantic:

Pydantic integration
--------------------

In addition to standard dataclasses, :func:`tyro.cli()` also supports
`Pydantic <https://github.com/pydantic/pydantic>`_ models.


.. code-block:: python
    :linenos:

    # 06_pydantic.py
    from pydantic import BaseModel, Field

    import tyro

    class Args(BaseModel):
        """Description.
        This should show up in the helptext!"""

        field1: str
        field2: int = Field(3, description="An integer field.")

    if __name__ == "__main__":
        args = tyro.cli(Args)
        print(args)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./06_pydantic.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./06_pydantic.py [-h] --field1 <span style="font-weight: bold">STR</span> [--field2 <span style="font-weight: bold">INT</span>]
    
    Description. This should show up in the helptext!
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help    <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field1 <span style="font-weight: bold">STR  </span><span style="color: #e60000">(required)                     </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field2 <span style="font-weight: bold">INT  </span><span style="font-weight: lighter">An</span><span style="font-weight: lighter"> integer</span><span style="font-weight: lighter"> field.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 3) </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./06_pydantic.py --field1 hello</strong>
    field1='hello' field2=3
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./06_pydantic.py --field1 hello --field2 5</strong>
    field1='hello' field2=5
    </pre>
.. _example-07_attrs:

Attrs integration
-----------------

In addition to standard dataclasses, :func:`tyro.cli()` also supports
`attrs <https://www.attrs.org/>`_ classes.


.. code-block:: python
    :linenos:

    # 07_attrs.py
    import attr

    import tyro

    @attr.s
    class Args:
        """Description.
        This should show up in the helptext!"""

        field1: str = attr.ib()
        """A string field."""

        field2: int = attr.ib(factory=lambda: 5)
        """A required integer field."""

    if __name__ == "__main__":
        args = tyro.cli(Args)
        print(args)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./07_attrs.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./07_attrs.py [-h] --field1 <span style="font-weight: bold">STR</span> [--field2 <span style="font-weight: bold">INT</span>]
    
    Description. This should show up in the helptext!
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help    <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit       </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field1 <span style="font-weight: bold">STR  </span><span style="font-weight: lighter">A</span><span style="font-weight: lighter"> string</span><span style="font-weight: lighter"> field.</span> <span style="color: #e60000">(required)            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field2 <span style="font-weight: bold">INT  </span><span style="font-weight: lighter">A</span><span style="font-weight: lighter"> required</span><span style="font-weight: lighter"> integer</span><span style="font-weight: lighter"> field.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 5)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./07_attrs.py --field1 hello</strong>
    Args(field1='hello', field2=5)
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./07_attrs.py --field1 hello --field2 5</strong>
    Args(field1='hello', field2=5)
    </pre>
.. _example-08_ml_collections:

ML collections
--------------

:func:`tyro.cli` understands and can populate config objects implemented using
`ml_collections <https://github.com/google/ml_collections/>`_, which is an
excellent library from folks at Google.

``ml_collections`` structures aren't statically typed, so we infer field types
based on value.


.. code-block:: python
    :linenos:

    # 08_ml_collections.py
    from pprint import pprint

    from ml_collections import ConfigDict, FrozenConfigDict  # type: ignore

    import tyro

    def get_config() -> FrozenConfigDict:
        config = ConfigDict()

        # Wandb config.
        config.wandb = ConfigDict()
        config.wandb.mode = "online"  # online, offline, disabled.
        config.wandb.project = "robot-sandbox"

        # Network config.
        config.network = ConfigDict()
        config.network.policy_layer_dims = (128,) * 3
        config.network.value_layer_dims = (256,) * 5
        config.network.policy_obs_key = "state"
        config.network.value_obs_key = "state"

        return FrozenConfigDict(config)

    def train(config: FrozenConfigDict = get_config()) -> None:
        """Train a model."""
        pprint(config.to_dict())  # type: ignore

    if __name__ == "__main__":
        tyro.cli(train)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./08_ml_collections.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./08_ml_collections.py [-h] [OPTIONS]
    
    Train a model.
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help                                         <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit             </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config.network</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">───────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.policy-layer-dims <span style="font-weight: bold">[INT</span><span style="font-weight: bold"> [INT</span><span style="font-weight: bold"> ...]]</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> 128</span><span style="color: #008080"> 128</span><span style="color: #008080"> 128)                      </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.policy-obs-key <span style="font-weight: bold">STR               </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> state)                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.value-layer-dims <span style="font-weight: bold">[INT</span><span style="font-weight: bold"> [INT</span><span style="font-weight: bold"> ...]] </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> 256</span><span style="color: #008080"> 256</span><span style="color: #008080"> 256</span><span style="color: #008080"> 256</span><span style="color: #008080"> 256)              </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.value-obs-key <span style="font-weight: bold">STR                </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> state)                            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config.wandb</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.wandb.mode <span style="font-weight: bold">STR                           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> online)                           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.wandb.project <span style="font-weight: bold">STR                        </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> robot-sandbox)                    </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./08_ml_collections.py --config.network.policy-layer-dims 64 64 64</strong>
    {'network': {'policy_layer_dims': (64, 64, 64),
                 'policy_obs_key': 'state',
                 'value_layer_dims': (256, 256, 256, 256, 256),
                 'value_obs_key': 'state'},
     'wandb': {'mode': 'online', 'project': 'robot-sandbox'}}
    </pre>
.. _example-09_ml_collections_refs:

ML collections + field references
---------------------------------

``ml_collections`` supports references for sharing values across multiple fields.


.. code-block:: python
    :linenos:

    # 09_ml_collections_refs.py
    from pprint import pprint

    from ml_collections import ConfigDict, FieldReference  # type: ignore

    import tyro

    def get_config() -> ConfigDict:
        config = ConfigDict()

        # Placeholder.
        hidden_dim_ref = FieldReference(128)
        config.hidden_dim = hidden_dim_ref

        # Wandb config.
        config.wandb = ConfigDict()
        config.wandb.mode = "online"  # online, offline, disabled.
        config.wandb.project = "robot-sandbox"

        # Network config.
        # Updating `policy_hidden_dim` will update `value_hidden_dim`, but
        # updating `value_hidden_dim` will not update `policy_hidden_dim`.
        config.network = ConfigDict()
        config.network.policy_hidden_dim = hidden_dim_ref
        config.network.value_hidden_dim = hidden_dim_ref * 2
        config.network.policy_obs_key = "state"
        config.network.value_obs_key = "state"

        return config

    def train(config: ConfigDict = get_config()) -> None:
        """Train a model."""
        pprint(config.to_dict())  # type: ignore

    if __name__ == "__main__":
        tyro.cli(train)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./09_ml_collections_refs.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./09_ml_collections_refs.py [-h] [OPTIONS]
    
    Train a model.
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">─────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help                                        <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.hidden-dim <span style="font-weight: bold">INT                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">Reference</span><span style="font-weight: lighter"> default:</span><span style="font-weight: lighter"> 128.</span> <span style="color: #008080">(assigns</span><span style="color: #008080"> reference)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config.network</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">──────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.policy-hidden-dim <span style="font-weight: bold">INT           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">Reference</span><span style="font-weight: lighter"> default:</span><span style="font-weight: lighter"> 128.</span> <span style="color: #008080">(assigns</span><span style="color: #008080"> reference)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.policy-obs-key <span style="font-weight: bold">STR              </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> state)                           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.value-hidden-dim <span style="font-weight: bold">INT            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="font-weight: lighter">Reference</span><span style="font-weight: lighter"> default:</span><span style="font-weight: lighter"> 256.</span> <span style="color: #008080">(assigns</span><span style="color: #008080"> reference)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.network.value-obs-key <span style="font-weight: bold">STR               </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> state)                           </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">config.wandb</span><span style="font-weight: lighter; color: #808080"> options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.wandb.mode <span style="font-weight: bold">STR                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> online)                          </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --config.wandb.project <span style="font-weight: bold">STR                       </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span>       <span style="color: #008080">(default:</span><span style="color: #008080"> robot-sandbox)                   </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">───────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./09_ml_collections_refs.py --config.hidden-dim 32</strong>
    {'hidden_dim': 32,
     'network': {'policy_hidden_dim': 32,
                 'policy_obs_key': 'state',
                 'value_hidden_dim': 64,
                 'value_obs_key': 'state'},
     'wandb': {'mode': 'online', 'project': 'robot-sandbox'}}
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./09_ml_collections_refs.py --config.network.policy-hidden-dim 64</strong>
    {'hidden_dim': 64,
     'network': {'policy_hidden_dim': 64,
                 'policy_obs_key': 'state',
                 'value_hidden_dim': 128,
                 'value_obs_key': 'state'},
     'wandb': {'mode': 'online', 'project': 'robot-sandbox'}}
    </pre>
.. _example-10_msgspec:

Msgspec integration
-------------------

In addition to standard dataclasses, :func:`tyro.cli()` also supports
`msgspec <https://jcristharif.com/msgspec/>`_ structs.


.. code-block:: python
    :linenos:

    # 10_msgspec.py
    import msgspec

    import tyro

    class Args(msgspec.Struct):
        """Description.
        This should show up in the helptext!"""

        field1: str
        """A string field."""

        field2: int = 5
        """A required integer field."""

    if __name__ == "__main__":
        args = tyro.cli(Args)
        print(args)




.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./10_msgspec.py --help</strong>
    <span style="font-weight: bold">usage:</span> ./10_msgspec.py [-h] --field1 <span style="font-weight: bold">STR</span> [--field2 <span style="font-weight: bold">INT</span>]
    
    Description. This should show up in the helptext!
    
    <span style="font-weight: lighter; color: #808080">╭</span><span style="font-weight: lighter; color: #808080">─</span> <span style="font-weight: lighter; color: #808080">options</span> <span style="font-weight: lighter; color: #808080">────────────────────────────────────────────╮</span>
    <span style="font-weight: lighter; color: #808080">│</span> -h, --help    <span style="font-weight: lighter">show</span><span style="font-weight: lighter"> this</span><span style="font-weight: lighter"> help</span><span style="font-weight: lighter"> message</span><span style="font-weight: lighter"> and</span><span style="font-weight: lighter"> exit       </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field1 <span style="font-weight: bold">STR  </span><span style="font-weight: lighter">A</span><span style="font-weight: lighter"> string</span><span style="font-weight: lighter"> field.</span> <span style="color: #e60000">(required)            </span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">│</span> --field2 <span style="font-weight: bold">INT  </span><span style="font-weight: lighter">A</span><span style="font-weight: lighter"> required</span><span style="font-weight: lighter"> integer</span><span style="font-weight: lighter"> field.</span> <span style="color: #008080">(default:</span><span style="color: #008080"> 5)</span> <span style="font-weight: lighter; color: #808080">│</span>
    <span style="font-weight: lighter; color: #808080">╰</span><span style="font-weight: lighter; color: #808080">──────────────────────────────────────────────────────</span><span style="font-weight: lighter; color: #808080">╯</span>
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./10_msgspec.py --field1 hello</strong>
    Args(field1='hello', field2=5)
    </pre>



.. raw:: html

    <pre class="highlight" style="padding: 1em; box-sizing: border-box; font-size: 0.85em; line-height: 1.2em;">
    <strong style="opacity: 0.7; padding-bottom: 0.5em; display: inline-block"><span style="user-select: none">$ </span>python ./10_msgspec.py --field1 hello --field2 5</strong>
    Args(field1='hello', field2=5)
    </pre>