Rocket Hazmat Rocket Hazmat - 8 months ago 60
Python Question

Variable length arguments

I am creating a python program using the

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:

./ (phone mmsid | file)

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

Is this possible with
? I was hoping I could use
, 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
gives the same error):

ValueError: mutually exclusive arguments must be optional

It looks like it wants me to use
instead of

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
(--phone --msid) or (--file)


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.