'Capturing runpy.run_module stdout
I'm unable to capture stdout of runpy.run_module into a variable using StringIO.
To demonstrate the problem, I created a script called runpy_test.py (code below) using an arg switch;
- 0 = do not redirect stdout.
- 1 = redirect using StringIO, capture into variable, print variable.
Console Output
(base) PS C:\Users\justi\Documents> python .\runpy_test.py 0
pip 20.0.2 from C:\ProgramData\Anaconda3\lib\site-packages\pip (python 3.6)
(base) PS C:\Users\justi\Documents> python .\runpy_test.py 1
(base) PS C:\Users\justi\Documents>
I was expecting python .\runpy_test.py 1
to print pip 20.0.2 from C:\ProgramData\Anaconda3\lib\site-packages\pip (python 3.6)
, but as you can see from the above console capture, I'm getting nothing.
runpy_test.py
import io
import sys
import runpy
import copy
capture_stdout = bool(sys.argv[1] == "1")
if capture_stdout:
_stdout = sys.stdout
sys.stdout = io.StringIO()
_argv = copy.deepcopy(sys.argv)
sys.argv = ['', '-V']
runpy.run_module("pip", run_name="__main__")
sys.argv = _argv
if capture_stdout:
result = sys.stdout.getvalue()
sys.stdout = _stdout
print(f"result: {result}")
I'm guessing sys.stdout
is not being correctly re-initialised before I print because of something related to runpy.run_module
, but not really sure how to debug. Any ideas would be great, solutions even better.
My environment is Python 3.6.10 using conda 4.8.3.
Thanks in advance.
Solution 1:[1]
Using subprocess.check_output
instead of runpy.run_module
solved my problem.
See Installing python module within code
Solution 2:[2]
You can use capsys in the pytest framework:
def test_main(capsys):
runpy.run_module(
"helloworld",
init_globals=None,
run_name="__main__",
alter_sys=False)
captured = capsys.readouterr()
assert captured.out == "Hello, World!"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | David A. |