Home > front end >  Python3 Unable to store stdout to variable
Python3 Unable to store stdout to variable

Time:07-30

My case is a little bit specific. I'm trying to run a Python program using Python for testing purposes. The case is as follows:

# file1.py
print("Hello world")
# file1.test.py
import io
import sys
import os
import unittest

EXPECTED_OUTPUT = "Hello world"

class TestHello(unittest.TestCase):
    def test_hello(self):
        sio = io.StringIO()
        sys.stdout = sio
        os.system("python3 path/to/file1.py")
        sys.stdout = sys.__stdout__
        print("captured value:", sio.getvalue())
        self.assertEqual(sio.getvalue(), EXPECTED_STDOUT)

if __name__ == "__main__":
    unittest.main()

But nothing ends up in the sio variable. This way and similar ways are introduced online but they don't seem to work for me. My Python version is 3.8.10 but it doesn't really matter if this works better in some other version, I can switch to that.

Note: I know that if I was using an importable object this might be easier, but right now I need to know how to catch the output of another file.

Thanks!

CodePudding user response:

stdout redirection does not work like this - this will change the stdout variable inside your Python process. But by using os.system, you are running another process, that will re-use the same terminal pseudo-files your parent process is using.

If you want to log a subprocess, the way to do it is to use the subprocess modules calls, which allow you to redirect the subprocess output. https://docs.python.org/3/library/subprocess.html

Also, the subprocess won't be able to use a StringIO object from the parent process (it is not an O.S. level object, just an in-process Python object with a write method). The docs above include instructions about using the special object subprocess.PIPE which allows for in-memory communication, or, you can just pass an ordinary filesystem file, which you can read afterwards.

  • Related