1

I'm having issues with negative strings being fed into argparse and resulting in errors. I am wondering if anyone has figured out a way around this. Unfortunately, I need the strings to be prepended by a negative sign in some cases, so I cannot fix this by removing the negation part.

I've taken a look at some other stackoverflow pages, such as How to parse positional arguments with leading minus sign (negative numbers) using argparse but still have no solution for this. I'm sure that someone must have a solution for this!

Here is what I have tried and am seeing:

PyDev console: starting.
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:07:29) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
import argparse
argparser = argparse.ArgumentParser()
# arguments:
argparser.add_argument("--configfile", "--config", type=str, default=None,
                       help="A config file to parse (see src/configs/sample_config.ini for more details).")
argparser.add_argument("--starttime", "--st", type=str, default="-1h@m",
                       help="Starting time for the dump; default: one hour ago rounded to the last minute. \n"
                            "Supported structure: -[0-9]+[h,m,s]+(@[h,m,s])?; for example: -1h@m, -10h, ... OR now")
argparser.add_argument("--endtime", "--et", type=str, default="@m",
                       help="Ending time for the dump; default: current time rounded to the last minute. \n"
                            "Supported structure: -[0-9]+[h,m,s]+(@[h,m,s])?; for example: -1h@m, -10h, ... OR now")
argparser.add_argument("--indexes", "--i", type=str, nargs="+", default="-config-",
                       help="Provide one or more indexes (comma-separated with quotes around the list; "
                            "ex: \"index1, index two, index3\") to search on. Default is \"-config-\" "
                            "which means that the indeces will be gathered from file names; see the sample "
                            "config for details.")
argparser.add_argument("--format", "--f", type=str, default="csv",
                       help="Write data out to CSV file.")
import shlex
args = argparser.parse_args(shlex.split("--configfile /somepath/sample_config_test04.ini --endtime now --indexes \"index one\" index2 index3 --format csv --starttime -5h@m"))
usage: pydevconsole.py [-h] [--configfile CONFIGFILE] [--starttime STARTTIME]
                       [--endtime ENDTIME] [--indexes INDEXES [INDEXES ...]]
                       [--format FORMAT]
pydevconsole.py: error: argument --starttime/--st: expected one argument
Process finished with exit code 2

As you can see the above fails, but the following works fine, so I am sure that it's an issue with the "-":

PyDev console: starting.
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:07:29) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
import argparse
argparser = argparse.ArgumentParser()
# arguments:
argparser.add_argument("--configfile", "--config", type=str, default=None,
                       help="A config file to parse (see src/configs/sample_config.ini for more details).")
argparser.add_argument("--starttime", "--st", type=str, default="-1h@m",
                       help="Starting time for the dump; default: one hour ago rounded to the last minute. \n"
                            "Supported structure: -[0-9]+[h,m,s]+(@[h,m,s])?; for example: -1h@m, -10h, ... OR now")
argparser.add_argument("--endtime", "--et", type=str, default="@m",
                       help="Ending time for the dump; default: current time rounded to the last minute. \n"
                            "Supported structure: -[0-9]+[h,m,s]+(@[h,m,s])?; for example: -1h@m, -10h, ... OR now")
argparser.add_argument("--indexes", "--i", type=str, nargs="+", default="-config-",
                       help="Provide one or more indexes (comma-separated with quotes around the list; "
                            "ex: \"index1, index two, index3\") to search on. Default is \"-config-\" "
                            "which means that the indeces will be gathered from file names; see the sample "
                            "config for details.")
argparser.add_argument("--format", "--f", type=str, default="csv",
                       help="Write data out to CSV file.")
import shlex
args = argparser.parse_args(shlex.split("--configfile /somepath/sample_config_test04.ini --endtime now --indexes \"index one\" index2 index3 --format csv --starttime 5h@m"))
print(args)
Namespace(configfile='/somepath/sample_config_test04.ini', endtime='now', format='csv', indexes=['index one', 'index2', 'index3'], starttime='5h@m')

You may be wondering why I'm calling the code like this; that's because I need to do some unittest-ing of the argparse calls that I am running, so I need to be able to call it from both the commandline as well as from my unittesting code.

If I call the same code from commandline without any quotes or \ in front of the -5h@m, that seems to work fine, but only for commandline (gets converted to \-5h@m). I have tried --starttime \"-5h@m\" and --starttime \-5h@m, -5h@m, '\-5h@m', etc. but nothing seems to be accepted and correctly parsed by argparse other than cmdl input.

The error is typically: test.py: error: argument --starttime/--st: expected one argument

Any help would be greatly appreciated!


Updates: changing the input to be alike to -configfile=/somepath/sample_config_test04.ini -endtime=now -indexes="index one, index2, index3" -format=csv -starttime=-5h@m seems to work from command line.

NOTE: I'd like to keep this answer mainly because the other suggested answer has a very weirdly phrased title that I would not be have been able to find by doing a google search for what I needed. I did update the question to also reflect that I also had listed items as part of it.

Chmod
  • 107
  • 1
  • 9
  • I'm noticing this line in argparse.py, which I think is the culprit: default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] I'm wondering if there isn't a way to make a prefix more than one char, which should be intuitive... What do you all think? – Chmod Jul 26 '18 at 20:01
  • Possible duplicate of [Can't get argparse to read quoted string with dashes in it?](https://stackoverflow.com/questions/16174992/cant-get-argparse-to-read-quoted-string-with-dashes-in-it) – k-nut Jul 26 '18 at 20:21
  • The '-5..' is being parsed as a flag, even though to you it looks like a negative number followed by other characters. So all the previous discussions of accepting an argument that begins with a dash apply. The simplest fix is to use `starttime=-5h@m' style of input. – hpaulj Jul 26 '18 at 21:24
  • 1
    Quoting the argument with an initial space also works: `--starttime ' -5h@m'` – hpaulj Jul 26 '18 at 21:33
  • I think my main issue is that things that work ok with command line, do not work in code-testing. I tried this: ["bogus","-configfile=/sample_config_test04.ini","-starttime=-5h@m","-endtime=now","-indexes=index1","-format=csv"] to make it look like argv format, but I can't seem to make argparse accept anything of this format. I am completely out of ideas on how to go about testing this via unittest code. Btw, the error that it gives me (very vague): "_jb_unittest_runner.py: error: unrecognized arguments: ". Any ideas? – Chmod Jul 30 '18 at 14:09
  • i'm just going to put a space in front of "-". seems to work fine for testing. – Chmod Jul 30 '18 at 14:19

0 Answers0