Pass a parameter value starting with minus (-) using argparse [duplicate] - python

This question already has answers here:
Can't get argparse to read quoted string with dashes in it?
(7 answers)
Closed 5 years ago.
I'm doing a command line utility that can receive a parameter starting with a minus or plus, for instance, -gtest or +gtest the problem is that python3 don't accept this:
This is a minimal code that reproduce this problem:
import argparse
if (__name__== "__main__"):
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--string', action='store',
help='String value')
p = parser.parse_args()
if p.string:
print("pass value:", p.string)
I try to invoke it as:
./example.py -s -gtest
./example.py -s "-gtest"
./example.py -s \-gtest
And always get next error:
usage: example.py [-h] [-s STRING]
example.py: error: argument -s/--string: expected one argument
So, my question is how I can pass a argument starting with a minus using argparse

You can run it with:
python example.py -s-gtest
python example.py -s+gtest
So simply not putting any space, nor escaping it in any special way.

Related

How to get the command-line script of the running python program? [duplicate]

This question already has answers here:
Full command line as it was typed
(10 answers)
Closed 8 months ago.
Context
For example, there is a python file named helloworld.py, and I am using python helloworld.py --arg1 --arg2 to run this python file.
Question
What should I write in the python file helloworld.py to obtain its running command-line script, i.e., python helloworld.py --arg1 --arg2?
2 options: sys.argv and argparse
sys.argv:
Simpler, provides the command line arguments as a list of strings. So running
python helloworld.py --arg1 --arg2
will mean that sys.argv contains
['helloworld.py', '--arg1', '--arg2']
argparse:
More feature rich. Unquestionably my recommendation for anything more than a singular argument.
Supports positional and keyword arguments.
Arguments mat have values and may be limited to presets.
help is automatically generated
Example:
## helloworld.py
import argparse
parser = argparse.ArgumentParser()
# Positional argument
parser.add_argument(
"operator",
help="Operator to use",
choices=("add","subtract")
)
# Optional argument with value
parser.add_argument(
"-i",
"--integer",
help="An integer",
default=0
)
# Optional argument, True if present, otherwise False
parser.add_argument(
"-sq",
"--square-everything",
action="store_true",
help="Whether all numbers will get squared"
)
args = parser.parse_args()
argument_dict = dict(args) # parse_args returns a namespace object
print(argument_dict)
python helloworld.py add -i 4 -sq
{"operator":"add", "integer":4, "square-everything": True}

Getting tuple from command line arguments [duplicate]

This question already has answers here:
Passing a tuple as command line argument
(3 answers)
Closed 2 years ago.
Have a question,
I'm writing a python-script and need to pass argument to the script from cmd.
My code to implement this little feature:
import sys
cars = sys.argv[1]
From command line, I type the next command:
python my_script.py ("Opel", "Nissan", 'Reno')
But when I checked the results, it was not a tuple, it was a string. How can I get a tuple from argument?
The command line does not know about Python data structures. All you get from there are strings. You can create them in Python, however:
cars = sys.argv[1].split()
# cars = tuple(sys.argv[1].split())
and call script as
python my_script.py "Opel Nissan Reno"
For more advanced argument processing, you should consider using the argparse module.
command line is not define tuple.
try this from command line
python my_script.py "Opel" "Nissan" "Reno"
import sys
# get from 1 to end
cars = sys.argv[1:]
How about this:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--data', nargs='+', type=str)
args = parser.parse_args()
my_tuple = tuple(args.data)
print(type(my_tuple)) # Check type
Run:
python my_script.py --data Opel Nissan Reno
Output:
<class 'tuple'>

How to use argparse without using dest variable? [duplicate]

This question already has answers here:
Python argparse command line flags without arguments
(5 answers)
Closed 4 years ago.
I want to use argparse to get option to my program. Here is my sample program:
from argparse import ArgumentParser
parser = ArgumentParser()
print("enter the numbers:")
a=int(input("number 1:"))
b=int(input("number 2:"))
parser.add_argument('-a','--add')
parser.add_argument('-s','--sub')
options = parser.parse_args()
if options:
c=a+b
if options.d:
c=a-b
print(c)
it gives the output correctly if I use
python file.pu -a 1
But I don't want to give value like 1 in compilation. What I want is
python file.py -a
that performs addition.
python file.py -s
that performs subtraction.
How to change the code for it?
You can use:
action='store_true'
...in the following:
parser.add_argument('-a', '-add', action='store_true')

argparse - valid argument value falsely ignored [duplicate]

This question already has answers here:
Can't get argparse to read quoted string with dashes in it?
(7 answers)
Closed 5 years ago.
Consider following MCVE:
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--test")
parser.add_argument("-o", "--other")
assert sys.argv == ['mcve.py', '-o', '-t 123']
parsed = parser.parse_args()
assert parsed.other == "-t 123"
And its' invocation:
lrogalsk-mac01:src lrogalsk$ python mcve.py -o "-t 123"
usage: mcve.py [-h] [-t TEST] [-o OTHER]
mcve.py: error: argument -o/--other: expected one argument
As you can see, values in shell are interpreted correctly and passed to Python process as separate command line arguments. Nevertheless, argparse parsing mechanism still rejects this value (likely because it begins with match of another parameter, -t).
Changing invocation to space-prepended value (see below) and adjusting assertions in MCVE script makes it work, but this for me is merely workaround and not an actual solution.
lrogalsk-mac01:src lrogalsk$ python mcve.py -o " -t 123"
Is there any known way of fixing this behaviour in argparse?
Set-up details:
lrogalsk-mac01:src lrogalsk$ python --version
Python 2.7.10
In the 'argparse' documentation, this case is mentioned (16.4.4.3):
The parse_args() method attempts to give errors whenever the user has
clearly made a mistake, but some situations are inherently ambiguous.
For example, the command-line argument -1 could either be an attempt
to specify an option or an attempt to provide a positional argument.
The parse_args() method is cautious here: positional arguments may
only begin with - if they look like negative numbers and there are no
options in the parser that look like negative numbers
For positional arguments, you can prepend a '--', but in your case that doesn't seem to work. Instead, the use of subparsers is supported, so
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help = 'the subparsers')
parser_a = subparsers.add_parser('o', help = 'the o option')
parser_a.add_argument('-t', '--test')
parsed = parser.parse_args()
print(parsed.test)
works. Calling the script with
python mcve.py o -t 123
gives the output
123

Python argparse store_true and store optional option in one argument [duplicate]

This question already has answers here:
Option accepted with and without value
(2 answers)
Closed 9 years ago.
I need to recognise if was given argument alone or with optional string or neither
parser.add_argument(???)
options = parser.parse_args()
so
./prog.py --arg
should store '' into options.arg,
./prog.py --arg=lol
stores 'lol' into options.arg and
./prog.py
left options.arg as None
now I have:
parser.add_argument("--arg", nargs="?",type=str,dest="arg")
but when I run myprogram as ./prog.py --arg options.arg remains None. Only way to recognise --arg was given is run it as ./prog.py --arg= and this is problem for me.
Use the const keyword:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--arg", nargs="?", type=str, dest="arg", const="")
print(parser.parse_args([]))
print(parser.parse_args(['--arg']))
print(parser.parse_args(['--arg=lol']))
results in
Namespace(arg=None)
Namespace(arg='')
Namespace(arg='lol')
You can do it with a custom action:
import argparse
parser = argparse.ArgumentParser()
class ArgAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
if values:
setattr(namespace,self.dest,values)
else:
setattr(namespace,self.dest,'')
parser.add_argument("--arg",nargs='?',action=ArgAction,dest="arg")
print parser.parse_args("--arg".split())
print parser.parse_args("--arg=foo".split())

Categories