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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import string
import sys
import traceback
try:
sys.ps1
except AttributeError:
sys.ps1 = ">>> "
try:
sys.ps2
except AttributeError:
sys.ps2 = "... "
def print_exc(limit=None, file=None):
if not file:
file = sys.stderr
# we're going to skip the outermost traceback object, we don't
# want people to see the line which excecuted their code.
tb = sys.exc_traceback
if tb:
tb = tb.tb_next
try:
sys.last_type = sys.exc_type
sys.last_value = sys.exc_value
sys.last_traceback = tb
traceback.print_exception(sys.last_type, sys.last_value,
sys.last_traceback, limit, file)
except:
print '--- hola! ---'
traceback.print_exception(sys.exc_type, sys.exc_value,
sys.exc_traceback, limit, file)
class PyInteractive:
def __init__(self):
self._pybuf = ""
def executeline(self, stuff, out = None, env = None):
if env is None:
import __main__
env = __main__.__dict__
if out:
saveerr, saveout = sys.stderr, sys.stdout
sys.stderr = sys.stdout = out
try:
if self._pybuf:
self._pybuf = self._pybuf + '\n' + stuff
else:
self._pybuf = stuff
# Compile three times: as is, with \n, and with \n\n appended.
# If it compiles as is, it's complete. If it compiles with
# one \n appended, we expect more. If it doesn't compile
# either way, we compare the error we get when compiling with
# \n or \n\n appended. If the errors are the same, the code
# is broken. But if the errors are different, we expect more.
# Not intuitive; not even guaranteed to hold in future
# releases; but this matches the compiler's behavior in Python
# 1.4 and 1.5.
err = err1 = err2 = None
code = code1 = code2 = None
# quickly get out of here when the line is 'empty' or is a comment
stripped = string.strip(self._pybuf)
if not stripped or stripped[0] == '#':
self._pybuf = ''
sys.stdout.write(sys.ps1)
sys.stdout.flush()
return
try:
code = compile(self._pybuf, "<input>", "single")
except SyntaxError, err:
pass
except:
# OverflowError. More?
print_exc()
self._pybuf = ""
sys.stdout.write(sys.ps1)
sys.stdout.flush()
return
try:
code1 = compile(self._pybuf + "\n", "<input>", "single")
except SyntaxError, err1:
pass
try:
code2 = compile(self._pybuf + "\n\n", "<input>", "single")
except SyntaxError, err2:
pass
if code:
try:
exec code in env
except:
print_exc()
self._pybuf = ""
elif code1:
pass
elif err1 == err2 or (not stuff and self._pybuf):
print_exc()
self._pybuf = ""
if self._pybuf:
sys.stdout.write(sys.ps2)
sys.stdout.flush()
else:
sys.stdout.write(sys.ps1)
sys.stdout.flush()
finally:
if out:
sys.stderr, sys.stdout = saveerr, saveout
|