Reputation: 733
Using argparse in a Jupyter Notebook throws a TypeError. The same code works fine if I execute the same code as a script. MWE:
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args()
Result:
TypeError: 'level' is an invalid keyword argument for this function
Upvotes: 7
Views: 6067
Reputation: 231665
When I run your code in a Notebook, I get an argparse
usage error message:
usage: ipykernel_launcher.py [-h] [--name NAME]
ipykernel_launcher.py: error: unrecognized arguments: -f /run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json
With a print(sys.argv)
I get
['/home/paul/.local/lib/python3.6/site-packages/ipykernel_launcher.py', '-f', '/run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json']
sys.argv
, which parser
parses, contains the values used to launch the Notebook server, which this particular parser
is not setup to handle.
parser.parse_known_args()
displays:
(Namespace(name='foo'),
['-f',
'/run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json'])
That extra stuff that your parser can't handle is put in the extras
list.
Run with a custom argv
list works:
parser.parse_args(['-n', 'foobar'])
Namespace(name='foobar')
It's a good idea to put argparse
code (at least the parse_args
line) in a __main__
block, so it is not run when the script is imported. It will still run when the script is run as a script.
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args()
print(args)
This script also works when using %run stack50763033.py
. You can even give it arguments as you would with a script:
%run stack50763033.py -n testing
I have no idea what code is producing the level
keyword error. You'll have to give us the traceback if you want help with that.
Upvotes: 0
Reputation: 3042
Ipython is running some command-line arguments in the background. This interfers with argparse and optparse.
See this bug for Spyder (Ipython IDE), where -f
was being added as a command option and crashing as there was no handler for -f
.
You could try checking the arguments currently in play (as they did for the Spyder bug) and putting a dummy handler in place.
Run
import sys
print(sys.argv)
inside Ipython and see what it outputs.
On my system, it gives
['/usr/lib/python3.6/site-packages/ipykernel_launcher.py', '-f', '/run/user/1000/jupyter/kernel-7537e4dd-b5e2-407c-9d4c-7023575cfc7c.json']
Argparse assumes the first entry is the program name (sys.argv[0]
). In order to fix this, I had to call
parser = argparse.ArgumentParser(prog='myprogram', description='Foo')
... and now argparse
works in my notebook.
Upvotes: 2
Reputation: 733
One solution is to parse an empty list of arguments:
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args([])
Another is to use parse_known_args:
args, _ = parser.parse_known_args()
Upvotes: 7