The Python interpreter can be run either in script or interactive/REPL mode.
I do have a Python script as text file but want to run it as if it was manually typed in in the interactive/REPL mode.
I want to get the output (stdout) exactly as if this was done.
To give an example, assume that I have the following text stored in a file called srcipt.py
a = 5
a + 8
if a < 4:
print("123")
else:
print("xyz")
exit()
I want to execute this script and get the following stdout:
Python 3.12.3 (main, Jun 18 2025, 17:59:45) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 5
>>> a + 8
13
>>> if a < 4:
... print("123")
... else:
... print("xyz")
...
xyz
>>> exit()
As far as I can see, this is not possible using the python3
command with any of the standard options.
So I am looking either for some Bash script or maybe a Python program that would take the path to my script as input and then produce the stdout as required.
If need be, I could also change my input script to look like this:
>>> a = 5
>>> a + 8
>>> if a < 4:
... print("123")
... else:
... print("xyz")
>>> exit()
I feel that what I want should be possible, because I think that doctests doing something not very far from this.
Many thanks for any suggestions or pointers.
Cheers, Thomas.
Have you tried the code module?
I would simply supply each line as input to code module and then process it later for whatever type of output I want.
Example
import code
import sys
import io
from contextlib import redirect_stdout
def simulate_repl(script_path):
# Read the script
with open(script_path, 'r') as file:
lines = file.readlines()
# Remove trailing newlines and handle empty lines
lines = [line.rstrip('\n') for line in lines]
# If you really want the python header or skip it
print(f"Python {sys.version} on {sys.platform}")
print('Type "help", "copyright", "credits" or "license" for more information.')
# Create an InteractiveConsole instance (best option for you)
console = code.InteractiveConsole()
# Buffer for multi-line statements
source = []
is_multiline = False
for line in lines:
# Skip empty lines
if not line.strip():
continue
# Check if the line is a continuation (starts with ...)
if line.strip().startswith('...'):
source.append(line.replace('...', '', 1).lstrip())
continue
# If we're in a multiline block, complete it
if is_multiline:
# Execute the collected multiline block
block = '\n'.join(source)
print(f'>>> {source[0]}')
for s in source[1:]:
print(f'... {s}')
# Capture output
with io.StringIO() as buf, redirect_stdout(buf):
more = console.push(block)
output = buf.getvalue()
if output:
print(output, end='')
source = []
is_multiline = more
if line.strip() == 'exit()':
break
if not is_multiline:
continue
# Handle single-line statements
if line.strip() == 'exit()':
print('>>> exit()')
break
# Print the prompt and the line
print(f'>>> {line}')
# Check if the line starts a multiline block
if line.rstrip().endswith(':'):
source.append(line)
is_multiline = True
continue
# Execute single-line statement and capture output
with io.StringIO() as buf, redirect_stdout(buf):
more = console.push(line)
output = buf.getvalue()
if output:
print(output, end='')
is_multiline = more
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python repl_simulator.py <script_path>")
sys.exit(1)
simulate_repl(sys.argv[1])