Skip to content

Printing default values as well as help from the command line  #65

Open
@akinwilson

Description

@akinwilson

I am trying to use the ArgumentDefaultsHelpFormatter class from the original argparse library to enhance the displayed help information when using the ArgumentParser class from the argparse_dataclass library. Suppose I run the following script.py with the help - -h - flag

from dataclasses import dataclass, field 
from argparse_dataclass import ArgumentParser
from argparse import ArgumentDefaultsHelpFormatter

@dataclass
class Args:
    val_a : int = field(default=30522, metadata={'help':'info about val_a'})
    val_b :int = field(default=768, metadata={'help':'info about val_b'})
    val_c : str = field(default='foo', metadata={'help':'info about val_c'})
    

if __name__ == "__main__":
    parser =ArgumentParser(Args,formatter_class=ArgumentDefaultsHelpFormatter)
    args = parser.parse_args()

I would expect the terminal output to be like:

usage: script.py [-h] [--val-a VAL_A ] [--val-b VAL_B] [--val-c VAL_C]

options:
  -h, --help            show this help message and exit
  --val-a VAL_A
                        info about val_a (default:30522)
  --val-b VAL_B 
                        info about val_b (default: 768)
  --val-c VAL_C 
                        info about val_c (default: foo)

but its actually like:

usage: script.py [-h] [--val-a VAL_A ] [--val-b VAL_B] [--val-c VAL_C]

options:
  -h, --help            show this help message and exit
  --val-a VAL_A
                        info about val_a (default: <dataclasses._MISSING_TYPE object at 0x711c99aeed70>)
  --val-b VAL_B 
                        info about val_b (default: <dataclasses._MISSING_TYPE object at 0x711c99aeed70>)
  --val-c VAL_C 
                        info about val_c (default: <dataclasses._MISSING_TYPE object at 0x711c99aeed70>)

Does anyone know how to rectify this behavior?

EDIT
As I am seeking help from multiple places on the subject, the other being a stack overflow post, it was pointed out that this behavior is due to these lines in the source code

could potentially editing these lines in the source code from

def _add_dataclass_options(
    options_class: Type[OptionsType], parser: argparse.ArgumentParser
) -> None:
    if not is_dataclass(options_class):
        raise TypeError("cls must be a dataclass")

    for field in fields(options_class):
        args = field.metadata.get("args", [f"--{_get_arg_name(field)}"])
        positional = not args[0].startswith("-")
        kwargs = {
            "type": field.metadata.get("type", field.type),
            "help": field.metadata.get("help", None),
        }

to

def _add_dataclass_options(
    options_class: Type[OptionsType], parser: argparse.ArgumentParser
) -> None:
    if not is_dataclass(options_class):
        raise TypeError("cls must be a dataclass")

    for field in fields(options_class):
        args = field.metadata.get("args", [f"--{_get_arg_name(field)}"])
        positional = not args[0].startswith("-")
        kwargs = {
            "type": field.metadata.get("type", field.type),
            "help": field.metadata.get("help", None),
            "default": field.default,
        }

stop this behavior from happening?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions