brentyi / tyro

CLI interfaces & config objects, from types
https://brentyi.github.io/tyro
MIT License
467 stars 23 forks source link

Optional string argument with None default does not work with argument alias #156

Closed KolinGuo closed 2 weeks ago

KolinGuo commented 2 weeks ago

It seemed like Optional[str] argument with None as its default value breaks the specified argument alias. See the minimal example below where the --vid alias for vendor_id fails to be recognized while the --pid alias for product-id works.

from typing import Annotated, Optional

import tyro

def detect_usb_device(
    vendor_id: Annotated[Optional[str], tyro.conf.arg(aliases=["--vid"])] = None,
    product_id: Annotated[Optional[str], tyro.conf.arg(aliases=["--pid"])] = "",
) -> None:
    """
    Detect connected USB device by vendor_id + product_id.

    :param vendor_id: vendor_id of a specific USB device.
    :param product_id: product_id of a specific USB device.
    """
    print(f"{vendor_id=} {product_id=}")

if __name__ == "__main__":
    tyro.cli(detect_usb_device)
root@machine:/scripts# python3 test.py -h
usage: test.py [-h] [--vendor-id {None}|{None}|STR] [--product-id {None}|STR]

Detect connected USB device by vendor_id + product_id.

╭─ options ─────────────────────────────────────────────────────────────╮
│ -h, --help        show this help message and exit                     │
│ --vendor-id {None}|{None}|STR                                         │
│                   vendor_id of a specific USB device. (default: None) │
│ --product-id {None}|STR, --pid {None}|STR                             │
│                   product_id of a specific USB device. (default: '')  │
╰───────────────────────────────────────────────────────────────────────╯
root@machine:/scripts# python3 test.py --vid 1234
╭─ Unrecognized options ────────────────╮
│ Unrecognized options: --vid           │
│ ───────────────────────────────────── │
│ For full helptext, run test.py --help │
╰───────────────────────────────────────╯
brentyi commented 2 weeks ago

Hi @KolinGuo, thanks for the issue report!

I did some digging and it seems like this is because of a bug in Python<=3.10: https://github.com/python/cpython/issues/90353 https://github.com/python/typing_extensions/issues/310 https://github.com/python/typing_extensions/pull/312

It's not ideal but I added a workaround in #157, as well as test cases based on the snippet you provided. This will be fixed in the next release.

brentyi commented 2 weeks ago

This should be fixed in tyro>=0.8.9!

KolinGuo commented 2 weeks ago

Thank you @brentyi for fixing it so promptly! I've verified that it's working now.