Handle spaces in argparse input
Question:
Using python and argparse, the user could input a file name with -d as the flag.
parser.add_argument("-d", "--dmp", default=None)
However, this failed when the path included spaces. E.g.
-d C:SMTHNGName with spacesMOREfile.csv
NOTE: the spaces would cause an error (flag only takes in ‘C:SMTHNGName’ as input).
error: unrecognized arguments: with spacesMOREfile.csv
Took me longer than it should have to find the solution to this problem…
(did not find a Q&A for it so I’m making my own post)
Answers:
Simple solution:
argparse considers a space filled string as a single argument if it is encapsulated by quotation marks.
This input worked and “solved” the problem:
-d "C:SMTHNGName with spacesMOREfile.csv"
NOTICE: argument has “” around it.
For those who can’t parse arguments and still get “error: unrecognized arguments:” I found a workaround:
parser.add_argument('-d', '--dmp', nargs='+', ...)
opts = parser.parse_args()
and then when you want to use it just do
' '.join(opts.dmp)
Bumped into this problem today too.
-d "foo bar"
didn’t help. I had to add the equal sign
-d="foo bar"
and then it did work.
After some experiments (python 2.7 Win10) I found out that the golden rule is to put quotes (“”) around arguments which contain spaces and do NOT put if there are no spaces in argument. Even if you are passing a string/path. Also putting a single quotes (”) is a bad idea, at least for Windows.
Small example:
python script.py –path ….Some_Folder –string “Here goes a string”
You need to surround your path with quotes such as:
python programname.py -path "c:My path with spaces"
In the argument parse you get a list with one element. You then have to read it like:
path = args.path[0]
A common mistake, when forwarding bash script arguments, is to forget double quotes.
for example writting this:
ARGS="C:SMTHNGName with spacesMOREfile.csv"
mypythonscript -d $ARGS
while it should be
ARGS="C:SMTHNGName with spacesMOREfile.csv"
mypythonscript -d "$ARGS"
There are 2 important points here (from my perspective):
- You do not want to replace all the spaces in the argument input.
- You want to use
argparse
interface.
My best aproax would be to use an argparse.Action
with the function strip
for the string:
import argparse
class StripArgument(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values.strip())
parser = argparse.ArgumentParser(
prog=f"your program", description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="See '<command> --help' to read about a specific sub-command.")
parser.add_argument(
"-n", "--variable-name", type=str, default='vx', action=StripArgument,
help="Variable name inside something (default: %(default)s)")
Using python and argparse, the user could input a file name with -d as the flag.
parser.add_argument("-d", "--dmp", default=None)
However, this failed when the path included spaces. E.g.
-d C:SMTHNGName with spacesMOREfile.csv
NOTE: the spaces would cause an error (flag only takes in ‘C:SMTHNGName’ as input).
error: unrecognized arguments: with spacesMOREfile.csv
Took me longer than it should have to find the solution to this problem…
(did not find a Q&A for it so I’m making my own post)
Simple solution:
argparse considers a space filled string as a single argument if it is encapsulated by quotation marks.
This input worked and “solved” the problem:
-d "C:SMTHNGName with spacesMOREfile.csv"
NOTICE: argument has “” around it.
For those who can’t parse arguments and still get “error: unrecognized arguments:” I found a workaround:
parser.add_argument('-d', '--dmp', nargs='+', ...)
opts = parser.parse_args()
and then when you want to use it just do
' '.join(opts.dmp)
Bumped into this problem today too.
-d "foo bar"
didn’t help. I had to add the equal sign
-d="foo bar"
and then it did work.
After some experiments (python 2.7 Win10) I found out that the golden rule is to put quotes (“”) around arguments which contain spaces and do NOT put if there are no spaces in argument. Even if you are passing a string/path. Also putting a single quotes (”) is a bad idea, at least for Windows.
Small example:
python script.py –path ….Some_Folder –string “Here goes a string”
You need to surround your path with quotes such as:
python programname.py -path "c:My path with spaces"
In the argument parse you get a list with one element. You then have to read it like:
path = args.path[0]
A common mistake, when forwarding bash script arguments, is to forget double quotes.
for example writting this:
ARGS="C:SMTHNGName with spacesMOREfile.csv"
mypythonscript -d $ARGS
while it should be
ARGS="C:SMTHNGName with spacesMOREfile.csv"
mypythonscript -d "$ARGS"
There are 2 important points here (from my perspective):
- You do not want to replace all the spaces in the argument input.
- You want to use
argparse
interface.
My best aproax would be to use an argparse.Action
with the function strip
for the string:
import argparse
class StripArgument(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values.strip())
parser = argparse.ArgumentParser(
prog=f"your program", description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="See '<command> --help' to read about a specific sub-command.")
parser.add_argument(
"-n", "--variable-name", type=str, default='vx', action=StripArgument,
help="Variable name inside something (default: %(default)s)")