Replaced your cpp extension module by a plain Python one, which simply prints every line of the file that it receives as an argument.
Below it's an example of capturing its output.
cpp.py:
def strings(file_name):
with open(file_name) as f:
for line in f:
print(line.rstrip())
code00.py:
#!/usr/bin/env python
import sys
import io
import traceback
import cpp as cpp_fun
def capture_function_output(func, *func_args):
tmp_buf_out = io.StringIO()
tmp_buf_err = io.StringIO()
_sys_stdout = sys.stdout
sys.stdout = tmp_buf_out
_sys_stderr = sys.stderr
sys.stderr = tmp_buf_err
try:
func_ret = func(*func_args)
except:
func_ret = None
traceback.print_exc()
tmp_buf_out.flush()
tmp_buf_err.flush()
sys.stdout = _sys_stdout
sys.stderr = _sys_stderr
tmp_buf_out.seek(0)
func_stdout = tmp_buf_out.read()
tmp_buf_err.seek(0)
func_stderr = tmp_buf_err.read()
return func_ret, func_stdout, func_stderr
def test_capture_cpp_fun_output(file_name):
retcode, sout, serr = capture_function_output(cpp_fun.strings, file_name) # Store function return code, stdout and stderr contents into 3 variables
print("Function ({0:s}) returned: {1:}".format(cpp_fun.strings.__name__, retcode))
print("Function printed to stdout: \n{0:s}".format(sout))
print("--- Done")
print("Function printed to stderr: \n{0:s}".format(serr))
print("--- Done")
def main(*argv):
for file_name in [
"dummy.txt",
"dummy.txt0", # Doesn't exist!
]:
print("\nTesting file: {0:s}:".format(file_name))
test_capture_cpp_fun_output(file_name)
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
Output:
e:\Work\Dev\StackOverflow\q060851454>sopr.bat
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
[prompt]> type dummy.txt
dummy line 0
next line
0123456789
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Testing file: dummy.txt:
Function (strings) returned: None
Function printed to stdout:
dummy line 0
next line
0123456789
--- Done
Function printed to stderr:
--- Done
Testing file: dummy.txt0:
Function (strings) returned: None
Function printed to stdout:
--- Done
Function printed to stderr:
Traceback (most recent call last):
File "code00.py", line 18, in capture_function_output
func_ret = func(*func_args)
File "e:\Work\Dev\StackOverflow\q060851454\cpp.py", line 2, in strings
with open(file_name) as f:
FileNotFoundError: [Errno 2] No such file or directory: 'dummy.txt0'
--- Done
Done.
Update #0
Changed the code to also capture function's stderr.
Update #1
Adding the [Python 3.Docs]: subprocess - Subprocess management based variant (which works too on my side). This needs an additional script (cpp_wrapper.py, which relies on cpp.py from above).
cpp_wrapper.py:
import sys
import cpp as cpp_fun
if __name__ == "__main__":
if (len(sys.argv) < 2):
raise RuntimeError("Missing argument")
file_name = sys.argv[1]
try:
cpp_fun.strings(file_name)
except:
raise
else:
raise RuntimeError("This module should be executed directly")
code01.py:
#!/usr/bin/env python
import sys
import subprocess
def capture_cpp_fun_output(file_name):
cmd = (sys.executable, "cpp_wrapper.py", file_name)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
return p.returncode, out.decode(), err.decode()
def main(*argv):
for file_name in [
"dummy.txt",
"dummy.txt0", # Doesn't exist!
]:
print("\nTesting file: {0:s}:".format(file_name))
retcode, sout, serr = capture_cpp_fun_output(file_name) # Store function return code, stdout and stderr contents into 3 variables
print("Function returned: {0:}".format(retcode))
print("Function printed to stdout: \n{0:s}".format(sout))
print("--- Done")
print("Function printed to stderr: \n{0:s}".format(serr))
print("--- Done")
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
Output:
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Testing file: dummy.txt:
Function returned: 0
Function printed to stdout:
dummy line 0
next line
0123456789
--- Done
Function printed to stderr:
--- Done
Testing file: dummy.txt0:
Function returned: 1
Function printed to stdout:
--- Done
Function printed to stderr:
Traceback (most recent call last):
File "cpp_wrapper.py", line 11, in <module>
cpp_fun.strings(file_name)
File "e:\Work\Dev\StackOverflow\q060851454\cpp.py", line 2, in strings
with open(file_name) as f:
FileNotFoundError: [Errno 2] No such file or directory: 'dummy.txt0'
--- Done
Done.