Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

argparse: optional argument between positional arguments

Tags:

I want to emulate the behavior of most command-line utilities, where optional arguments can be put anywhere in the command line, including between positional arguments, such as in this mkdir example:

mkdir before --mode 077 after

In this case, we know that --mode takes exactly 1 argument, so before and after are both considered positional arguments. The optional part, --mode 077, can really be put anywhere in the command line.

However, with argparse, the following code does not work with this example:

# mkdir.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--mode', nargs=1)
parser.add_argument('dirs', nargs='*')
args = parser.parse_args()

Running ./mkdir.py before --mode 077 after results in:

mkdir.py: error: unrecognized arguments: after

How can I get argparse to accept an optional argument (with a fixed, known number of items) between positional ones?

like image 912
anol Avatar asked Sep 25 '20 20:09

anol


1 Answers

Starting from Python 3.7, it seems argparse now supports this kind of Unix-style parsing:

Intermixed parsing

ArgumentParser.parse_intermixed_args(args=None, namespace=None)

A number of Unix commands allow the user to intermix optional arguments with positional arguments. The parse_intermixed_args() and parse_known_intermixed_args() methods support this parsing style.

There is a caveat, but for "simple" options, it does not affect them:

These parsers do not support all the argparse features, and will raise exceptions if unsupported features are used. In particular, subparsers, argparse.REMAINDER, and mutually exclusive groups that include both optionals and positionals are not supported.

(I posted this FAQ-style question after spending 1 hour trying to understand why the examples in the Python argparse documentation didn't seem to include it, and only by chance found a somewhat unrelated question which contained the mention to this "intermixed" function in a comment, which I am unable to find again to cite it properly.)

like image 142
anol Avatar answered Sep 30 '22 22:09

anol