1

I am building a command-line program using the argparse module, and have been trying to design two separate, mutually exclusive groups of arguments that perform completely different tasks. I decided to use separate the two sets of arguments by creating subparsers, and I have tried to follow the formatting that is specified in the following link (https://pymotw.com/2/argparse/) as well as numerous stackoverflow threads, but whenever I try to run the script with one of the subparsers in the terminal, an attribute error is always yielded.

My code is set up in the following way (note: I have slightly condensed and simplified the following from my original code for the purpose of brevity):

import argparse

def check_input_file(filename):
    ###validates input file
    return validated_file

if __name__ == "__main__":
    parser = argparse.ArgumentParser(prog= "MyProg")
    parser.description= "This gives an overview of the two different workflows A and B, what they can do, and what arguments they require or can use."   

    A_or_B_subparsers = parser.add_subparsers(help="A processes a certain input to create a .csv spreadsheet, B takes an existing .csv spreadsheet and sends out a certain number to be printed")

    A_parser= A_or_B_subparsers.add_parser("A", help= "A needs the name of an existing input file to make the .csv spreadsheet")

    A_parser.add_argument("-input", required= True, type= check_input_file, help= "validates input file as being suitable for creating the .csv spreadsheet")

    B_parser = A_or_B_subparsers.add_parser("B", help="B will tell the computer to print a certain number of existing spreadsheets in a certain format")

    B_parser.add_argument("-num", type= int, default= 4, help= "number of times to do print existing .csv spreadsheet")

    B_parser.add_argument("-csv", help= "specify the existing .csv spreadsheet that must be formatted and then printed)

    args= MyProg.parse_args()

    if args.A:
        input= open(args.input, 'r')
        ###create .csv spreadsheet of input file in working directory

    if args.B:
        x_number= args.num
        file= args.csv
        ###format existing .csv spreadsheet
        ###print .csv spreadsheet file x_number of times 

Now, if I try to run this code in the terminal with, for example, the following commands, I get the following error:

$python MyProg_user_interface.py A -input someinputfilename.txt
AttributeError: 'Namespace' object has no attribute 'B'

How can I run my command line program so that only one subparser (and its required arguments) can run at a time?

UPDATE

After having found this source (https://allthingstechilike.blogspot.co.uk/2013/07/python-argparse-example-using-subparser.html), I decided to set dest= 'mode' in the line where A_or_B_subparsers = parser.add_subparsers(help="A processes a certain input blah blah blah blah") so that, depending on whether subcommand A or B was called in the command line, only the arguments required each subcommand would have to be typed into the command line.

I subsequently then modified my conditional tree after the line args= MyProg.parse_args() to look like this:

if args.mode == "A":
    input= open(args.input, 'r')
    ###create .csv spreadsheet of input file in working directory
elif args.mode== "B":
    x_number= args.num
    file= args.csv
    ###format existing .csv spreadsheet
    ###print .csv spreadsheet file x_number of times 
else:
    argparse.ArgumentError("too few arguments")

However, this modification does not seem to amend the problem. Although subcommand A can run fine, subcommand B refuses to run at all. Does anyone know if this is because of how my code is set up or because of another internal problem?

Bob McBobson
  • 743
  • 1
  • 9
  • 29

0 Answers0