Migrate all ServerArgs fields to Annotated style, reduce add_cli_args by ~2400 lines (#28919)

This commit is contained in:
Lianmin Zheng
2026-06-22 08:34:37 -07:00
committed by GitHub
parent 6b2c730bf7
commit b28e990161
4 changed files with 1856 additions and 2760 deletions
+23 -6
View File
@@ -70,6 +70,7 @@ class Arg:
required: Optional[bool] = None
action: Optional[Any] = None
action_kwargs: Optional[dict] = None
const: Optional[Any] = None
# When True, this field is skipped by add_cli_args_from_dataclass.
# Use for fields that have no CLI surface (e.g. injected via Python only).
no_cli: bool = False
@@ -185,12 +186,18 @@ def add_cli_args_from_dataclass(parser, cls, *, fields: Optional[List[str]] = No
cli_name = arg_meta.cli_name or _field_to_cli_name(field.name)
names = [cli_name] + (arg_meta.aliases or [])
default = _field_default(field)
# Anchor dest to the field name so argparse stores the value
# under the dataclass attribute directly, even when cli_name
# differs (e.g. --tensor-parallel-size → tp_size).
auto_dest = cli_name.lstrip("-").replace("-", "_")
dest_kwarg = {"dest": field.name} if field.name != auto_dest else {}
# Handle custom action
if arg_meta.action is not None:
kwargs = {
"action": arg_meta.action,
"help": arg_meta.help,
**dest_kwarg,
}
if default is not _MISSING:
kwargs["default"] = default
@@ -209,34 +216,42 @@ def add_cli_args_from_dataclass(parser, cls, *, fields: Optional[List[str]] = No
# Infer type from first literal value
val_type = type(literal_vals[0]) if literal_vals else str
type_func = arg_meta.type_parser or _infer_type_func(val_type)
kwargs = dict(type=type_func, choices=choices, help=arg_meta.help)
kwargs = dict(
type=type_func, choices=choices, help=arg_meta.help, **dest_kwarg
)
if default is not _MISSING:
kwargs["default"] = default
if arg_meta.const is not None:
kwargs["const"] = arg_meta.const
parser.add_argument(*names, **kwargs)
continue
# Check for List[X]
# Check for List[X] — but skip if type_parser is set (the parser
# handles the whole value as a single string, e.g. json_list_type).
origin = get_origin(inner_type)
if origin is list or origin is List:
if (origin is list or origin is List) and arg_meta.type_parser is None:
elem_args = get_args(inner_type)
elem_type = elem_args[0] if elem_args else str
type_func = arg_meta.type_parser or _infer_type_func(elem_type)
type_func = _infer_type_func(elem_type)
nargs = arg_meta.nargs or "+"
kwargs = dict(
type=type_func,
nargs=nargs,
help=arg_meta.help,
**dest_kwarg,
)
if arg_meta.choices:
kwargs["choices"] = arg_meta.choices
if default is not _MISSING:
kwargs["default"] = default
if arg_meta.const is not None:
kwargs["const"] = arg_meta.const
parser.add_argument(*names, **kwargs)
continue
# Bool → store_true
if inner_type is bool:
kwargs = dict(action="store_true", help=arg_meta.help)
kwargs = dict(action="store_true", help=arg_meta.help, **dest_kwarg)
if default is not _MISSING:
kwargs["default"] = default
parser.add_argument(*names, **kwargs)
@@ -244,13 +259,15 @@ def add_cli_args_from_dataclass(parser, cls, *, fields: Optional[List[str]] = No
# Scalar types (str, int, float, etc.)
type_func = arg_meta.type_parser or _infer_type_func(inner_type)
kwargs = dict(type=type_func, help=arg_meta.help)
kwargs = dict(type=type_func, help=arg_meta.help, **dest_kwarg)
if arg_meta.choices:
kwargs["choices"] = arg_meta.choices
if arg_meta.nargs:
kwargs["nargs"] = arg_meta.nargs
if default is not _MISSING:
kwargs["default"] = default
if arg_meta.const is not None:
kwargs["const"] = arg_meta.const
if (
arg_meta.required is True
or (arg_meta.required is None and default is _MISSING)
File diff suppressed because it is too large Load Diff