The prompt module is a simple embedded multiline python interpreter built around raw_input(). The interpreter can be started at any given location in a program by executing a tiny code object and is allways executed in the namespace of the caller. Objects in the current scope can easily be explored and modified. Intermediate interruption of the control flow for manual interaction is handy for debugging purposes. The ability of multiline commands was crucial for me, so I wrote this module. It is tested with python, jython and stackless. The prompt codeobject can also be started from the pdb prompt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #!/bin/env python
"""
prompt - multiline prompt
"""
# Simple embedded multiline python interpreter built around raw_input().
# Interrupts the control flow at any given location with 'exec prompt'
# and gives control to the user.
# Allways runs in the current scope and can even be started from the
# pdb prompt in debugging mode. Tested with python, jython and stackless.
# Handy for simple debugging purposes.
prompt = compile("""
try:
_prompt
_recursion = 1
except:
_recursion = 0
if not _recursion:
from traceback import print_exc as print_exc
from traceback import extract_stack
_prompt = {'print_exc':print_exc, 'inp':'','inp2':'','co':''}
_a_es, _b_es, _c_es, _d_es = extract_stack()[-2]
if _c_es == '?':
_c_es = '__main__'
else:
_c_es += '()'
print '\\nprompt in %s at %s:%s - continue with CTRL-D' % (_c_es, _a_es, _b_es)
del _a_es, _b_es, _c_es, _d_es, _recursion, extract_stack, print_exc
while 1:
try:
_prompt['inp']=raw_input('>>> ')
if not _prompt['inp']:
continue
if _prompt['inp'][-1] == chr(4):
break
exec compile(_prompt['inp'],'<prompt>','single')
except EOFError:
print
break
except SyntaxError:
while 1:
_prompt['inp']+=chr(10)
try:
_prompt['inp2']=raw_input('... ')
if _prompt['inp2']:
if _prompt['inp2'][-1] == chr(4):
print
break
_prompt['inp']=_prompt['inp']+_prompt['inp2']
_prompt['co']=compile(_prompt['inp'],'<prompt>','exec')
if not _prompt['inp2']:
exec _prompt['co']
break
continue
except EOFError:
print
break
except:
if _prompt['inp2']:
continue
_prompt['print_exc']()
break
except:
_prompt['print_exc']()
print '--- continue ----'
# delete the prompts stuff at the end
del _prompt
""", '<prompt>', 'exec')
# runs the testcase
if __name__=='__main__':
def my_func():
exec prompt
class prompt_test:
def __init__(self):
self.init = 'init'
def test_method(self):
self.dummy = 'dummy'
# interrupt control flow inside a method
exec prompt
# 1: exec prompt inside a method
prompt_test().test_method()
# 2: exec prompt inside a function
my_func()
# 3: exec prompt inside the modules global scope
exec prompt
|
here is a sample run of the testcase
python prompt.py
prompt in test_method() at prompt.py:83 - continue with CTRL-D
>>> dir() # we are in a methods scope
['_prompt', 'self']
>>> print self # and the instance is ...
here is a sample run of the testcase
python prompt.py
prompt in test_method() at prompt.py:83 - continue with CTRL-D
>>> dir() # we are in a methods scope
['_prompt', 'self']
>>> print self # and the instance is ...