jabozzo
jabozzo

Reputation: 611

Execute python script within the interpreter, with arguments

I have a (python3) script that executes with argparse. For instance:

my_program.py arg0 arg1 arg2=foo

For debugging purposes, I want the script to execute and leave me in an open interpreter session. The usual methods for calling a script within the python interpreter are not working for me. For example:

# How to input the program arguments? (arg0 arg1 arg2=foo)
exec(open("my_program.py").read())
# How to inherit the interpreter variables once the program has finished executing?
import subprocess
subprocess.call(["my_program.py", "arg0", "arg1", "arg2=foo"])
# How to input the program arguments? (arg0 arg1 arg2=foo)
import my_program
my_program.main()

Is there a way to leave open the interpreter of my program after running and being able to input the program arguments?

Upvotes: 0

Views: 918

Answers (2)

hpaulj
hpaulj

Reputation: 231385

I have small script to echo the sys.argv (used to debug inputs to argparse):

2303:~/mypy$ cat echo.py
import sys
print(sys.argv)

If I run it, with the python '-i' option, I am left in an interpreter session with sys available:

2303:~/mypy$ python3 -i echo.py foo bar
['echo.py', 'foo', 'bar']
>>> sys.argv
['echo.py', 'foo', 'bar']
>>> 
<exit>

Or a simple script using argparse:

import argparse
p = argparse.ArgumentParser()
p.add_argument('-p')
p.add_argument('foo')
args = p.parse_args()
print(args)

Run with '-i':

2313:~/mypy$ python3 -i stack60625769.py -p foo bar
Namespace(foo='bar', p='foo')
>>> p
ArgumentParser(prog='stack60625769.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
>>> args
Namespace(foo='bar', p='foo')
>>> 

I usually work in an ipython session. From there I can %run a script:

2312:~/mypy$ inumpy3
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.11.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: %run stack60625769.py -p foo bar                                                        
Namespace(foo='bar', p='foo')
In [2]: args                                                                                   
Out[2]: Namespace(foo='bar', p='foo')
In [3]: p                                                                                      
Out[3]: ArgumentParser(prog='stack60625769.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)

I could run that parser again, with a custom argv (not the one that started the ipython session:

In [9]: p.parse_args('foo -p bar'.split())                                                     
Out[9]: Namespace(foo='foo', p='bar')

%run has various namespace options. The default is to run the script in a new namespace, but update the interactive on with its values.

Upvotes: 0

rdas
rdas

Reputation: 21285

Not the cleanest solution. You can set the sys.argv from the calling script:

Let's say we have foo.py:

import sys

print(sys.argv)

And we execute it like so:

import sys

sys.argv = ["arg1", "arg2"]

exec(open('foo.py').read())

We get:

['arg1', 'arg2']

Upvotes: 1

Related Questions