History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/lib/python/code.py (1 of 3706 files). Show all

Unified · Split

sys/lib/python/code.py+307−0
@@ -0,0 +1,307 @@
1+"""Utilities needed to emulate Python's interactive interpreter.
2+
3+"""
4+
5+# Inspired by similar code by Jeff Epler and Fredrik Lundh.
6+
7+
8+import sys
9+import traceback
10+from codeop import CommandCompiler, compile_command
11+
12+__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
13+ "compile_command"]
14+
15+def softspace(file, newvalue):
16+ oldvalue = 0
17+ try:
18+ oldvalue = file.softspace
19+ except AttributeError:
20+ pass
21+ try:
22+ file.softspace = newvalue
23+ except (AttributeError, TypeError):
24+ # "attribute-less object" or "read-only attributes"
25+ pass
26+ return oldvalue
27+
28+class InteractiveInterpreter:
29+ """Base class for InteractiveConsole.
30+
31+ This class deals with parsing and interpreter state (the user's
32+ namespace); it doesn't deal with input buffering or prompting or
33+ input file naming (the filename is always passed in explicitly).
34+
35+ """
36+
37+ def __init__(self, locals=None):
38+ """Constructor.
39+
40+ The optional 'locals' argument specifies the dictionary in
41+ which code will be executed; it defaults to a newly created
42+ dictionary with key "__name__" set to "__console__" and key
43+ "__doc__" set to None.
44+
45+ """
46+ if locals is None:
47+ locals = {"__name__": "__console__", "__doc__": None}
48+ self.locals = locals
49+ self.compile = CommandCompiler()
50+
51+ def runsource(self, source, filename="<input>", symbol="single"):
52+ """Compile and run some source in the interpreter.
53+
54+ Arguments are as for compile_command().
55+
56+ One several things can happen:
57+
58+ 1) The input is incorrect; compile_command() raised an
59+ exception (SyntaxError or OverflowError). A syntax traceback
60+ will be printed by calling the showsyntaxerror() method.
61+
62+ 2) The input is incomplete, and more input is required;
63+ compile_command() returned None. Nothing happens.
64+
65+ 3) The input is complete; compile_command() returned a code
66+ object. The code is executed by calling self.runcode() (which
67+ also handles run-time exceptions, except for SystemExit).
68+
69+ The return value is True in case 2, False in the other cases (unless
70+ an exception is raised). The return value can be used to
71+ decide whether to use sys.ps1 or sys.ps2 to prompt the next
72+ line.
73+
74+ """
75+ try:
76+ code = self.compile(source, filename, symbol)
77+ except (OverflowError, SyntaxError, ValueError):
78+ # Case 1
79+ self.showsyntaxerror(filename)
80+ return False
81+
82+ if code is None:
83+ # Case 2
84+ return True
85+
86+ # Case 3
87+ self.runcode(code)
88+ return False
89+
90+ def runcode(self, code):
91+ """Execute a code object.
92+
93+ When an exception occurs, self.showtraceback() is called to
94+ display a traceback. All exceptions are caught except
95+ SystemExit, which is reraised.
96+
97+ A note about KeyboardInterrupt: this exception may occur
98+ elsewhere in this code, and may not always be caught. The
99+ caller should be prepared to deal with it.
100+
101+ """
102+ try:
103+ exec code in self.locals
104+ except SystemExit:
105+ raise
106+ except:
107+ self.showtraceback()
108+ else:
109+ if softspace(sys.stdout, 0):
110+ print
111+
112+ def showsyntaxerror(self, filename=None):
113+ """Display the syntax error that just occurred.
114+
115+ This doesn't display a stack trace because there isn't one.
116+
117+ If a filename is given, it is stuffed in the exception instead
118+ of what was there before (because Python's parser always uses
119+ "<string>" when reading from a string).
120+
121+ The output is written by self.write(), below.
122+
123+ """
124+ type, value, sys.last_traceback = sys.exc_info()
125+ sys.last_type = type
126+ sys.last_value = value
127+ if filename and type is SyntaxError:
128+ # Work hard to stuff the correct filename in the exception
129+ try:
130+ msg, (dummy_filename, lineno, offset, line) = value
131+ except:
132+ # Not the format we expect; leave it alone
133+ pass
134+ else:
135+ # Stuff in the right filename
136+ value = SyntaxError(msg, (filename, lineno, offset, line))
137+ sys.last_value = value
138+ list = traceback.format_exception_only(type, value)
139+ map(self.write, list)
140+
141+ def showtraceback(self):
142+ """Display the exception that just occurred.
143+
144+ We remove the first stack item because it is our own code.
145+
146+ The output is written by self.write(), below.
147+
148+ """
149+ try:
150+ type, value, tb = sys.exc_info()
151+ sys.last_type = type
152+ sys.last_value = value
153+ sys.last_traceback = tb
154+ tblist = traceback.extract_tb(tb)
155+ del tblist[:1]
156+ list = traceback.format_list(tblist)
157+ if list:
158+ list.insert(0, "Traceback (most recent call last):\n")
159+ list[len(list):] = traceback.format_exception_only(type, value)
160+ finally:
161+ tblist = tb = None
162+ map(self.write, list)
163+
164+ def write(self, data):
165+ """Write a string.
166+
167+ The base implementation writes to sys.stderr; a subclass may
168+ replace this with a different implementation.
169+
170+ """
171+ sys.stderr.write(data)
172+
173+
174+class InteractiveConsole(InteractiveInterpreter):
175+ """Closely emulate the behavior of the interactive Python interpreter.
176+
177+ This class builds on InteractiveInterpreter and adds prompting
178+ using the familiar sys.ps1 and sys.ps2, and input buffering.
179+
180+ """
181+
182+ def __init__(self, locals=None, filename="<console>"):
183+ """Constructor.
184+
185+ The optional locals argument will be passed to the
186+ InteractiveInterpreter base class.
187+
188+ The optional filename argument should specify the (file)name
189+ of the input stream; it will show up in tracebacks.
190+
191+ """
192+ InteractiveInterpreter.__init__(self, locals)
193+ self.filename = filename
194+ self.resetbuffer()
195+
196+ def resetbuffer(self):
197+ """Reset the input buffer."""
198+ self.buffer = []
199+
200+ def interact(self, banner=None):
201+ """Closely emulate the interactive Python console.
202+
203+ The optional banner argument specify the banner to print
204+ before the first interaction; by default it prints a banner
205+ similar to the one printed by the real Python interpreter,
206+ followed by the current class name in parentheses (so as not
207+ to confuse this with the real interpreter -- since it's so
208+ close!).
209+
210+ """
211+ try:
212+ sys.ps1
213+ except AttributeError:
214+ sys.ps1 = ">>> "
215+ try:
216+ sys.ps2
217+ except AttributeError:
218+ sys.ps2 = "... "
219+ cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
220+ if banner is None:
221+ self.write("Python %s on %s\n%s\n(%s)\n" %
222+ (sys.version, sys.platform, cprt,
223+ self.__class__.__name__))
224+ else:
225+ self.write("%s\n" % str(banner))
226+ more = 0
227+ while 1:
228+ try:
229+ if more:
230+ prompt = sys.ps2
231+ else:
232+ prompt = sys.ps1
233+ try:
234+ line = self.raw_input(prompt)
235+ except EOFError:
236+ self.write("\n")
237+ break
238+ else:
239+ more = self.push(line)
240+ except KeyboardInterrupt:
241+ self.write("\nKeyboardInterrupt\n")
242+ self.resetbuffer()
243+ more = 0
244+
245+ def push(self, line):
246+ """Push a line to the interpreter.
247+
248+ The line should not have a trailing newline; it may have
249+ internal newlines. The line is appended to a buffer and the
250+ interpreter's runsource() method is called with the
251+ concatenated contents of the buffer as source. If this
252+ indicates that the command was executed or invalid, the buffer
253+ is reset; otherwise, the command is incomplete, and the buffer
254+ is left as it was after the line was appended. The return
255+ value is 1 if more input is required, 0 if the line was dealt
256+ with in some way (this is the same as runsource()).
257+
258+ """
259+ self.buffer.append(line)
260+ source = "\n".join(self.buffer)
261+ more = self.runsource(source, self.filename)
262+ if not more:
263+ self.resetbuffer()
264+ return more
265+
266+ def raw_input(self, prompt=""):
267+ """Write a prompt and read a line.
268+
269+ The returned line does not include the trailing newline.
270+ When the user enters the EOF key sequence, EOFError is raised.
271+
272+ The base implementation uses the built-in function
273+ raw_input(); a subclass may replace this with a different
274+ implementation.
275+
276+ """
277+ return raw_input(prompt)
278+
279+
280+def interact(banner=None, readfunc=None, local=None):
281+ """Closely emulate the interactive Python interpreter.
282+
283+ This is a backwards compatible interface to the InteractiveConsole
284+ class. When readfunc is not specified, it attempts to import the
285+ readline module to enable GNU readline if it is available.
286+
287+ Arguments (all optional, all default to None):
288+
289+ banner -- passed to InteractiveConsole.interact()
290+ readfunc -- if not None, replaces InteractiveConsole.raw_input()
291+ local -- passed to InteractiveInterpreter.__init__()
292+
293+ """
294+ console = InteractiveConsole(local)
295+ if readfunc is not None:
296+ console.raw_input = readfunc
297+ else:
298+ try:
299+ import readline
300+ except ImportError:
301+ pass
302+ console.interact(banner)
303+
304+
305+if __name__ == '__main__':
306+ import pdb
307+ pdb.run("interact()\n")