47

I'm learning basics of Python and got already stuck at the beginning of argparse tutorial. I'm getting the following error:

import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
usage: __main__.py [-h] echo
__main__.py: error: unrecognized arguments: -f
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

a %tb command gives the following output:

SystemExit                                Traceback (most recent call last)
<ipython-input-16-843cc484f12f> in <module>()
----> 1 args = parser.parse_args()

C:\Users\Haik\Anaconda2\lib\argparse.pyc in parse_args(self, args, namespace)
   1702         if argv:
   1703             msg = _('unrecognized arguments: %s')
-> 1704             self.error(msg % ' '.join(argv))
   1705         return args
   1706 

C:\Users\Haik\Anaconda2\lib\argparse.pyc in error(self, message)
   2372         """
   2373         self.print_usage(_sys.stderr)
-> 2374         self.exit(2, _('%s: error: %s\n') % (self.prog, message))

C:\Users\Haik\Anaconda2\lib\argparse.pyc in exit(self, status, message)
   2360         if message:
   2361             self._print_message(message, _sys.stderr)
-> 2362         _sys.exit(status)
   2363 
   2364     def error(self, message):

SystemExit: 2

How could I fix this problem?

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Haik
  • 573
  • 1
  • 4
  • 5
  • 1
    You cannot experiment with this easily in ipython as the ipython command line will be used per default in `parse_args`. Try this with a normal `*.py` file and the python executable to launch that file. – languitar Feb 15 '17 at 12:56
  • See this [argparse](http://stackoverflow.com/questions/23714542/why-does-pythons-argparse-use-an-error-code-of-2-for-systemexit). It will help to you or surely helps to others – bob marti Feb 15 '17 at 12:57
  • I've reproduced your code and I don't find any problem. Have you tried it in .py file instead of another way? – Juan Antonio Feb 15 '17 at 13:01
  • 1
    Alternatively in ipython you can pass a list of args to the parser. From the argparse documentation: `parser.parse_args(['--sum', '7', '-1', '42'])` or `parser.parse_args('--sum 7 -1 42'.split() )` – nigel222 Feb 15 '17 at 13:02
  • thank you guys for immediate help pointing out where my mistake was and also providing alternative way, I've tried in different ways but all with ipython and not "normal" *.py – Haik Feb 15 '17 at 13:32
  • Please check out my answer below. I spent 3 hours on this and I think I found the real solution (and it should be the accepted answer to help people with the same problem). I took my answer from here https://stackoverflow.com/questions/48796169/how-to-fix-ipykernel-launcher-py-error-unrecognized-arguments-in-jupyter – Francesco Aug 31 '22 at 09:32

8 Answers8

50

argparse is a module designed to parse the arguments passed from the command line, so for example if you type the following at a command prompt:

$ python my_programme.py --arg1=5 --arg2=7

You can use argparse to interpret the --arg1=5 --arg2=7 part. If argparse thinks the arguments are invalid, it exits, which in general is done in python by calling sys.exit() which raises the SystemExit error, which is what you're seeing.

So the problem is you're trying to use argparse from an interactive interpreter (looks like ipython), and at this point the programme has already started, so the args should have already been parsed.

To try it properly create a separate python file such as my_programme.py and run it using python from a command line, as I illustrated.

daphtdazz
  • 7,754
  • 34
  • 54
  • 1
    yes it was exactly ipython, just want to say how much i appreciate your clear answer! And even I've spent several hours trying to figure out it myself, it seems I would need some more days to solve this problem alone. Thank you. – Haik Feb 15 '17 at 13:23
38

[quick solution] Add an dummy parser argument in the code

parser.add_argument('-f')
johninvirtual
  • 409
  • 4
  • 4
  • 4
    Hey, it worked but can you please provide some explanation on how does it working? – Saksham Dubey May 11 '20 at 09:21
  • 4
    Jupyter-Notebook has some some default arguments set. One of which is "-f ". import sys sys.argv running the above code will display them – johninvirtual Jan 15 '21 at 12:13
  • 1
    This should be the accepted answer in my opinion. The accepted answer is not a solution, my code is a Jupyter notebook I cannot run it as a script in the command line. – Francesco Jun 11 '22 at 05:01
25

had run into a similar issue. adding these lines fixed the issue for me.

import sys
sys.argv=['']
del sys
algorythms
  • 1,547
  • 1
  • 15
  • 28
6

I'm surprised nobody mentioned this answer here How to fix ipykernel_launcher.py: error: unrecognized arguments in jupyter?

There is no need for the -f argument. Also, the -f tricks works for Jupyter but not in VS code.

tl;dr

Use

args, unknown = parser.parse_known_args()

INSTEAD of

args = parser.parse_args()
Francesco
  • 461
  • 5
  • 15
5

parse_args method, when it's called without arguments, attempts to parse content of sys.argv. Your interpreter process had filled sys.argv with values that does not match with arguments supported by your parser instance, that's why parsing fails.

Try printing sys.argv to check what arguments was passed to your interpreter process.

Try calling parser.parse_args(['my', 'list', 'of', 'strings']) to see how parser will work for interpreter launched with different cmdline arguments.

Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
0

I know this question is nearly three years old but as dumb as it can sound, this exit error is also produced when you don't have argparse installed instead of the default "This module can't be found" error message. Just helping people that may have this error aswell.

0

Add an argument and assign some value works. I was passing args (ArgumentParser type object) from one function to another (not in a typical case, like, getting user args from terminal).

from argparse import ArgumentParser
parser = ArgumentParser()
# create and assign a dummy args
parser.add_argument('--myarg1')
args = parser.parse_args(['--myarg1', ''])

args.myarg2 = True  # actuals args assignment
myTargetFunction(args)  # passing args to another function  

I found without any actual args in parser, parse_args() gives error.

imankalyan
  • 155
  • 1
  • 8
0

There are two ways of solving this:

  1. Use get_ipython().__class__.__name__ to determine whether we're running on ipython or terminal, and then use parser.parse_args(args = []) when we're running on ipython

    try:
        get_ipython().__class__.__name__
        # No error means we're running on ipython
        args = parser.parse_args(args = []) # Reset args
    except NameError:
        # NameError means that we're running on terminal
        args = parser.parse_args()
    
  2. Use parser.parse_known_args() to store existing args separately. We would get a return of a tuple with two values (first is args that are added by add_argument and second is existing args)

    args = parser.parse_known_args()[0] # Allow unrecognized arguments
    

The difference of these two approaches is that the second one will allow unrecognized arguments. It will be stored in the second value of the returned tuple.

Neuron
  • 5,141
  • 5
  • 38
  • 59