1111from typing import Annotated , Optional , Sequence , Type , Union
1212from unittest .mock import patch
1313
14- from .cli_flags import CliFlags
1514
1615from ..cli import Command
1716from ..settings import CliSettings
3332from .form_dict import EnvClass , TagDict , dataclass_to_tagdict , MissingTagValue , dict_added_main
3433
3534try :
35+ from .cli_flags import CliFlags
3636 from tyro import cli
37- from tyro ._argparse import _SubParsersAction , ArgumentParser
38- from tyro ._argparse_formatter import TyroArgumentParser
39- from tyro ._singleton import MISSING_NONPROP
37+
38+ try : # tyro >= 0.10
39+ from tyro import _experimental_options
40+
41+ _experimental_options ["backend" ] = "argparse"
42+ from tyro ._backends ._argparse import _SubParsersAction , ArgumentParser
43+ from tyro ._backends ._argparse_formatter import TyroArgumentParser
44+ except ImportError :
45+ from tyro ._argparse import _SubParsersAction , ArgumentParser
46+ from tyro ._argparse_formatter import TyroArgumentParser
47+ from tyro ._parsers import ParserSpecification
48+
4049 from tyro .conf import OmitArgPrefixes , OmitSubcommandPrefixes , DisallowNone , FlagCreatePairsOff
4150
4251 from .tyro_patches import (
4554 custom_init ,
4655 custom_parse_known_args ,
4756 failed_fields ,
48- patched_parse_known_args ,
57+ patched__parse_known_args ,
58+ patched__format_help ,
4959 subparser_call ,
5060 argparse_init ,
5161 )
@@ -183,6 +193,7 @@ def annot(type_form):
183193 helponly = False
184194 try :
185195 # Why redirect_stdout? Help-text shows the defaults, which also uses the subcommanded-config.
196+ # TODO maybe new tyro 0.10 will not output to stdout, get rid of the buffer
186197 with redirect_stdout (buffer ):
187198 try :
188199 # Standard way.
@@ -234,16 +245,16 @@ def annot(type_form):
234245 kwargs , None if helponly else m , args , type_form , env_classes , _custom_registry , annot , _req_fields
235246 )
236247
237- # Why setting m.env instead of putting into into a constructor of a new get_interface() call?
238- # 1. Getting the interface is a costly operation
239- # 2. There is this bug so that we need to use single interface:
240- # TODO
241- # As this works badly, lets make sure we use single interface now
242- # and will not need the second one.
243- # get_interface("gui")
244- # m = get_interface("gui")
245- # m.select([1,2,3])
246- m .env = env
248+ # Why setting m.env instead of putting into into a constructor of a new get_interface() call?
249+ # 1. Getting the interface is a costly operation
250+ # 2. There is this bug so that we need to use single interface:
251+ # TODO
252+ # As this works badly, lets make sure we use single interface now
253+ # and will not need the second one.
254+ # get_interface("gui")
255+ # m = get_interface("gui")
256+ # m.select([1,2,3])
257+ m .env = env
247258 except SystemExit as exception :
248259 # --- (C) The dialog missing section ---
249260 # Some fields are needed to be filled up.
@@ -339,8 +350,7 @@ def _apply_patches(cf: Optional[CliFlags], ask_for_missing, env_classes, kwargs)
339350 patches = []
340351
341352 patches .append (patch .object (_SubParsersAction , "__call__" , subparser_call ))
342- patches .append (patch .object (TyroArgumentParser , "_parse_known_args" , patched_parse_known_args ))
343-
353+ patches .append (patch .object (TyroArgumentParser , "_parse_known_args" , patched__parse_known_args ))
344354 kw = {
345355 k : v for k , v in kwargs .items () if k != "default"
346356 } # NOTE I might separate kwargs['default'] and do not do this filtering
@@ -359,6 +369,11 @@ def _apply_patches(cf: Optional[CliFlags], ask_for_missing, env_classes, kwargs)
359369 "__init__" ,
360370 custom_init (cf ),
361371 ),
372+ patch .object (
373+ TyroArgumentParser ,
374+ "format_help" ,
375+ patched__format_help (cf ),
376+ ),
362377 patch .object (
363378 TyroArgumentParser ,
364379 "parse_known_args" ,
@@ -486,7 +501,12 @@ def _fetch_currently_failed(requireds) -> TagDict:
486501 missing_req = {}
487502 for field in failed_fields .get ():
488503 # ex: `_subcommands._nested_subcommands (positional)`
489- fname = field .dest .replace (" (positional)" , "" ).replace ("-" , "_" ) # `_subcommands._nested_subcommands`
504+ fname = (
505+ field .dest .replace (" (positional)" , "" )
506+ .replace ("-" , "_" )
507+ .replace ("__tyro_dummy_inner__." , "" )
508+ .replace ("__tyro_dummy_inner__" , "" )
509+ ) # `_subcommands._nested_subcommands`
490510 fname_raw = fname .rsplit ("." , 1 )[- 1 ] # `_nested_subcommands`
491511
492512 if isinstance (field , _SubParsersAction ):
0 commit comments