trevorld / r-argparse

command-line optional and positional argument parser
GNU General Public License v2.0
103 stars 11 forks source link

Support default args with action="append" #35

Closed miker985 closed 2 years ago

miker985 commented 2 years ago

I cannot figure out how to pass default args as a list - they always come through as a tuple.

What I can do in Python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--test-dim", dest="dims", action="append", default=['year', 'sex', 'age'])

args = parser.parse_args(["--test-dim", "race"])
assert args.dims == ['year', 'sex', 'age', 'race']

What I'm trying to do in R

test_that("we can action = 'append' with a default list", {
  parser <- argparse::ArgumentParser()
  parser$add_argument("--test-dim", dest = "dims", action = "append", default = c("year", "sex", "age"))
  args <- parser$parse_args(c("--test-dim", "race"))

  expect_equal(args$dims, c("year", "sex", "age", "race"))
})

this results in the following error:

test-argparse.R:34: error: we can action = 'append' with a default list
python error
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
  File "/usr/lib/python3.7/argparse.py", line 1758, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python3.7/argparse.py", line 1790, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python3.7/argparse.py", line 1996, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/usr/lib/python3.7/argparse.py", line 1936, in consume_optional
    take_action(action, args, option_string)
  File "/usr/lib/python3.7/argparse.py", line 1864, in take_action
    action(self, namespace, argument_values, option_string)
  File "/usr/lib/python3.7/argparse.py", line 977, in __call__
    items.append(values)
Attribute'tuple' object has no attribute 'append'
Backtrace:
 1. parser$parse_args(c("--test-dim", "race")) tests/testthat/test-argparse.R:34:2
 2. argparse:::.stop(output, "Error: python error")

Changing the default to default = list("year", "sex", "age") results in a different error

test-argparse.R:34: error: we can action = 'append' with a default list
python error
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
Namename 'year' is not defined
Backtrace:
 1. parser$parse_args(c("--test-dim", "race")) tests/testthat/test-argparse.R:34:2
 2. argparse:::.stop(output, "Error: python error")
trevorld commented 2 years ago

For now it seems you must manually add the default to dims after parsing the args

test_that("we can action = 'append' with a default list", {
  parser <- argparse::ArgumentParser()
  parser$add_argument("--test-dim", dest = "dims", action = "append")
  args <- parser$parse_args(c("--test-dim", "race"))
  args$dims <- c("year", "sex", "age", args$dims)

  expect_equal(args$dims, c("year", "sex", "age", "race"))
})
trevorld commented 2 years ago