Thomas Ahle
Thomas Ahle

Reputation: 31594

Named arguments with Python argparse

I'm trying to create a terminal application a bit similar to cutechess-cli, which has options like the following:

-epdout FILE    Save the end position of the games to FILE in FEN format.
-recover        Restart crashed engines instead of stopping the match
-repeat [N]     Play each opening twice (or N times). Unless the -noswap...

which can all be done with argparse in Python.

However it also has "named arguments" like the following:

-resign movecount=COUNT score=SCORE [twosided=VALUE]
        Adjudicate the game as a loss if an engine's score is
        at least SCORE centipawns below zero for at least COUNT
        consecutive moves.
-sprt elo0=ELO0 elo1=ELO1 alpha=ALPHA beta=BETA
        Use a Sequential Probability Ratio Test as a termination
        criterion for the match. This option should only be used...

I can implement that with argparse using nargs='*' and then writing my own parser (maybe just regex). However that doesn't give nice documentation, and if argparse can already do something like this, I would rarther use the builtin approach.

Summary: Does argparse have a concept of named arguments similar to resign and sprt above? And if not, would the best approach be to do this manyally using nargs='*'?

Upvotes: 0

Views: 251

Answers (1)

Giacomo Alzetta
Giacomo Alzetta

Reputation: 2479

You can use a custom type to split the values and use the metavar argument to give a better description for the value:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--arg', nargs='*', type=lambda text: text.split('=', maxsplit=1), metavar='PARAM-NAME=PARAM-VALUE', help='Some other parameters')
args = parser.parse_args()
args.arg = {k: v for k,v in args.arg}

Which produces:

usage: [-h] [--arg [PARAM-NAME=PARAM-VALUE [PARAM-NAME=PARAM-VALUE ...]]]

optional arguments:
  -h, --help            show this help message and exit
  --arg [PARAM-NAME=PARAM-VALUE [PARAM-NAME=PARAM-VALUE ...]]
                        Some other parameters

If you wanted to you could avoid the "postprocessing" step to build the dictionary by using a custom Action type. But it seems an overkill to me in this case.

Upvotes: 1

Related Questions