]>
Commit | Line | Data |
---|---|---|
d14a1e28 | 1 | """Interpreter executes Python commands.""" |
1fded56b | 2 | |
d14a1e28 RD |
3 | __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" |
4 | __cvsid__ = "$Id$" | |
5 | __revision__ = "$Revision$"[11:-2] | |
1fded56b | 6 | |
d14a1e28 RD |
7 | import os |
8 | import sys | |
9 | from code import InteractiveInterpreter | |
10 | import dispatcher | |
11 | import introspect | |
1fed7eda | 12 | import wx |
d14a1e28 RD |
13 | |
14 | class Interpreter(InteractiveInterpreter): | |
15 | """Interpreter based on code.InteractiveInterpreter.""" | |
16 | ||
17 | revision = __revision__ | |
18 | ||
19 | def __init__(self, locals=None, rawin=None, | |
61071e61 RD |
20 | stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, |
21 | showInterpIntro=True): | |
d14a1e28 RD |
22 | """Create an interactive interpreter object.""" |
23 | InteractiveInterpreter.__init__(self, locals=locals) | |
24 | self.stdin = stdin | |
25 | self.stdout = stdout | |
26 | self.stderr = stderr | |
27 | if rawin: | |
28 | import __builtin__ | |
29 | __builtin__.raw_input = rawin | |
30 | del __builtin__ | |
61071e61 RD |
31 | if showInterpIntro: |
32 | copyright = 'Type "help", "copyright", "credits" or "license"' | |
33 | copyright += ' for more information.' | |
34 | self.introText = 'Python %s on %s%s%s' % \ | |
35 | (sys.version, sys.platform, os.linesep, copyright) | |
d14a1e28 RD |
36 | try: |
37 | sys.ps1 | |
38 | except AttributeError: | |
39 | sys.ps1 = '>>> ' | |
40 | try: | |
41 | sys.ps2 | |
42 | except AttributeError: | |
43 | sys.ps2 = '... ' | |
44 | self.more = 0 | |
45 | # List of lists to support recursive push(). | |
46 | self.commandBuffer = [] | |
02b800ce RD |
47 | self.startupScript = None |
48 | ||
d14a1e28 RD |
49 | |
50 | def push(self, command): | |
51 | """Send command to the interpreter to be executed. | |
52 | ||
53 | Because this may be called recursively, we append a new list | |
54 | onto the commandBuffer list and then append commands into | |
55 | that. If the passed in command is part of a multi-line | |
56 | command we keep appending the pieces to the last list in | |
57 | commandBuffer until we have a complete command. If not, we | |
58 | delete that last list.""" | |
1fed7eda RD |
59 | |
60 | # In case the command is unicode try encoding it | |
61 | if type(command) == unicode: | |
62 | try: | |
63 | command = command.encode(wx.GetDefaultPyEncoding()) | |
64 | except UnicodeEncodeError: | |
65 | pass # otherwise leave it alone | |
66 | ||
d14a1e28 RD |
67 | if not self.more: |
68 | try: del self.commandBuffer[-1] | |
69 | except IndexError: pass | |
70 | if not self.more: self.commandBuffer.append([]) | |
71 | self.commandBuffer[-1].append(command) | |
72 | source = '\n'.join(self.commandBuffer[-1]) | |
73 | more = self.more = self.runsource(source) | |
74 | dispatcher.send(signal='Interpreter.push', sender=self, | |
75 | command=command, more=more, source=source) | |
76 | return more | |
77 | ||
78 | def runsource(self, source): | |
79 | """Compile and run source code in the interpreter.""" | |
80 | stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr | |
81 | sys.stdin, sys.stdout, sys.stderr = \ | |
82 | self.stdin, self.stdout, self.stderr | |
83 | more = InteractiveInterpreter.runsource(self, source) | |
84 | # If sys.std* is still what we set it to, then restore it. | |
85 | # But, if the executed source changed sys.std*, assume it was | |
86 | # meant to be changed and leave it. Power to the people. | |
87 | if sys.stdin == self.stdin: | |
88 | sys.stdin = stdin | |
89 | if sys.stdout == self.stdout: | |
90 | sys.stdout = stdout | |
91 | if sys.stderr == self.stderr: | |
92 | sys.stderr = stderr | |
93 | return more | |
94 | ||
95 | def getAutoCompleteKeys(self): | |
96 | """Return list of auto-completion keycodes.""" | |
97 | return [ord('.')] | |
98 | ||
99 | def getAutoCompleteList(self, command='', *args, **kwds): | |
100 | """Return list of auto-completion options for a command. | |
101 | ||
102 | The list of options will be based on the locals namespace.""" | |
103 | stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr | |
104 | sys.stdin, sys.stdout, sys.stderr = \ | |
105 | self.stdin, self.stdout, self.stderr | |
106 | l = introspect.getAutoCompleteList(command, self.locals, | |
107 | *args, **kwds) | |
108 | sys.stdin, sys.stdout, sys.stderr = stdin, stdout, stderr | |
109 | return l | |
110 | ||
111 | def getCallTip(self, command='', *args, **kwds): | |
112 | """Return call tip text for a command. | |
113 | ||
114 | Call tip information will be based on the locals namespace.""" | |
115 | return introspect.getCallTip(command, self.locals, *args, **kwds) | |
116 | ||
117 | ||
118 | class InterpreterAlaCarte(Interpreter): | |
119 | """Demo Interpreter.""" | |
120 | ||
121 | def __init__(self, locals, rawin, stdin, stdout, stderr, | |
122 | ps1='main prompt', ps2='continuation prompt'): | |
123 | """Create an interactive interpreter object.""" | |
124 | Interpreter.__init__(self, locals=locals, rawin=rawin, | |
125 | stdin=stdin, stdout=stdout, stderr=stderr) | |
126 | sys.ps1 = ps1 | |
127 | sys.ps2 = ps2 | |
128 | ||
129 |