0

I have a function to conduct the argument parsing for my program, let's say I have

def parse_program_args():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--A",
        type='str'
        )
    parser.add_argument(
        "--B",
        type='str'
        )
    parser.add_argument(
        "--C",
        type=int
        )

...
...

A can have one of a few options as well as B and C (each of them has another set of optional values). I'm trying to manage restriction on the user choices and mutual exclude some values for those arguments. For example, I want to ban the following combinations of arguments:

  • --A apple" and "--B red
  • --B red --C 1

The problem is that I don't want to impose an order restriction on the user, so I can't rely on the argument order. I'm looking for a pythonic way to do so.

danwgh
  • 79
  • 6
  • 2
    FWIW, `type` must be a callable like `int`, not an a string like `'int'`… Also, `str` as a type is the default and can be omitted. – deceze Feb 09 '23 at 10:21
  • 3
    `argparse` can do a lot, but it can't do everything. In this case, it seems the best way is just to add a check after parsing all the arguments. – Thomas Feb 09 '23 at 10:21
  • 1
    Have you tried a library like click or Typer CLI? I've always used an external library, not the builtin argparse module – Tom McLean Feb 09 '23 at 10:30
  • This question may belong to [codereview.se]. – Dorian Turba Feb 09 '23 at 10:55
  • 1
    Have you seen this https://docs.python.org/3/library/argparse.html#mutual-exclusion ? – Anentropic Feb 09 '23 at 11:14
  • Or if you need to do your own validation then see the answers here about raising errors https://stackoverflow.com/questions/8107713/using-argparse-argumenterror-in-python – Anentropic Feb 09 '23 at 11:15
  • 2
    @DorianTurba, this does not fit the CR requirements. CR is for improving working code, especially in organization and style. It's not a how-to forum – hpaulj Feb 09 '23 at 17:23
  • 1
    This looks like a straight forward post parsing error checking. You can raise your own errors, or use `parser.error` to get a `usage` message along with the error message. Sometimes cross argument error checking can be implemented in custom `action` classes, but that's hard to do in an order-independent manner. Post parsing testing is nearly always easier. Another thing to think about - how do you tell your users about these constraints? – hpaulj Feb 09 '23 at 17:27
  • @hpaulj The OP wants to manage mutual exclusion for flags' values. He can do that in a naive way, but wants a more pythonic way to do that. Yes, for CR, you need a working example so he can't copy paste the question without adding some information. But currently, it doesn't fit SO either. – Dorian Turba Feb 09 '23 at 17:29
  • @DorianTurba, "pythonic" is a fuzzy term. I suspect that if the OP posted this on CR with working naive testing, they'd quibble with style details that don't conform to PEP8 (or whatever is the preferred style standard these days). https://codereview.stackexchange.com/questions/273571/creating-an-argument-parser-using-argparse-with-groups-and-arguments-are-defi is the only "recent" CR question about adding to `argparse`, and the answer focused on OOP style issues. There's no `[argparse]` tag. – hpaulj Feb 11 '23 at 17:02
  • 1
    @DorianTurba Just because a question doesn't fit on Stack Overflow doesn't mean it fits on Code Review. As you observed the code needs to be working. Any ellipses in the code make the question off-topic on Code Review due to Missing Review Context, the statement `Let's say I have ...` also makes the question off-topic on Code Review for the same reason since it is hypothetical. Here are some CR guidelines https://codereview.meta.stackexchange.com/questions/5777/a-guide-to-code-review-for-stack-overflow-users/5778#5778 and https://codereview.stackexchange.com/help/how-to-ask – pacmaninbw Feb 11 '23 at 17:34
  • I know > Yes, for CR, you need a working example so he can't copy paste the question without adding some information. But currently, it doesn't fit SO either. – Dorian Turba Feb 12 '23 at 07:05
  • Thank you all for your comments, im not sure if it's worth to create a full working example for CR since the code i presented is a very simplified version of a huge code base which employs multiple packages. The aim of my question was to get either an `argparse` facilty/tweak that im not aware of or to get a more structural solution. – danwgh Feb 13 '23 at 13:39
  • "structural solution" like like having a helper class that will hold the current state and will have some methods for each purpose, so i could create an object of that class along with the parser object and "somehow" send those methods as arguments to `action` / `type`. im not sure how to do it (I mean, all i know is to use a class for every action and then define a `__cal__` for each class, but this will require a lot of classes, and worst, I'll not be able to hold the whole state in one object), If some someone have the the knowledge how to work it, i'd be grateful for him to post here – danwgh Feb 13 '23 at 13:41

0 Answers0