|
|
"""Pydantic models for argparse arguments and argument groups.""" |
|
|
|
|
|
from typing import ( |
|
|
Any, |
|
|
List, |
|
|
Literal, |
|
|
Optional, |
|
|
Tuple, |
|
|
) |
|
|
|
|
|
from pydantic import BaseModel, model_validator |
|
|
|
|
|
SEP = "__" |
|
|
|
|
|
|
|
|
class ArgparseArgumentModel(BaseModel): |
|
|
"""Pydantic model for an argparse argument.""" |
|
|
|
|
|
name: str |
|
|
type: Any |
|
|
dest: str |
|
|
default: Any |
|
|
required: bool |
|
|
action: Literal["store_true", "store"] |
|
|
help: Optional[str] |
|
|
nargs: Optional[Literal["+"]] |
|
|
choices: Optional[Tuple] |
|
|
|
|
|
@model_validator(mode="after") |
|
|
@classmethod |
|
|
def validate_action(cls, values: "ArgparseArgumentModel"): |
|
|
"""Validate the action based on the type.""" |
|
|
if values.type is bool and values.action != "store_true": |
|
|
raise ValueError('If type is bool, action must be "store_true"') |
|
|
return values |
|
|
|
|
|
@model_validator(mode="after") |
|
|
@classmethod |
|
|
def remove_props_on_store_true(cls, values: "ArgparseArgumentModel"): |
|
|
"""Remove type, nargs, and choices if action is store_true.""" |
|
|
if values.action == "store_true": |
|
|
values.type = None |
|
|
values.nargs = None |
|
|
values.choices = None |
|
|
return values |
|
|
|
|
|
|
|
|
def model_dump(self, **kwargs): |
|
|
"""Override the model_dump method to remove empty choices.""" |
|
|
res = super().model_dump(**kwargs) |
|
|
|
|
|
|
|
|
if "choices" in res and not res["choices"]: |
|
|
del res["choices"] |
|
|
|
|
|
return res |
|
|
|
|
|
|
|
|
class ArgparseArgumentGroupModel(BaseModel): |
|
|
"""Pydantic model for a custom argument group.""" |
|
|
|
|
|
name: str |
|
|
arguments: List[ArgparseArgumentModel] |
|
|
|