61

Hey so I'm using argparse to try and generate a quarterly report. This is what the code looks like:

parser  = argparse.ArgumentParser()

parser.add_argument('-q', "--quarter",  action='store_true', type=int, help="Enter a Quarter number: 1,2,3, or 4 ")
parser.add_argument('-y', "--year", action='store_true',type=str,help="Enter a year in the format YYYY ")
args = parser.parse_args()

the error I receive is:

TypeError: init() got an unexpected keyword argument 'type'

as far as I can tell from the argparse documentation type is one of the parameters of the add_argument function. I tried removing this and updating the code to :

parser  = argparse.ArgumentParser()

parser.add_argument('-q', "--quarter",  action='store_true', help="Enter a Quarter number: 1,2,3, or 4 ")
parser.add_argument('-y', "--year", action='store_true',help="Enter a year in the format YYYY ")
args = parser.parse_args()

I then tried to run it with: python scriptname.py -q 1 -y 2015 and it is giving me the following error:

error:unrecognized arguments: 1 2015

I don't know why that is either. Can anyone please shed some light on this.

5
  • Please reformat that code, it's hard to read - 4 chars before each line will make it be a code block. Commented Nov 6, 2015 at 19:31
  • 1
    Why are you using action='store_true'? What was your understanding of what that would do? Commented Nov 6, 2015 at 19:33
  • 1
    later on in the code i do a check to see if the variables stored in argparse are true. if they are i execute some code. Commented Nov 6, 2015 at 19:37
  • if args.quarter and args.year: Commented Nov 6, 2015 at 19:37
  • 3
    The purpose of store_true is to save the value True for the named variable. Specifying a type value for the same option is meaningless, and disallowed. Commented Nov 6, 2015 at 19:43

2 Answers 2

70

What action="store_true" means is that if the argument is given on the command line then a True value should be stored in the parser. What you actually want is to store the given year (as a string) and quarter (as an int).

parser  = argparse.ArgumentParser()

parser.add_argument('-q', "--quarter", type=int, help="Enter a Quarter number: 1,2,3, or 4 ")
parser.add_argument('-y', "--year", type=str, help="Enter a year in the format YYYY ")
args = parser.parse_args()

When you specify action='store_true argparse is internally instantiating a _StoreAction instance whose constructor does not accept a type parameter (since it will always be a boolean (True/False)). You cannot supply action="store_true" and 'type' at the same time.

Sign up to request clarification or add additional context in comments.

1 Comment

dang tutorial. They make it look like you need action="store_true" if you want a short version like -q
19

The argparse documentation is not as detailed as it could be (but still has more information than many users can absorb).

In particular, the actual information that an argument needs varies with action.

parser.add_argument('-q', "--quarter",  action='store_true', type=int, help="Enter a Quarter number: 1,2,3, or 4 ")

A store_true action does not take any parameters (i.e. nargs=0). It's default value is False, and if used the attribute is set to True.

If you want the user to give one of those four numbers I'd suggest using

parser.add_argument('-q', '--quarter', type=int, choices=[1,2,3,4], help="...")

https://docs.python.org/3/library/argparse.html#choices has a similar example.

The examples in https://docs.python.org/3/library/argparse.html#action give a pretty good idea of what parameters each action class takes.

There is a Python bug/issue discussing improving either the documentation, or the error message when unnecessary parameters are given in the function. As it stands, it's the Python subclass definition that is issuing the error message.

6 Comments

Interesting, to so the "optionality" flavor is built in, no need to do nargs='?' for example, which apparently conflicts with that built in/default design.
The base Action class has 2 parameters and 8 keyword parameters. But for the 'store_true' subclass, _StoreTrueAction subclass, only 3 of those keywords are in its __init__, and only the help makes sense. Class inheritance gives a lot of flexibility, but sometimes makes accurate documentation difficult.
argparse docs on required may help docs.python.org/2/library/argparse.html#required
Got confused when getting this error, turns out when using action='store_true', type= is not needed and will cause error. Simply removing it solves the problem.
Awesome! That suggestion was perfect for what I was going for. I was going to have two mutually exclusive arguments that I wanted to store constants (one would be 3 the other 4) but it wouldn't let me use type=int. The 'official' answer tells me why that doesn't work, but your answer showed me a much better way to do what I really wanted: provide a selection of exclusive version numbers. And this is easier to expand to support a version 5 (of my script) if it ever comes out. Brilliant!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.