0

i'm trying to make a python program that has a complex argument parser . the program (let call it MyProg ) need to work as follow

1-MyProg wil take some files as input so i used a -f flage in the main parser (this is already a subparser so i can't use a subparser).

2-the program has 2 argument (-a and -s)that shoudent be present together and one of them is required so i used a mutualexclusion group.

3--a need to have a -k argument with it so i put the -k alone in a normal group inside the mutualexclusion group i made i the 2nd step and made it (-k) a required argument.

4-the problem is that the -s argument need either -k or another --e argument (not both) so i don't know where to put this -e argument so it can't be with -a or with -k .

the code :


description = "Prog"
# Initialize parser
parser = argparse.ArgumentParser(description=description,)

subparsers = parser.add_subparsers(required=True)

parser_MyProg = subparsers.add_parser('MyProg')


group_mut = parser_MyProg.add_mutually_exclusive_group()

group_k = group_mut.add_argument_group()


group_mut.add_argument('-a', type=int)
group_k.add_argument('-k', '--key', required=True, type=type=argparse.FileType('r'))

group_mut.add_argument('-s', type=int,)

group_mut.add_argument('-e',type=int)


parser_MyProg.add_argument( '-f', nargs='+', type=type=argparse.FileType('r'))

#some valid usecases (Should be valid)

args = parser.parse_args(
    'MyProg -a 8 -k k.txt  -f file1.txt file2.txt '.split())

args = parser.parse_args(
    'MyProg -s 8 -k k.txt  -f file1.txt file2.txt '.split())

args = parser.parse_args(
    'MyProg -s 8 -e 5  -f file1.txt file2.txt '.split())

#some invalid usecases (Should not be valid)

args = parser.parse_args('MyProg -a 8    -f file1.txt file2.txt '.split())   #need a -k

args = parser.parse_args('MyProg -s 8  -f file1.txt file2.txt '.split())    #need a -k or -e

args = parser.parse_args('MyProg -s 8 -e 5 -k k.txt  -f file1.txt file2.txt '.split())  # -k and -e can't be present together

in the code above i used -e in the mutual exclusion groupe but that doesent work because : 1- i can't use it with -s 2- i can use it with -k 3- the argument -k is required even with -s argument (with -s i want either -e or -k not both)

i simplified the code a little so you can see the problem . the program is an encryption and decryption and hashing program but i just wanted to make it clear that's why i did simplify it a little.

5
  • It would be nice if we could tell at a glance what is working and what isn't. Your end users might also like a simple fool proof usage as well. Instead it looks like I'll have to spend several minutes studying your code and description to figure out that out. Latter... Commented Apr 20, 2020 at 21:43
  • sorry but there is no error in the program excution , the problem is in the logic of the program so i think you need to read the description to know what i want to do. and thank ou for the fast comment anyway. Commented Apr 20, 2020 at 21:52
  • add_argument_group is used only for help formatting; it does not form a "any/and" group within the mutually_exclusive_group. argparse does not provide that kind of logic. Only the simple "xor" logic of an exclusive group. Commented Apr 20, 2020 at 23:46
  • Add a dest to the add_subparsers so it can format an error message. Commented Apr 20, 2020 at 23:47
  • argument_group and mutually_exclusive_group are not designed to be nested. Due to inheritance, the commands don't raise errors, but the nesting doesn't do anything useful. Here -k gets added to the MyProg subparser, but not to group_mut. Commented Apr 21, 2020 at 4:28

1 Answer 1

1

The usage from your code (after some syntax error corrections)

usage: stack61332378.py MyProg [-h] [-a A] -k KEY [-s S] [-e E] [-f F [F ...]]

Note that '-k' is required (no []).

If I remove 'group_k' and '-k'

usage: stack61332378.py MyProg [-h] [-a A | -s S | -e E] [-f F [F ...]]

'a/s/e' form the mutually exclusive group.

Off hand, this seems to be cleanest definition:

subparsers = parser.add_subparsers(dest='cmd', required=True)

parser_MyProg = subparsers.add_parser('MyProg')

group_mut = parser_MyProg.add_mutually_exclusive_group(required=True)
group_mut.add_argument('-a', type=int)
group_mut.add_argument('-s', type=int)

parser_MyProg.add_argument('-k', '--key', type=argparse.FileType('r'))
parser_MyProg.add_argument('-e',type=int)

parser_MyProg.add_argument( '-f', nargs='+', type=argparse.FileType('r'))

with the resulting help:

usage: stack61332378.py MyProg [-h] (-a A | -s S) [-k KEY] [-e E]
                               [-f F [F ...]]

optional arguments:
  -h, --help         show this help message and exit
  -a A
  -s S
  -k KEY, --key KEY
  -e E
  -f F [F ...]

You'll have to enforce any rules about k and e occurring with other arguments - after parsing. argparse only has the xor of the mutually exclusive group, and the subparser mechanism.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.