I want to find (or make) a python script that reads a different python script line by line and prints the commands executed and the output right there after.
Suppose you have a python script, testfile.py
as such:
print("Hello world")
for i in range(3):
print(f"i is: {i}")
Now, I want a different python script that parses the testfile.py
and outputs the following:
print("Hello world")
## Hello world
for i in range(3):
print(f"i is: {i}")
## i is: 0
## i is: 1
## i is: 2
Any suggestions on existing software or new code on how to achieve this is greatly appreciated!
ipython
from python:One of the first thoughts were to run ipython from python using subprocess
:
import subprocess
import re
try:
proc = subprocess.Popen(args=["ipython", "-i"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
# Delimiter to know when to stop reading
OUTPUT_DELIMITER = ":::EOL:::"
# Variable to contain the entire interaction:
output_string = ""
# Open testfile.py
with open("testfile.py") as file_:
for line in file_:
# Read command
cmd = line.rstrip()
# Add the command to the output string
output_string += cmd + "\n"
proc.stdin.write(f"{cmd}\n")
# Print the delimiter so we know when to end:
proc.stdin.write('print("{}")\n'.format(OUTPUT_DELIMITER))
proc.stdin.flush()
# Start reading output from ipython
while True:
thisoutput = proc.stdout.readline()
thisoutput = thisoutput.rstrip()
# Now check if it's the delimiter
if thisoutput.find(OUTPUT_DELIMITER) >= 0:
break
output_string += thisoutput + "\n"
except Exception as e:
proc.stdout.close()
proc.stdin.close()
raise
proc.stdout.close()
proc.stdin.close()
print("-" * 4 + "START OUTPUT" + "-" * 4)
print(output_string)
print("-" * 4 + "END OUTPUT" + "-" * 4)
In this approach, the problem becomes indented blocks, like the for
loop.
Ideally something like this would work using just plain python
(and not ipython
).
code.InteractiveConsole.interact
does exactly what is asked.