6

How do I specify the position of a positional argument?

In my example below, the SCR & SCV arguments appear at the end of the optional arguments, I want them to appear at the beginning.

#!/usr/bin/python
import argparse

### Parse arguments ###
parser = argparse.ArgumentParser()
parser.add_argument("SCR",type=int)
parser.add_argument("SCV",type=int)
parser.add_argument("--itemid",nargs='?')
parser.add_argument("--tkt",nargs='?')
parser.add_argument("--rfc",nargs='?')
parser.add_argument("--state",nargs='?')
parser.add_argument("--vendor",nargs='?')
parser.add_argument("--application",nargs='?')
parser.add_argument("--submitter",nargs='?')
parser.add_argument("--assigneddev",nargs='?')
parser.add_argument("--manager",nargs='?')
parser.add_argument("--maasteps",nargs='?')
parser.add_argument("--reasonforfailure",nargs='?')
parser.add_argument("--assignedpm",nargs='?')
parser.add_argument("--release",nargs='?')
parser.add_argument("--erelease",nargs='?')
parser.add_argument("--testenvloaded",nargs='?')
parser.add_argument("--datetestloaded",nargs='?')
parser.add_argument("--dateint2loaded",nargs='?')
parser.add_argument("--tqadeploytime",nargs='?')
parser.add_argument("--prodenvloaded",nargs='?')
parser.add_argument("--dateprodloaded",nargs='?')
parser.add_argument("--proddeploytime",nargs='?')
parser.add_argument("--proddeployer",nargs='?')
args = parser.parse_args()



> scratch.py -h
usage: scratch.py [-h] [--itemid [ITEMID]] [--tkt [TKT]] [--rfc [RFC]]
                  [--state [STATE]] [--vendor [VENDOR]]
                  [--application [APPLICATION]] [--submitter [SUBMITTER]]
                  [--assigneddev [ASSIGNEDDEV]] [--manager [MANAGER]]
                  [--maasteps [MAASTEPS]]
                  [--reasonforfailure [REASONFORFAILURE]]
                  [--assignedpm [ASSIGNEDPM]] [--release [RELEASE]]
                  [--erelease [ERELEASE]] [--testenvloaded [TESTENVLOADED]]
                  [--datetestloaded [DATETESTLOADED]]
                  [--dateint2loaded [DATEINT2LOADED]]
                  [--tqadeploytime [TQADEPLOYTIME]]
                  [--prodenvloaded [PRODENVLOADED]]
                  [--dateprodloaded [DATEPRODLOADED]]
                  [--proddeploytime [PRODDEPLOYTIME]]
                  [--proddeployer [PRODDEPLOYER]]
                  SCR SCV
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Radamand
  • 175
  • 1
  • 12
  • 3
    In traditional UNIX programs, options (what argparse calls "optional arguments") come before operands ("positional arguments"). Most modern programs will accept them in either order, but argparse still encourages people to pass them correctly. Why do you want to defeat that? – Kevin Apr 13 '15 at 17:31
  • 3
    Optional arguments *always* come before positional arguments in command line interfaces. Why do you need this to be different? – Martijn Pieters Apr 13 '15 at 17:31
  • i just thought it 'reads' better with the required arguments first rather than last... – Radamand Apr 13 '15 at 17:36
  • Probable duplicate of http://stackoverflow.com/questions/4480075/argparse-optional-positional-arguments – Caridorc Apr 13 '15 at 17:46
  • 4480075 asks about making positionals optional, this asks about position in the usage line. Not a duplicate. – hpaulj Apr 14 '15 at 04:13
  • 1
    @MartijnPieters Always? Git has them come after. – user1175849 Mar 03 '18 at 00:50
  • @user1175849: fine, *good* command line interfaces don't break that convention. Git is a terrible command-line UI. – Martijn Pieters Mar 03 '18 at 12:04

1 Answers1

7

The default usage formatter separates the positional arguments from the optionals, and displays them at the end. In the case of multiline displays like this, the positionals are put on a separate line. That is what you are seeing.

When parsing positionals can come first.

An obvious way around this is to supply your own usage string, but with this many arguments I can understand not wanting to do so.

https://stackoverflow.com/a/26986546/901925 (last November) has a HelpFormatter patch that disables this reordering. But as written it only applies to single line usage. Multiline usage is handled later in the same method.

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353