blob: 3554b35de9798dbbe375759f43b8e5eec689ea07 [file] [log] [blame]
Guido van Rossum5227f0f1998-09-22 20:38:53 +00001"""Utilities dealing with code objects.
2
3Inspired by similar code by Jeff Epler and Fredrik Lundh.
4"""
Guido van Rossum1557a731997-07-18 16:57:52 +00005
Guido van Rossuma93b8481998-06-23 19:31:19 +00006import sys
7import string
8import traceback
9
Guido van Rossum1557a731997-07-18 16:57:52 +000010def compile_command(source, filename="<input>", symbol="single"):
11 r"""Compile a command and determine whether it is incomplete.
12
13 Arguments:
14
15 source -- the source string; may contain \n characters
16 filename -- optional filename from which source was read; default "<input>"
17 symbol -- optional grammar start symbol; "single" (default) or "eval"
18
Guido van Rossum5227f0f1998-09-22 20:38:53 +000019 Return value / exceptions raised:
Guido van Rossum1557a731997-07-18 16:57:52 +000020
21 - Return a code object if the command is complete and valid
22 - Return None if the command is incomplete
Guido van Rossum5227f0f1998-09-22 20:38:53 +000023 - Raise SyntaxError or OverflowError if the command is a syntax error
24 (OverflowError if the error is in a numeric constant)
Guido van Rossum1557a731997-07-18 16:57:52 +000025
26 Approach:
Guido van Rossum5227f0f1998-09-22 20:38:53 +000027
28 First, check if the source consists entirely of blank lines and
29 comments; if so, replace it with 'pass', because the built-in
30 parser doesn't always do the right thing for these.
31
Guido van Rossum1557a731997-07-18 16:57:52 +000032 Compile three times: as is, with \n, and with \n\n appended. If
33 it compiles as is, it's complete. If it compiles with one \n
34 appended, we expect more. If it doesn't compile either way, we
35 compare the error we get when compiling with \n or \n\n appended.
36 If the errors are the same, the code is broken. But if the errors
37 are different, we expect more. Not intuitive; not even guaranteed
38 to hold in future releases; but this matches the compiler's
Guido van Rossum5227f0f1998-09-22 20:38:53 +000039 behavior from Python 1.4 through 1.5.2, at least.
40
41 Caveat:
42
43 It is possible (but not likely) that the parser stops parsing
44 with a successful outcome before reaching the end of the source;
45 in this case, trailing symbols may be ignored instead of causing an
46 error. For example, a backslash followed by two newlines may be
47 followed by arbitrary garbage. This will be fixed once the API
48 for the parser is better.
Guido van Rossum1557a731997-07-18 16:57:52 +000049
50 """
51
Guido van Rossum5227f0f1998-09-22 20:38:53 +000052 # Check for source consisting of only blank lines and comments
53 for line in string.split(source, "\n"):
54 line = string.strip(line)
55 if line and line[0] != '#':
56 break # Leave it alone
57 else:
58 source = "pass" # Replace it with a 'pass' statement
59
Guido van Rossum1557a731997-07-18 16:57:52 +000060 err = err1 = err2 = None
61 code = code1 = code2 = None
62
63 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000064 code = compile(source, filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000065 except SyntaxError, err:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000066 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000067
68 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000069 code1 = compile(source + "\n", filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000070 except SyntaxError, err1:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000071 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000072
73 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000074 code2 = compile(source + "\n\n", filename, symbol)
Guido van Rossum1557a731997-07-18 16:57:52 +000075 except SyntaxError, err2:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000076 pass
Guido van Rossum1557a731997-07-18 16:57:52 +000077
78 if code:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000079 return code
Guido van Rossum86871641998-01-14 15:40:30 +000080 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 e1 = err1.__dict__
Guido van Rossum86871641998-01-14 15:40:30 +000082 except AttributeError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000083 e1 = err1
Guido van Rossum86871641998-01-14 15:40:30 +000084 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000085 e2 = err2.__dict__
Guido van Rossum86871641998-01-14 15:40:30 +000086 except AttributeError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 e2 = err2
Guido van Rossum86871641998-01-14 15:40:30 +000088 if not code1 and e1 == e2:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000089 raise SyntaxError, err1
Guido van Rossum90981e01997-10-07 14:47:24 +000090
91
Guido van Rossum5227f0f1998-09-22 20:38:53 +000092class InteractiveInterpreter:
93 """Base class for InteractiveConsole.
Guido van Rossuma93b8481998-06-23 19:31:19 +000094
Guido van Rossum5227f0f1998-09-22 20:38:53 +000095 This class deals with parsing and interpreter state (the user's
96 namespace); it doesn't deal with input buffering or prompting or
97 input file naming (the filename is always passed in explicitly).
98
Guido van Rossuma93b8481998-06-23 19:31:19 +000099 """
100
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000101 def __init__(self, locals=None):
Guido van Rossuma93b8481998-06-23 19:31:19 +0000102 """Constructor.
103
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000104 The optional 'locals' argument specifies the dictionary in
105 which code will be executed; it defaults to a newly created
106 dictionary with key "__name__" set to "__console__" and key
107 "__doc__" set to None.
Guido van Rossuma93b8481998-06-23 19:31:19 +0000108
109 """
Guido van Rossuma93b8481998-06-23 19:31:19 +0000110 if locals is None:
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000111 locals = {"__name__": "__console__", "__doc__": None}
Guido van Rossuma93b8481998-06-23 19:31:19 +0000112 self.locals = locals
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000113
114 def runsource(self, source, filename="<input>", symbol="single"):
115 """Compile and run some source in the interpreter.
116
117 Arguments are as for compile_command().
118
119 One several things can happen:
120
121 1) The input is incorrect; compile_command() raised an
122 exception (SyntaxError or OverflowError). A syntax traceback
123 will be printed by calling the showsyntaxerror() method.
124
125 2) The input is incomplete, and more input is required;
126 compile_command() returned None. Nothing happens.
127
128 3) The input is complete; compile_command() returned a code
129 object. The code is executed by calling self.runcode() (which
130 also handles run-time exceptions, except for SystemExit).
131
132 The return value is 1 in case 2, 0 in the other cases (unless
133 an exception is raised). The return value can be used to
134 decide whether to use sys.ps1 or sys.ps2 to prompt the next
135 line.
136
137 """
138 try:
139 code = compile_command(source, filename, symbol)
140 except (OverflowError, SyntaxError):
141 # Case 1
142 self.showsyntaxerror(filename)
143 return 0
144
145 if code is None:
146 # Case 2
147 return 1
148
149 # Case 3
150 self.runcode(code)
151 return 0
152
153 def runcode(self, code):
154 """Execute a code object.
155
156 When an exception occurs, self.showtraceback() is called to
157 display a traceback. All exceptions are caught except
158 SystemExit, which is reraised.
159
160 A note about KeyboardInterrupt: this exception may occur
161 elsewhere in this code, and may not always be caught. The
162 caller should be prepared to deal with it.
163
164 """
165 try:
166 exec code in self.locals
167 except SystemExit:
168 raise
169 except:
170 self.showtraceback()
171
172 def showsyntaxerror(self, filename=None):
173 """Display the syntax error that just occurred.
174
175 This doesn't display a stack trace because there isn't one.
176
177 If a filename is given, it is stuffed in the exception instead
178 of what was there before (because Python's parser always uses
179 "<string>" when reading from a string).
180
181 The output is written by self.write(), below.
182
183 """
184 type, value, sys.last_traceback = sys.exc_info()
185 sys.last_type = type
186 sys.last_value = value
187 if filename and type is SyntaxError:
188 # Work hard to stuff the correct filename in the exception
189 try:
190 msg, (dummy_filename, lineno, offset, line) = value
191 except:
192 # Not the format we expect; leave it alone
193 pass
194 else:
195 # Stuff in the right filename
196 try:
197 # Assume SyntaxError is a class exception
198 value = SyntaxError(msg, (filename, lineno, offset, line))
199 except:
200 # If that failed, assume SyntaxError is a string
201 value = msg, (filename, lineno, offset, line)
202 list = traceback.format_exception_only(type, value)
203 map(self.write, list)
204
205 def showtraceback(self):
206 """Display the exception that just occurred.
207
208 We remove the first stack item because it is our own code.
209
210 The output is written by self.write(), below.
211
212 """
213 try:
214 type, value, tb = sys.exc_info()
215 sys.last_type = type
216 sys.last_value = value
217 sys.last_traceback = tb
218 tblist = traceback.extract_tb(tb)
219 del tblist[:1]
220 list = traceback.format_list(tblist)
221 if list:
222 list.insert(0, "Traceback (innermost last):\n")
223 list[len(list):] = traceback.format_exception_only(type, value)
224 finally:
225 tblist = tb = None
226 map(self.write, list)
227
228 def write(self, data):
229 """Write a string.
230
231 The base implementation writes to sys.stderr; a subclass may
232 replace this with a different implementation.
233
234 """
235 sys.stderr.write(data)
236
237
238class InteractiveConsole(InteractiveInterpreter):
239 """Closely emulate the behavior of the interactive Python interpreter.
240
241 This class builds on InteractiveInterpreter and adds prompting
242 using the familiar sys.ps1 and sys.ps2, and input buffering.
243
244 """
245
246 def __init__(self, locals=None, filename="<console>"):
247 """Constructor.
248
249 The optional locals argument will be passed to the
250 InteractiveInterpreter base class.
251
252 The optional filename argument should specify the (file)name
253 of the input stream; it will show up in tracebacks.
254
255 """
256 InteractiveInterpreter.__init__(self, locals)
257 self.filename = filename
Guido van Rossuma93b8481998-06-23 19:31:19 +0000258 self.resetbuffer()
259
260 def resetbuffer(self):
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000261 """Reset the input buffer."""
Guido van Rossuma93b8481998-06-23 19:31:19 +0000262 self.buffer = []
263
264 def interact(self, banner=None):
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000265 """Closely emulate the interactive Python console.
266
267 The optional banner argument specify the banner to print
268 before the first interaction; by default it prints a banner
269 similar to the one printed by the real Python interpreter,
270 followed by the current class name in parentheses (so as not
271 to confuse this with the real interpreter -- since it's so
272 close!).
273
274 """
Guido van Rossuma93b8481998-06-23 19:31:19 +0000275 try:
276 sys.ps1
277 except AttributeError:
278 sys.ps1 = ">>> "
279 try:
280 sys.ps2
281 except AttributeError:
282 sys.ps2 = "... "
283 if banner is None:
284 self.write("Python %s on %s\n%s\n(%s)\n" %
285 (sys.version, sys.platform, sys.copyright,
286 self.__class__.__name__))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000287 else:
Guido van Rossuma93b8481998-06-23 19:31:19 +0000288 self.write("%s\n" % str(banner))
289 more = 0
290 while 1:
291 try:
292 if more:
293 prompt = sys.ps2
294 else:
295 prompt = sys.ps1
296 try:
297 line = self.raw_input(prompt)
298 except EOFError:
299 self.write("\n")
300 break
301 else:
302 more = self.push(line)
303 except KeyboardInterrupt:
304 self.write("\nKeyboardInterrupt\n")
305 self.resetbuffer()
306 more = 0
307
308 def push(self, line):
309 """Push a line to the interpreter.
310
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000311 The line should not have a trailing newline; it may have
312 internal newlines. The line is appended to a buffer and the
313 interpreter's runsource() method is called with the
314 concatenated contents of the buffer as source. If this
315 indicates that the command was executed or invalid, the buffer
316 is reset; otherwise, the command is incomplete, and the buffer
317 is left as it was after the line was appended. The return
318 value is 1 if more input is required, 0 if the line was dealt
319 with in some way (this is the same as runsource()).
Guido van Rossuma93b8481998-06-23 19:31:19 +0000320
321 """
322 self.buffer.append(line)
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000323 source = string.join(self.buffer, "\n")
324 more = self.runsource(source, self.filename)
325 if not more:
Guido van Rossuma93b8481998-06-23 19:31:19 +0000326 self.resetbuffer()
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000327 return more
Guido van Rossuma93b8481998-06-23 19:31:19 +0000328
329 def raw_input(self, prompt=""):
330 """Write a prompt and read a line.
331
332 The returned line does not include the trailing newline.
333 When the user enters the EOF key sequence, EOFError is raised.
334
335 The base implementation uses the built-in function
336 raw_input(); a subclass may replace this with a different
337 implementation.
338
339 """
340 return raw_input(prompt)
341
342
343def interact(banner=None, readfunc=None, locals=None):
344 """Closely emulate the interactive Python interpreter.
345
346 This is a backwards compatible interface to the InteractiveConsole
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000347 class. When readfunc is not specified, it attempts to import the
348 readline module to enable GNU readline if it is available.
Guido van Rossuma93b8481998-06-23 19:31:19 +0000349
350 Arguments (all optional, all default to None):
351
352 banner -- passed to InteractiveConsole.interact()
353 readfunc -- if not None, replaces InteractiveConsole.raw_input()
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000354 locals -- passed to InteractiveInterpreter.__init__()
Guido van Rossuma93b8481998-06-23 19:31:19 +0000355
356 """
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000357 console = InteractiveConsole(locals)
Guido van Rossuma93b8481998-06-23 19:31:19 +0000358 if readfunc is not None:
359 console.raw_input = readfunc
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000360 else:
361 try:
362 import readline
363 except:
364 pass
Guido van Rossuma93b8481998-06-23 19:31:19 +0000365 console.interact(banner)
Guido van Rossum5227f0f1998-09-22 20:38:53 +0000366
367
Guido van Rossum90981e01997-10-07 14:47:24 +0000368if __name__ == '__main__':
369 interact()