How do I suppress an argument when nothing is input on command line?

Question:

#!/usr/bin/env python3

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--selection', '-s')
parser.add_argument('--choice', '-c', default = argparse.SUPPRESS)
args = parser.parse_args()

def main(selection, choice):
    print(selection)
    print(choice)

if __name__=='__main__':
    main(args.selection, args.choice)

The example provided is just to provide something simple and short that accurately articulates the actual problem I am facing in my project. My goal is to be able to ignore an argument within the code body when it is NOT typed into the terminal. I would like to be able to do this through passing the argument as a parameter for a function. I based my code off of searching ‘suppress’ in the following link: https://docs.python.org/3/library/argparse.html

When I run the code as is with the terminal input looking like so: python3 stackquestion.py -s cheese, I receive the following error on the line where the function is called:

AttributeError: 'Namespace' object has no attribute 'choice'

I’ve tried adding the following parameter into parser like so:

parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)

I’ve also tried the above with

parser.add_argument('--choice', '-c')

But I get the same issue on the same line.

@Barmar answered this question in the comments. Using ‘default = None’ in parser.add_argument works fine; The code runs without any errors. I selected the anser from @BorrajaX because it’s a simple solution to my problem.

Asked By: dvines

||

Answers:

According to the docs:

Providing default=argparse.SUPPRESS causes no attribute to be added if the command-line argument was not present:

But you’re still assuming it will be there by using it in the call to main:

main(args.selection, args.choice)

A suppressed argument won’t be there (i.e. there won’t be an args.choice in the arguments) unless the caller specifically called your script adding --choice="something". If this doesn’t happen, args.choice doesn’t exist.

If you really want to use SUPPRESS, you’re going to have to check whether the argument is in the args Namespace by doing if 'choice' in args: and operate accordingly.

Another option (probably more common) can be using a specific… thing (normally the value None, which is what argparse uses by default, anyway) to be used as a default, and if args.choice is None, then assume it hasn’t been provided by the user.

Maybe you could look at this the other way around: You want to ensure selection is provided and leave choice as optional?

You can try to set up the arguments like this:

parser = argparse.ArgumentParser()
parser.add_argument('--selection', '-s', required=True)
parser.add_argument('--choice', '-c')
args = parser.parse_args()

if __name__ == '__main__':
    if args.choice is None:
        print("No choice provided")
    else:
        print(f"Oh, the user provided choice and it's: {args.choice}")

    print(f"And selection HAS TO BE THERE, right? {args.selection}")
Answered By: BorrajaX
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.