gen_Eric
gen_Eric

Reputation: 227200

Variable length arguments

I am creating a python program using the argparse module and I want to allow the program to take either one argument or 2 arguments.

What do I mean? Well, I am creating a program to download/decode MMS messages and I want the user to either be able to provide a phone number and MMS-Transaction-ID to download the data or provide a file from their system of already downloaded MMS data.

What I want is something like this, where you can either enter in 2 arguments, or 1 argument:

./mms.py (phone mmsid | file)

NOTE: phone would be a phone number (like 15555555555), mmsid a string (MMS-Transaction-ID) and file a file on the user's computer

Is this possible with argparse? I was hoping I could use add_mutually_exclusive_group, but that didn't seem to do what I want.

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('phone', help='Phone number')
group.add_argument('mmsid', help='MMS-Transaction-ID to download')
group.add_argument('file', help='MMS binary file to read')

This gives the error (removing required=True gives the same error):

ValueError: mutually exclusive arguments must be optional

It looks like it wants me to use --phone instead of phone:

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--phone', help='Phone number')
group.add_argument('--mmsid', help='MMS-Transaction-ID to download')
group.add_argument('--file', help='MMS binary file to read')

When running my program with no arguments, I see:

error: one of the arguments --phone --mmsid --file is required

This is closer to what I want, but can I make argparse do (--phone --msid) or (--file)?

Upvotes: 6

Views: 724

Answers (1)

chepner
chepner

Reputation: 530960

This is a little beyond the scope of what argparse can do, as the "type" of the first argument isn't known ahead of time. I would do something like

import argparse

p = argparse.ArgumentParser()
p.add_argument("file_or_phone", help="MMS File or phone number")
p.add_argument ("mmsid", nargs="?", help="MMS-Transaction-ID")

args = p.parse_args()

To determine whether args.file_or_phone is intended as a file name or a phone number, you need to check whether or not args.mmsid is None.

Upvotes: 4

Related Questions