1

I have a CLI Python application that I am attempting to add an optional command flag to to be handled via argparse. I'd like to be able to pass a value to a flag that starts with a dash - or potentially two of them.

Naturally, argparse views values like this to be new flags and understandably complains. Is there a way to pass this value in as a raw string or something similar and have it stored as you would in most use cases?

Pseudo code:

parser = argparse.ArgumentParser(
    prog = 'foo',
    description="bar"
)
parser.add_argument(
    "-a",
    "--arguments",
    required=False,
    type=str,
    action='store',
    default='',
    help="hi mom"
)

args = parser.parse_args()

Shell is zsh, but something portable would be preferred if possible.

Workaround attempts:

  • prog.py -a '--fizz'

    foo: error: argument -a/--arguments: expected one argument

  • prog.py -a "--fizz"

    foo: error: argument -a/--arguments: expected one argument

  • prog.py -a "\-\-fizz"

    foo: error: argument -a/--arguments: expected one argument

  • buzz="--fizz" && prog.py -a $buzz

    foo: error: argument -a/--arguments: expected one argument

It looks like a workaround can be achieved by changing the prefix characters expected to something other than '-'/'--' via the prefix_chars setting of argparse.ArgumentParser, but that's a fairly major break from normal conventions. I suspect that I'll have to bypass argparse and pull in the data via a conf file, but I'm hoping to avoid it if I can.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • This has a come up often, both here and bug/issues. Other possibilities that I recall from previous SO include `-a " -foo"` (ie a space before the dash), `-a=-foo` (I'm not sure about this), and `-a -- -foo`. – hpaulj Feb 25 '23 at 20:26
  • Using dash to distinguish between flags (option_string) and arguments is such an integral part of `parse_args` that's hard to bypass it. You can test whether shell level escapes do anything by looking a `sys.argv`. This is the list of strings `argparse` works with. Sometimes people edit that list to get around parser limitations. – hpaulj Feb 25 '23 at 20:46
  • Searching for `[argparse] leading+dash` gave various past questions. This may be the most instructive, dating back to 2014. https://stackoverflow.com/questions/16174992/cant-get-argparse-to-read-quoted-string-with-dashes-in-it. I wrote a lengthy answer there. – hpaulj Feb 25 '23 at 20:56
  • And from the docs: https://docs.python.org/3/library/argparse.html#arguments-containing – hpaulj Feb 25 '23 at 20:59
  • @hpaulj Thanks for sharing the docs link, I've been staring at this for too long and missed it. Additionally the SO link is very helpful, thank you. I think that -a="--foo" is going to be the go to here and I'll have to take special steps to make sure it's properly mentioned in the arg's help section. – iamnotsteve Feb 26 '23 at 03:32

0 Answers0