HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Argparse with subparsers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withsubparsersargparse

Problem

We have a main application made of a few separate parts - Unity and Clc.

I'm writing a new tool which will be used to manage them: deploy Unity, or run some checks and a lot of other stuff. As there will be a lot of options, I want split them in to separate namespaces.

Here is my implementation, it works, but I'm not sure if it's the best way.

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

parser_unity = subparsers.add_parser('unity', help='Unity help')
parser_unity.add_argument('-t', '--tagcheck', dest='unity_tagcheck', action='store_true', help='Check tags in .csproj files')
parser_unity.add_argument('-d', '--deploy', dest='unity_deploy', action='store_true', help='Deploy Unity project to appropriate URL')

parser_clc = subparsers.add_parser('clc', help='Clc help')
parser_clc.add_argument('-d', '--deploy', dest='clc_deploy', action='store_true', help='Deploy Cloudlibrary project to appropriate environment')

res = parser.parse_args()

print('All %s' % res)

try:
    if res.unity_deploy:
        print('Unity deploy')

    if res.unity_tagcheck:
        print('Unity tagcheck')
except AttributeError:
    pass

try:
    if res.clc_deploy:
        print('Clc deploy')
except AttributeError:
    pass


And here is how is works:

d:\RDS\rdsmanager>tmp\test.py clc -d
All Namespace(clc_deploy=True)
Clc deploy

d:\RDS\rdsmanager>tmp\test.py unity -d -t
All Namespace(unity_deploy=True, unity_tagcheck=True)
Unity deploy
Unity tagcheck

d:\RDS\rdsmanager>tmp\test.py unity -d
All Namespace(unity_deploy=True, unity_tagcheck=False)
Unity deploy

Solution

If you take a look at the argparse documentation, they suggest to use
set_defaults on each of the parsers to associate a processing function
depending on which parser is selected. So if you do that then you can
get rid of the try/except blocks, which would improve things quite a
lot.

E.g.:

def handler_unity(res):
    if res.unity_deploy:
        print('Unity deploy')

    if res.unity_tagcheck:
        print('Unity tagcheck')

def handler_clc(res):
    if res.clc_deploy:
        print('Clc deploy')
...
parser_unity.set_defaults(func=handler_unity)
...
parser_clc.set_defaults(func=handler_clc)
...
res.func(res)

Code Snippets

def handler_unity(res):
    if res.unity_deploy:
        print('Unity deploy')

    if res.unity_tagcheck:
        print('Unity tagcheck')

def handler_clc(res):
    if res.clc_deploy:
        print('Clc deploy')
...
parser_unity.set_defaults(func=handler_unity)
...
parser_clc.set_defaults(func=handler_clc)
...
res.func(res)

Context

StackExchange Code Review Q#93301, answer score: 7

Revisions (0)

No revisions yet.