Search code examples
pythonargumentsargparse

Python ArgParse works even though script is called with argument with similar name


I have the following code:

import argparse

# Create the parser
parser = argparse.ArgumentParser("ArgParse intro")
# Add an argument

mand_arg_group = parser.add_argument_group("Mandatory arguments")
mand_arg_group.add_argument('--name', type = str, required = True, help = "This is the name of the person we are processing")

# Add more arguments
# If required is missing it is considered to be False
opt_arg_group = parser.add_argument_group("Optional arguments")
opt_arg_group.add_argument('--age', type = int,  help = "This is the age of the person we are processing")
# nargs specifies how many arguments to expect. If we don't know how many values the user will input we can use nargs='+'
opt_arg_group.add_argument('--tasks', type = int,  help = "These are the IDs of the tasks this person has completed ", nargs = '+')

# Mutually exclusive arguments
mut_ex_group = parser.add_mutually_exclusive_group()
mut_ex_group.add_argument('--day', type = str, help = "Day shift")
mut_ex_group.add_argument('--night', type = str, help = "Night shift")

# Parse the arguments
args = parser.parse_args()

if args.day:
    shift = args.day
else:
    shift = args.night
    
output_string = f"{args.name} has {args.age} years and completed tasks with the following IDs: {args.tasks}. {args.name} is working the {shift} shift"
print(output_string)

I have called the same script in two different ways and it still works:

  1. First way: python argparse_intro.py --name NAME1 --tasks 90 90 90
  2. Second way: python argparse_intro.py --name NAME1 --task 90 90 90

It seems that it doesn't matter if I spell task or tasks, the argument parser will recognize the value and variable and it prints out the correct message without throwing an error


Solution

  • parse_args accepts any unique prefix of a long option name:

    The parse_args() method by default allows long options to be abbreviated to a prefix, if the abbreviation is unambiguous (the prefix matches a unique option):

    If you had defined a second option like --taskserver, then --task would raise an error, because parse_args couldn't tell if you meant --tasks --taskserver. (--tasks itself would be unambiguous as the full name of an option, rather than an abbreviation of --taskserver.)