blob: d0ff4bf2bd16fa3dc98a63e198135c0d63a49cd6 [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:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000035 code = compile(source, filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000036 except SyntaxError, err:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000037 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000038
39 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000040 code1 = compile(source + "\n", filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000041 except SyntaxError, err1:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000042 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000043
44 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000045 code2 = compile(source + "\n\n", filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000046 except SyntaxError, err2:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000047 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000048
49 if code:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000050 return code
Guido van Rossum86871641998-01-14 15:40:30 +000051 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000052 e1 = err1.__dict__
Guido van Rossum86871641998-01-14 15:40:30 +000053 except AttributeError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000054 e1 = err1
Guido van Rossum86871641998-01-14 15:40:30 +000055 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000056 e2 = err2.__dict__
Guido van Rossum86871641998-01-14 15:40:30 +000057 except AttributeError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000058 e2 = err2
Guido van Rossum86871641998-01-14 15:40:30 +000059 if not code1 and e1 == e2:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +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:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000073 print banner
Guido van Rossum90981e01997-10-07 14:47:24 +000074 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000075 print "Python Interactive Console", sys.version
76 print sys.copyright
Guido van Rossum90981e01997-10-07 14:47:24 +000077 buf = []
78 while 1:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000079 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
Guido van Rossum90981e01997-10-07 14:47:24 +0000109if __name__ == '__main__':
110 interact()