Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass command-line arguments to runpy

I have two files, one which has a side effect I care about that occurs within the if __name__ == "__main__" guard:

# a.py
d = {}
if __name__ == "__main__":
    d['arg'] = 'hello'

The second file imports the first (using runpy) and prints the dictionary:

# b.py
import runpy
m = runpy.run_module('a', run_name='__main__')
print(m['d'])  # {'arg': 'hello'}

So far this works. But now I want to change the first file to accept a command line argument:

import sys
d = {}
if __name__ == "__main__":
    d['arg'] = process(sys.argv[1])

The problem is that process() is written by someone else and outside of my control, but I still want to get the updated dictionary d after it has been "processed".

How can I mock sys.argv before calling runpy, or otherwise provide that value to a.py?

like image 830
Alex Shroyer Avatar asked Nov 06 '22 18:11

Alex Shroyer


1 Answers

Could it be this straightforward? I found this solution almost by accident.

$ python3 b.py foo
{'arg': 'foo'}

It seems that sys.argv[1] is passed in to a even when b.py is called from the command line.

edit

here is an example session from my shell:

me@desktop$ cat a.py b.py
import sys
d = {}
filename = sys.argv[1]
if __name__ == "__main__":
    d['result'] = filename + ' world'


# usage:
# python3 b.py filename
# 'filename' is passed in to the a module
import runpy
aa = runpy.run_module('a', run_name='__main__')
print(aa['d'])  # {}

me@desktop$ python3 b.py hello
{'result': 'hello world'}
like image 135
Alex Shroyer Avatar answered Nov 15 '22 10:11

Alex Shroyer