lebrice / SimpleParsing

Simple, Elegant, Typed Argument Parsing with argparse
MIT License
427 stars 52 forks source link

disable help for some arguments #98

Closed yuvval closed 2 years ago

yuvval commented 2 years ago

Is your feature request related to a problem? Please describe. Many times I wouldn't like to expose all the dataclass arguments in the help, but I'd still want to have them documented in the source code. Would it be possible to disable help for those arguments? maybe by a prefix like #nohelp in their comment

Describe the solution you'd like If an argument comment starts with #nohelp then this argument would not be exposed in the help

Describe alternatives you've considered Define those arguments in __post_init__()

lebrice commented 2 years ago

Hey there @yuvval , thanks for posting!

Hmm interesting idea. I have a few questions though:

  1. Have you checked out the docstrings example, out of curiosity? Perhaps what you want is to have a bit more control on which of the comments in the code shows up in the "--help" string, correct?
  2. Do you want the argument to not have a "help" value, or do you want them to be usable, but to not show up at all in the "--help" text?

    • In the latter case, I'm not sure if that's doable with plain argparse. If it's achievable with argparse though, then it will be very easy to add to simple-parsing. If it isn't, then that's not possible for me to add.

    • In case you don't want the argument to have a "--help" value, then you can use field from simple_parsing.helpers and pass a whitespace string value for "help", like so:

      
      from dataclasses import dataclass
      from simple_parsing import ArgumentParser
      from simple_parsing.helpers import field

@dataclass class Options: """ Some options. """

don't want this comment to show up in the "--help" text.

foo: int = field(default=123, help=" ")  # don't want this comment to show up either.
""" Also don't want this docstring to show up in the help string """

if name == "main": parser = ArgumentParser() parser.add_arguments(Options, dest="options") args = parser.parse_args() options = args.options print(options)

Running this from the command-line produces the following:
```console
$ python issue_98.py --help
usage: no_help.py [-h] [--foo int]

optional arguments:
  -h, --help  show this help message and exit

Options ['options']:
   Some options. 

  --foo int   (default: 123)

Notice how the --foo option still shows up, but none of the comments are used as part of the "--help" string.

Hope this helps, let me know if this doesn't address your issue.

lebrice commented 2 years ago

Oh @yuvval , Just realised, since you mentioned __post_init__:

If you're trying to just not parse a value from the command-line, for instance if you want to set the attribute value in __post_init__, then you should use the cmd=False option of field. That tells simple_parsing to not generate any command-line args for that field. Note that you need to provide a default value or a default factory for those fields.

from dataclasses import dataclass

from simple_parsing import ArgumentParser
from simple_parsing.helpers import field

@dataclass
class Options:
    """ Some options. """
    # Some attribute that we want to parse from the command-line. 
    foo: int = 123

    # Another attribute that we *dont* want to parse from the command-line.
    bar: float = field(default=1.23, cmd=False)

    def __post_init__(self):
        self.bar = self.foo * 4.56

if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_arguments(Options, dest="options")
    args = parser.parse_args()
    options = args.options
    print(options)
yuvval commented 2 years ago

Thank you!

cmd=False was exactly what I was looking for.

Your first response guided me to find another alternative for doing this, by setting help=argparse.SUPPRESS.