What’s supported

For minimum-boilerplate CLIs, tyro aims to maximize support of Python’s standard typing features.

Inputs can be annotated with:

Types can also be placed and nested in various structures, such as:

What’s not supported

There are some limitations. We currently do not fully support:

  • Self-referential types. For example, type RecursiveList[T] = T | list[RecursiveList[T]].

  • Variable-length sequences over nested structures, unless a default is provided. For types like list[Dataclass], we require a default value to infer length from. The length of the corresponding field cannot be changed from the CLI interface.

  • Type parameters in class and static methods. For example:

    class MyClass[T: int | str]:
      @staticmethod
      def method1(arg: T) -> T:
        return arg
    
      @classmethod
      def method2(cls, arg: T) -> T:
        return arg
    
    # The `int` type parameter will be ignored.
    tyro.cli(MyClass[int].method1)
    tyro.cli(MyClass[int].method2)
    

    This is because MyClass[int].method1 / MyClass[int].method2 cannot be distinguished from MyClass.method1 / MyClass.method2 at runtime.

For some of these cases, a custom constructor can be defined as a workaround.