ยปCore Development>Code coverage>Lib/code.py

Python code coverage for Lib/code.py

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