swansonk14 / typed-argument-parser

Typed argument parser for Python
MIT License
505 stars 40 forks source link

What is the right way to call `set_defaults` #109

Open aucampia opened 1 year ago

aucampia commented 1 year ago

The documentation for argparse [ref] suggests using set_defaults for handling subcommands, but I'm not sure what is the right way to call set_defaults with TAP, it would be great if you can add some examples or documentation for this.

aucampia commented 1 year ago

The alternative is to use dest from add_subparsers, but if I use this and also add a type hint for the dest then Tap thinks it should add an argument for it.

So if I do this for example:

class MainParser(Tap):
  subparser_flag: str

  ...

  def configure(self):
    ...
    self.add_subparsers(required=True, dest="subparser_flag")
    ...

And run, then I get error: the following arguments are required: --subparser_flag - it would be very helpful if there is some example of how subparser support is supposed to work given both the normal ways of using it with ArgumentParser is broken.

aucampia commented 1 year ago

I also tried with _subparser_flag as follow:

class MainParser(Tap):
  _subparser_flag: str

  ...

  def configure(self):
    ...
    self.add_subparsers(required=True, dest="_subparser_flag")
    ...

But get the same error.

It seems there is some code that attempts to ignore class variables starting with _:

https://github.com/swansonk14/typed-argument-parser/blob/eb55a9bf91b4675a0d8588b2a8f4947e48426336/tap/tap.py#L509-L522

But this does not seem to be working as intended, because these still show up in _get_annotations.

Is this another bug? If so I will raise an issue for it.

aucampia commented 1 year ago

As a workaround I have done this:


class MainParser(Tap):

    subparser_flag: str

    def configure(self):
        self.add_argument(
            # Hack to work around problems with Tap, without this Tap complains
            # that `subparser_flag` is not set even if a subcommand is supplied,
            # for more info see
            # <https://github.com/swansonk14/typed-argument-parser/issues/109>.
            "--subparser_flag",
            action="store",
            # dest="subparser_flag",
            help=argparse.SUPPRESS,
            required=False,
        )
        self.add_subparsers(required=True, dest="subparser_flag", help="sub-command")
martinjm97 commented 11 months ago

Hi @aucampia,

Unfortunately, we couldn't quite follow this issue. We realize that there's some concern with our current treatment of subparsers. Would you be able to clarify with some example code and then a description of the desired behavior versus the existing behavior?

Thanks, JK