Using argparse for mandatory argument without prefix

2024/5/20 11:46:08

I'm trying to use argparse module within my python application. My application should be run with single mandatory argument without any prefixes. I could not come up with a way to do it.

Answer

Here is a simple example using argparse to require exactly one integer argument:

import argparseparser = argparse.ArgumentParser(description='process an integer')
parser.add_argument('integer', metavar='N', type=int, nargs=1,help='an integer')
args = parser.parse_args()
print(args.integer)

Saving this code in argparse1.py and running it gives:

$ python argparse1.py 5
[5]  $ python argparse1.py
usage: argparse1.py [-h] N
argpars1.py: error: the following arguments are required: N$ python argparse1.py 5 7
usage: argparse1.py [-h] N
argparse1.py: error: unrecognized arguments: 7$ python argparse1.py test
usage: argparse1.py N
argparse1.py: error: argument N: invalid int value: 'test'$ python argparse1.py -h
usage: argparse1.py [-h] Nprocess an integerpositional arguments:N           an integeroptional arguments:-h, --help  show this help message and exit

To remove the optional arguments define ArgumentParser with add_help=False as follows:

import argparseparser = argparse.ArgumentParser(add_help=False)
parser.add_argument('integer', metavar='N', type=int, nargs=1)
args = parser.parse_args()
print(args.integer)

Putting this code in argparse2.py and testing it gives:

$ python argparse2.py
usage: argparse2.py N
argparse2.py: error: the following arguments are required: N$ python argparse2.py 5
[5]$ python argparse2.py 5 7
usage: argparse2.py N
argparse2.py: error: unrecognized arguments: 7$ python argparse2.py hello
usage: argparse2.py N
argparse2.py: error: argument N: invalid int value: 'hello'$ python argparse2.py -h
usage: argparse2.py N
argparse2.py: error: the following arguments are required: N

All usage messages can be suppressed by importing argparse.SUPPRESS and configuring ArgumentParser with usage=SUPPRESS as follows:

from argparse import ArgumentParser,SUPPRESSparser = ArgumentParser(add_help=False, usage=SUPPRESS)
parser.add_argument('integer', metavar='N', type=int, nargs=1)
args = parser.parse_args()
print(args.integer)

Saving this code in argparse3.py and running it gives:

$ python argparse3.py 5
[5]$ python argparse3.py 5 7 9
argparse3.py: error: unrecognized arguments: 7 9$ python argparse3.py -h
argparse3.py: error: the following arguments are required: N

The "unrecognized arguments" error is hardcoded in ArgumentParser.parse_args() (https://hg.python.org/cpython/file/3.4/Lib/argparse.py#l1727) and the "following arguments are required" error is separately hardcoded (https://hg.python.org/cpython/file/3.4/Lib/argparse.py#l1994) both without recourse to modification from the API. The latter appears to be in _parse_known_args(self, arg_strings, namespace) that I suppose could be overridden but would involve copying about 250 lines of code in order to modify 1 line to change that error message.

However, it is possible to avoid these error messages by adding just one argument with nargs='*' and no type, which effectively allows all command lines, and then adding custom error handling of arguments including your own error and usage messages. For example:

import os
import sys
from argparse import ArgumentParser,SUPPRESSscript =  os.path.basename(sys.argv[0])
usage = 'usage: ' + script + ' n (int)'parser = ArgumentParser(add_help=False, usage=SUPPRESS)
parser.add_argument('integer', nargs='*')
args = parser.parse_args()if (len(args.integer) == 0):print('error: no argument provided\n', usage, file=sys.stderr, sep = '')sys.exit(1)if (len(args.integer) > 1):print('error: too many arguments\n', usage, file=sys.stderr, sep = '')sys.exit(1)v = args.integer[0]try:v = int(v)
except ValueError:print("error: '", v, "'", ' is not an integer\n', usage, file=sys.stderr, sep='')sys.exit(1)print(v + 2)

Putting this code in argparse4.py and testing it gives:

$ python argparse4.py 5
7$ python argparse4.py
error: no argument provided
usage: argparse4.py n (int)$ python argparse4.py 5 9
error: too many arguments
usage: argparse4.py n (int)$ python argparse4.py hello
error: 'hello' is not an integer
usage: argparse4.py n (int)
https://en.xdnf.cn/q/72617.html

Related Q&A

prevent unexpected stdin reads and lock in subprocess

A simple case Im trying to solve for all situations. I am running a subprocess for performing a certain task, and I dont expect it to ask for stdin, but in rare cases that I might not even expect, it m…

Regex split string by last occurrence of pattern

I am using regex to split a string <book name> by <author name> into book and author names.re.split(r\bby\b, text, 0, re.I)But problem arises when the book name contains the word "by&q…

How to write a unit-test where each test case has different input but does the same?

I need to create a unit-test for some python class. I have a database of inputs and expected results which should be generated by the UUT for those inputs.Here is the pseudo-code of what I want to do:f…

Unable to pass authentication information to NetSuites REST interface using Python

Ive been trying to get a NetSuite Restlet to work with Python 3.3 using urllib, but I cant seem to get the authorization to take and continually return a urllib.error.HTTPError: HTTP Error 401: Authori…

letsencrypt failed with ImportError: No module named interface

Im using Amazon linux, and I followed some steps for using letsencrypt that easily found in google search, but all it fails with:Error: couldnt get currently installed version for /root/.local/share/le…

ModuleNotFoundError: No module named skimage.util.montage

Im trying to import montage2d module from scikit-image:from skimage.util.montage import montage2dBut this error popped up:ModuleNotFoundError: No module named skimage.util.montageIm pretty sure I insta…

upgrading python module within code

My question relates to this question: Installing python module within code, but involves upgrading the module.Ive triedpackages=[apscheduler,beautifulsoup4,gdata]def upgrade(packages):for package in pa…

Django - 403 Forbidden CSRF verification failed

I have a contact form in Django for my website and when I was testing it locally it was working fine but now when I try to submit my contact form "live" it always comes up with 403 Forbidden …

Python model object validation

Im writing an interface to be used by two applications. This interface should use some DoSomethingRequest and DoSomethingResponse classes to do the communication.Is there any library that does some mod…

Cassandra 1.2 inserting/updating a blob column type using Python and the cql library

IntroI have a blob column on a Cassandra 1.2 column family, the table is defined as follows:CREATE TABLE objects (id text,obj blob,PRIMARY KEY (id) );The problem:The problem is that when I…