Lukasz Korbasiewicz
Lukasz Korbasiewicz

Reputation: 159

Argparse and mutually exclusive command line arguments

I have created a pastebin terminal client in python. It can take some command line arguments, like -o to open a file, -n to set a paste name etc. It also has option -l which lists the pastes and allows you to delete or view pastes. The problem is that I don't know how to do it in a nice way (using argparse) - it should not allow to use -l with any other options.

I added a simple logic:

if args.name:
    if args.list:
        print('The -l should be used alone. Check "pb -h" for help.')
    sys.exit()

Can it be done using just argparse? I know about mutually exclusive groups, I even have one (to set paste privacy) but I haven't figured this one yet.

Full code is available here: https://github.com/lkorba/pbstc/blob/master/pb

Upvotes: 0

Views: 945

Answers (1)

Eypros
Eypros

Reputation: 5723

I don't think you can use argparse to achieve your goal in "a nice way" as you say.

I see 2 options here:

1) The simpler solution as I get it would be to just check your arguments after parsing them. Nothing fancy just:

args = parser.parse_args()
if args.list is not None:
    if not (args.name is None and args.open is None and
            args.public is None and args.format is None and args.exp is None):
        parser.error('Cannot use list with name, open, public, format or exp argument')

2) On the other hand you could revise a bit your program and use subparsers like:

subparsers = parser.add_subparsers(title="commands", dest="command")

parser_a = subparsers.add_parser('list', help='list help')

parser_b = subparsers.add_parser('action', help='Any action here')
parser_b.add_argument('-f', action="store", help='Choose paste format/syntax: text=None, '
                                                            'mysql=MYSQL, perl=Perl, python=Python etc...')
parser_b.add_argument('-n', '--name', action="store")
parser_b.add_argument('-o', '--open', action="store", help='Open file')
...

args = parser.parse_args()
if args.command == 'list':
    ...
elif args.command == 'action':
    ...

So, for example if you pass list -n='Name' as arguments in the latter case you will get an error:

usage: subparser_example.py [-h] {list,action} ...
subparser_example.py: error: unrecognized arguments: -n='Name'

Of course you also get (as overhead) one extra parameter action here...

Upvotes: 1

Related Questions