blob: 9b40ed97b9641766dc6e3afdb9cf567c09a35a5b [file] [log] [blame]
Guido van Rossum1557a731997-07-18 16:57:52 +00001"""Utilities dealing with code objects."""
2
3def compile_command(source, filename="<input>", symbol="single"):
4 r"""Compile a command and determine whether it is incomplete.
5
6 Arguments:
7
8 source -- the source string; may contain \n characters
9 filename -- optional filename from which source was read; default "<input>"
10 symbol -- optional grammar start symbol; "single" (default) or "eval"
11
12 Return value / exception raised:
13
14 - Return a code object if the command is complete and valid
15 - Return None if the command is incomplete
16 - Raise SyntaxError if the command is a syntax error
17
18 Approach:
19
20 Compile three times: as is, with \n, and with \n\n appended. If
21 it compiles as is, it's complete. If it compiles with one \n
22 appended, we expect more. If it doesn't compile either way, we
23 compare the error we get when compiling with \n or \n\n appended.
24 If the errors are the same, the code is broken. But if the errors
25 are different, we expect more. Not intuitive; not even guaranteed
26 to hold in future releases; but this matches the compiler's
27 behavior in Python 1.4 and 1.5.
28
29 """
30
31 err = err1 = err2 = None
32 code = code1 = code2 = None
33
34 try:
35 code = compile(source, filename, symbol)
36 except SyntaxError, err:
37 pass
38
39 try:
40 code1 = compile(source + "\n", filename, symbol)
41 except SyntaxError, err1:
42 pass
43
44 try:
45 code2 = compile(source + "\n\n", filename, symbol)
46 except SyntaxError, err2:
47 pass
48
49 if code:
50 return code
Guido van Rossum86871641998-01-14 15:40:30 +000051 try:
52 e1 = err1.__dict__
53 except AttributeError:
54 e1 = err1
55 try:
56 e2 = err2.__dict__
57 except AttributeError:
58 e2 = err2
59 if not code1 and e1 == e2:
Guido van Rossum1557a731997-07-18 16:57:52 +000060 raise SyntaxError, err1
Guido van Rossum90981e01997-10-07 14:47:24 +000061
62
63def interact(banner=None, readfunc=raw_input, local=None):
64 # Due to Jeff Epler, with changes by Guido:
65 """Closely emulate the interactive Python console."""
66 try: import readline # Enable GNU readline if available
67 except: pass
68 local = local or {}
69 import sys, string, traceback
70 sys.ps1 = '>>> '
71 sys.ps2 = '... '
72 if banner:
73 print banner
74 else:
75 print "Python Interactive Console", sys.version
76 print sys.copyright
77 buf = []
78 while 1:
79 if buf: prompt = sys.ps2
80 else: prompt = sys.ps1
81 try: line = readfunc(prompt)
82 except KeyboardInterrupt:
83 print "\nKeyboardInterrupt"
84 buf = []
85 continue
86 except EOFError: break
87 buf.append(line)
88 try: x = compile_command(string.join(buf, "\n"))
89 except SyntaxError:
90 traceback.print_exc(0)
91 buf = []
92 continue
93 if x == None: continue
94 else:
95 try: exec x in local
96 except:
97 exc_type, exc_value, exc_traceback = \
98 sys.exc_type, sys.exc_value, \
99 sys.exc_traceback
100 l = len(traceback.extract_tb(sys.exc_traceback))
101 try: 1/0
102 except:
103 m = len(traceback.extract_tb(
104 sys.exc_traceback))
105 traceback.print_exception(exc_type,
106 exc_value, exc_traceback, l-m)
107 buf = []
108
109if __name__ == '__main__':
110 interact()