Skip to content

Commit a809c1e

Browse files
authored
Restore helptext behavior for erased argument names (#253)
1 parent 971c839 commit a809c1e

6 files changed

+107
-5
lines changed

src/tyro/_parsers.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,19 @@ def format_group_name(group_name: str) -> str:
264264
if arg.is_suppressed():
265265
continue
266266

267-
group_name = arg.extern_prefix
267+
group_name = (
268+
arg.extern_prefix
269+
if arg.field.argconf.name != ""
270+
# If the field name is "erased", we'll place the argument in
271+
# the parent's group.
272+
#
273+
# This is to avoid "issue 1" in:
274+
# https://github.com/brentyi/tyro/issues/183
275+
#
276+
# Setting `tyro.conf.arg(name="")` should generally be
277+
# discouraged, so this will rarely matter.
278+
else arg.extern_prefix.rpartition(".")[0]
279+
)
268280
if group_name not in group_from_group_name:
269281
description = (
270282
parent.helptext_from_intern_prefixed_field_name.get(

tests/test_conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ class TrainConfig:
11171117
ModelConfig(num_slots=3)
11181118
)
11191119

1120-
# groups are still printed in the help text
1120+
# Groups are still printed in the helptext.
11211121
help_text = get_helptext_with_checks(annot)
11221122
assert "model options" in help_text
11231123
assert "--num-slots" in help_text

tests/test_helptext.py

+17
Original file line numberDiff line numberDiff line change
@@ -959,3 +959,20 @@ class Special(TypedDict):
959959

960960
help = get_helptext_with_checks(Special)
961961
assert "unset by default" in help, help
962+
963+
964+
def test_conf_erased_argname() -> None:
965+
@dataclasses.dataclass(frozen=True)
966+
class Verbose:
967+
is_verbose: bool = True
968+
969+
@dataclasses.dataclass(frozen=True)
970+
class Args:
971+
verbose: Annotated[Verbose, tyro.conf.arg(name="")]
972+
973+
def main(args: Args) -> None:
974+
print(args)
975+
976+
helptext = get_helptext_with_checks(main)
977+
assert "args options" in helptext
978+
assert "args.verbose options" not in helptext

tests/test_py311_generated/test_boolean_optional_generated.py

+50
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import dataclasses
22

3+
import pytest
34
from helptext_utils import get_helptext_with_checks
45

56
import tyro
@@ -83,3 +84,52 @@ class A:
8384
assert "(default: True)" in get_helptext_with_checks(A)
8485
assert "(default: False)" not in get_helptext_with_checks(A)
8586
assert "(default: None)" not in get_helptext_with_checks(A)
87+
88+
89+
def test_flag_no_pairs() -> None:
90+
"""Test for tyro.conf.FlagPairOff."""
91+
92+
@dataclasses.dataclass
93+
class A:
94+
x: tyro.conf.FlagCreatePairsOff[bool]
95+
y: tyro.conf.FlagCreatePairsOff[bool] = False
96+
z: tyro.conf.FlagCreatePairsOff[bool] = True
97+
98+
assert tyro.cli(
99+
A,
100+
args=["--x", "True"],
101+
) == A(True)
102+
assert tyro.cli(
103+
A,
104+
args=["--x", "True", "--y"],
105+
) == A(True, True)
106+
assert tyro.cli(
107+
A,
108+
args=["--x", "True", "--y", "--no-z"],
109+
) == A(True, True, False)
110+
111+
with pytest.raises(SystemExit):
112+
tyro.cli(
113+
A,
114+
args=["--x", "True", "--y", "True"],
115+
)
116+
with pytest.raises(SystemExit):
117+
tyro.cli(
118+
A,
119+
args=["--x", "True", "--no-y"],
120+
)
121+
with pytest.raises(SystemExit):
122+
tyro.cli(
123+
A,
124+
args=["--x", "True", "--z"],
125+
)
126+
with pytest.raises(SystemExit):
127+
tyro.cli(
128+
A,
129+
args=["--x"],
130+
)
131+
with pytest.raises(SystemExit):
132+
tyro.cli(
133+
A,
134+
args=["--no-x"],
135+
)

tests/test_py311_generated/test_conf_generated.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -1121,9 +1121,15 @@ class TrainConfig:
11211121
args="--model.num-slots 3".split(" "),
11221122
) == TrainConfig(ModelConfig(num_slots=3))
11231123

1124-
assert tyro.cli(
1125-
tyro.conf.OmitArgPrefixes[TrainConfig], args="--num-slots 3".split(" ")
1126-
) == TrainConfig(ModelConfig(num_slots=3))
1124+
annot = tyro.conf.OmitArgPrefixes[TrainConfig]
1125+
assert tyro.cli(annot, args="--num-slots 3".split(" ")) == TrainConfig(
1126+
ModelConfig(num_slots=3)
1127+
)
1128+
1129+
# Groups are still printed in the helptext.
1130+
help_text = get_helptext_with_checks(annot)
1131+
assert "model options" in help_text
1132+
assert "--num-slots" in help_text
11271133

11281134

11291135
def test_custom_constructor_0() -> None:

tests/test_py311_generated/test_helptext_generated.py

+17
Original file line numberDiff line numberDiff line change
@@ -960,3 +960,20 @@ class Special(TypedDict):
960960

961961
help = get_helptext_with_checks(Special)
962962
assert "unset by default" in help, help
963+
964+
965+
def test_conf_erased_argname() -> None:
966+
@dataclasses.dataclass(frozen=True)
967+
class Verbose:
968+
is_verbose: bool = True
969+
970+
@dataclasses.dataclass(frozen=True)
971+
class Args:
972+
verbose: Annotated[Verbose, tyro.conf.arg(name="")]
973+
974+
def main(args: Args) -> None:
975+
print(args)
976+
977+
helptext = get_helptext_with_checks(main)
978+
assert "args options" in helptext
979+
assert "args.verbose options" not in helptext

0 commit comments

Comments
 (0)