0

I'm trying to write a command line tool for Python that I can run like this..

orgtoanki 'b' 'aj.org' --delimiter="~" --fields="front,back"

Here's the script:

#!/usr/bin/env python3
import sys
import argparse

from orgtoanki.api import create_package

parser = argparse.ArgumentParser()
parser.add_argument('--fields', '-f', help="fields, separated by commas", type=str, default='front,back')
parser.add_argument('--delimiter', '-d', help="delimiter", type= str, default='*')
args = parser.parse_args()
name=sys.argv[1]
org_src=sys.argv[2]

create_package(name, org_src, args.fields, agrs.delimiter)

When I run it, I get the following error:

usage: orgtoanki [-h] [--fields FIELDS] [--delimiter DELIMITER]
orgtoanki: error: unrecognized arguments: b aj.org

Why aren't 'b' and 'ab.org' being interpreted as sys.argv[1] and sys.argv[2], respectively?

And will the default work as I expect it to, if fields and delimiter aren't supplied to the command line?

4
  • 3
    Argparse has no knowledge about what you do with sys.argv on your own or that this removes its responsibility to handle these parts. Why don’t you just also take two positional parameters via argparse? Commented Apr 23, 2020 at 7:58
  • To rephrase, since you ask “why not?”: please clarify why you think argparse should know about the manual handling of args 1 and 2 (especially after parsing)? Commented Apr 23, 2020 at 8:01
  • @MisterMiyagi I don't actually think argparse should know about sys.arg handling the positional arguments. Maybe the question title led you to think so. I am not asking why argparse isn't interpreting b as an argparse variable, for example. Commented Apr 23, 2020 at 8:05
  • Then what is the question? Currently, it states “Why aren't 'b' and 'ab.org' being interpreted as sys.argv[1] and sys.argv[2], respectively?”. The only thing that doesn’t interpret sys.argv[1] and sys.argv[2] “correctly” is argparse, hence throwing the error. Commented Apr 23, 2020 at 8:16

2 Answers 2

2

The error here is caused by argparse parser which fails to apprehend the 'b' 'aj.org' part of the command, and your code never reaches the lines with sys.argv. Try adding those arguments to the argparse and avoid using both argparse and sys.argv simultaneously:

parser = argparse.ArgumentParser()

# these two lines
parser.add_argument('name', type=str)
parser.add_argument('org_src', type=str)

parser.add_argument('--fields', '-f', help="fields, separated by commas",
                    type=str, default='front,back')
parser.add_argument('--delimiter', '-d', help="delimiter",
                    type= str, default='*')

args = parser.parse_args()

You then can access their values at args.name and args.org_src respectively.

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

Comments

1

The default input to parser.parse_args is sys.argv[1:].

usage: orgtoanki [-h] [--fields FIELDS] [--delimiter DELIMITER]
orgtoanki: error: unrecognized arguments: b aj.org

The error message was printed by argparse, followed by an sys exit.

The message means that it found strings in sys.argv[1:] that it wasn't programmed to recognize. You only told it about the '--fields' and '--delimiter' flags.

You could add two positional fields as suggested by others.

Or you could use

[args, extras] = parser.parse_known_args()
name, org_src = extras

extras should then be a list ['b', 'aj.org'], the unrecognized arguments, which you could assign to your 2 variables.

Parsers don't (usually) consume and modify sys.argv. So several parsers (argparse or other) can read the same sys.argv. But for that to work they have to be forgiving about strings they don't need or recognize.

Comments

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.