Show More
@@ -0,0 +1,26 b'' | |||
|
1 | # encoding: utf-8 | |
|
2 | ||
|
3 | """This file contains unittests for the interpreter.py module.""" | |
|
4 | ||
|
5 | __docformat__ = "restructuredtext en" | |
|
6 | ||
|
7 | #----------------------------------------------------------------------------- | |
|
8 | # Copyright (C) 2008 The IPython Development Team | |
|
9 | # | |
|
10 | # Distributed under the terms of the BSD License. The full license is in | |
|
11 | # the file COPYING, distributed as part of this software. | |
|
12 | #----------------------------------------------------------------------------- | |
|
13 | ||
|
14 | #----------------------------------------------------------------------------- | |
|
15 | # Imports | |
|
16 | #----------------------------------------------------------------------------- | |
|
17 | ||
|
18 | from IPython.kernel.core.interpreter import Interpreter | |
|
19 | ||
|
20 | def test_unicode(): | |
|
21 | """ Test unicode handling with the interpreter. | |
|
22 | """ | |
|
23 | i = Interpreter() | |
|
24 | i.execute_python(u'print "ù"') | |
|
25 | i.execute_python('print "ù"') | |
|
26 |
@@ -50,7 +50,6 b' import subprocess' | |||
|
50 | 50 | from subprocess import PIPE |
|
51 | 51 | import sys |
|
52 | 52 | import os |
|
53 | import time | |
|
54 | 53 | import types |
|
55 | 54 | |
|
56 | 55 | try: |
@@ -69,7 +68,15 b' except ImportError:' | |||
|
69 | 68 | |
|
70 | 69 | mswindows = (sys.platform == "win32") |
|
71 | 70 | |
|
71 | skip = False | |
|
72 | ||
|
72 | 73 | if mswindows: |
|
74 | import platform | |
|
75 | if platform.uname()[3] == '' or platform.uname()[3] > '6.0.6000': | |
|
76 | # Killable process does not work under vista when starting for | |
|
77 | # something else than cmd. | |
|
78 | skip = True | |
|
79 | else: | |
|
73 | 80 | import winprocess |
|
74 | 81 | else: |
|
75 | 82 | import signal |
@@ -78,6 +85,10 b' if not mswindows:' | |||
|
78 | 85 | def DoNothing(*args): |
|
79 | 86 | pass |
|
80 | 87 | |
|
88 | ||
|
89 | if skip: | |
|
90 | Popen = subprocess.Popen | |
|
91 | else: | |
|
81 | 92 | class Popen(subprocess.Popen): |
|
82 | 93 | if not mswindows: |
|
83 | 94 | # Override __init__ to set a preexec_fn |
@@ -50,7 +50,7 b' class PipedProcess(Thread):' | |||
|
50 | 50 | """ |
|
51 | 51 | env = os.environ |
|
52 | 52 | env['TERM'] = 'xterm' |
|
53 |
process = Popen |
|
|
53 | process = Popen(self.command_string + ' 2>&1', shell=True, | |
|
54 | 54 | env=env, |
|
55 | 55 | universal_newlines=True, |
|
56 | 56 | stdout=PIPE, stdin=PIPE, ) |
@@ -20,6 +20,8 b' import re' | |||
|
20 | 20 | |
|
21 | 21 | import IPython |
|
22 | 22 | import sys |
|
23 | import codeop | |
|
24 | import traceback | |
|
23 | 25 | |
|
24 | 26 | from frontendbase import FrontEndBase |
|
25 | 27 | from IPython.kernel.core.interpreter import Interpreter |
@@ -76,6 +78,11 b' class LineFrontEndBase(FrontEndBase):' | |||
|
76 | 78 | |
|
77 | 79 | if banner is not None: |
|
78 | 80 | self.banner = banner |
|
81 | ||
|
82 | def start(self): | |
|
83 | """ Put the frontend in a state where it is ready for user | |
|
84 | interaction. | |
|
85 | """ | |
|
79 | 86 | if self.banner is not None: |
|
80 | 87 | self.write(self.banner, refresh=False) |
|
81 | 88 | |
@@ -141,9 +148,18 b' class LineFrontEndBase(FrontEndBase):' | |||
|
141 | 148 | and not re.findall(r"\n[\t ]*\n[\t ]*$", string)): |
|
142 | 149 | return False |
|
143 | 150 | else: |
|
151 | self.capture_output() | |
|
152 | try: | |
|
144 | 153 | # Add line returns here, to make sure that the statement is |
|
145 | 154 | # complete. |
|
146 |
|
|
|
155 | is_complete = codeop.compile_command(string.rstrip() + '\n\n', | |
|
156 | "<string>", "exec") | |
|
157 | self.release_output() | |
|
158 | except Exception, e: | |
|
159 | # XXX: Hack: return True so that the | |
|
160 | # code gets executed and the error captured. | |
|
161 | is_complete = True | |
|
162 | return is_complete | |
|
147 | 163 | |
|
148 | 164 | |
|
149 | 165 | def write(self, string, refresh=True): |
@@ -181,7 +197,7 b' class LineFrontEndBase(FrontEndBase):' | |||
|
181 | 197 | #-------------------------------------------------------------------------- |
|
182 | 198 | |
|
183 | 199 | def prefilter_input(self, string): |
|
184 |
""" Pri |
|
|
200 | """ Prefilter the input to turn it in valid python. | |
|
185 | 201 | """ |
|
186 | 202 | string = string.replace('\r\n', '\n') |
|
187 | 203 | string = string.replace('\t', 4*' ') |
@@ -210,9 +226,12 b' class LineFrontEndBase(FrontEndBase):' | |||
|
210 | 226 | line = self.input_buffer |
|
211 | 227 | new_line, completions = self.complete(line) |
|
212 | 228 | if len(completions)>1: |
|
213 | self.write_completion(completions) | |
|
229 | self.write_completion(completions, new_line=new_line) | |
|
230 | elif not line == new_line: | |
|
214 | 231 | self.input_buffer = new_line |
|
215 | 232 | if self.debug: |
|
233 | print >>sys.__stdout__, 'line', line | |
|
234 | print >>sys.__stdout__, 'new_line', new_line | |
|
216 | 235 | print >>sys.__stdout__, completions |
|
217 | 236 | |
|
218 | 237 | |
@@ -222,10 +241,15 b' class LineFrontEndBase(FrontEndBase):' | |||
|
222 | 241 | return 80 |
|
223 | 242 | |
|
224 | 243 | |
|
225 | def write_completion(self, possibilities): | |
|
244 | def write_completion(self, possibilities, new_line=None): | |
|
226 | 245 | """ Write the list of possible completions. |
|
246 | ||
|
247 | new_line is the completed input line that should be displayed | |
|
248 | after the completion are writen. If None, the input_buffer | |
|
249 | before the completion is used. | |
|
227 | 250 | """ |
|
228 | current_buffer = self.input_buffer | |
|
251 | if new_line is None: | |
|
252 | new_line = self.input_buffer | |
|
229 | 253 | |
|
230 | 254 | self.write('\n') |
|
231 | 255 | max_len = len(max(possibilities, key=len)) + 1 |
@@ -246,7 +270,7 b' class LineFrontEndBase(FrontEndBase):' | |||
|
246 | 270 | self.write(''.join(buf)) |
|
247 | 271 | self.new_prompt(self.input_prompt_template.substitute( |
|
248 | 272 | number=self.last_result['number'] + 1)) |
|
249 |
self.input_buffer = |
|
|
273 | self.input_buffer = new_line | |
|
250 | 274 | |
|
251 | 275 | |
|
252 | 276 | def new_prompt(self, prompt): |
@@ -275,6 +299,8 b' class LineFrontEndBase(FrontEndBase):' | |||
|
275 | 299 | else: |
|
276 | 300 | self.input_buffer += self._get_indent_string( |
|
277 | 301 | current_buffer[:-1]) |
|
302 | if len(current_buffer.split('\n')) == 2: | |
|
303 | self.input_buffer += '\t\t' | |
|
278 | 304 | if current_buffer[:-1].split('\n')[-1].rstrip().endswith(':'): |
|
279 | 305 | self.input_buffer += '\t' |
|
280 | 306 |
@@ -24,6 +24,7 b' __docformat__ = "restructuredtext en"' | |||
|
24 | 24 | import sys |
|
25 | 25 | |
|
26 | 26 | from linefrontendbase import LineFrontEndBase, common_prefix |
|
27 | from frontendbase import FrontEndBase | |
|
27 | 28 | |
|
28 | 29 | from IPython.ipmaker import make_IPython |
|
29 | 30 | from IPython.ipapi import IPApi |
@@ -34,6 +35,7 b' from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap' | |||
|
34 | 35 | from IPython.genutils import Term |
|
35 | 36 | import pydoc |
|
36 | 37 | import os |
|
38 | import sys | |
|
37 | 39 | |
|
38 | 40 | |
|
39 | 41 | def mk_system_call(system_call_function, command): |
@@ -58,6 +60,8 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||
|
58 | 60 | completion... |
|
59 | 61 | """ |
|
60 | 62 | |
|
63 | debug = False | |
|
64 | ||
|
61 | 65 | def __init__(self, ipython0=None, *args, **kwargs): |
|
62 | 66 | """ Parameters: |
|
63 | 67 | ----------- |
@@ -65,12 +69,24 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||
|
65 | 69 | ipython0: an optional ipython0 instance to use for command |
|
66 | 70 | prefiltering and completion. |
|
67 | 71 | """ |
|
72 | LineFrontEndBase.__init__(self, *args, **kwargs) | |
|
73 | self.shell.output_trap = RedirectorOutputTrap( | |
|
74 | out_callback=self.write, | |
|
75 | err_callback=self.write, | |
|
76 | ) | |
|
77 | self.shell.traceback_trap = SyncTracebackTrap( | |
|
78 | formatters=self.shell.traceback_trap.formatters, | |
|
79 | ) | |
|
80 | ||
|
81 | # Start the ipython0 instance: | |
|
68 | 82 | self.save_output_hooks() |
|
69 | 83 | if ipython0 is None: |
|
70 | 84 | # Instanciate an IPython0 interpreter to be able to use the |
|
71 | 85 | # prefiltering. |
|
72 | 86 | # XXX: argv=[] is a bit bold. |
|
73 |
ipython0 = make_IPython(argv=[] |
|
|
87 | ipython0 = make_IPython(argv=[], | |
|
88 | user_ns=self.shell.user_ns, | |
|
89 | user_global_ns=self.shell.user_global_ns) | |
|
74 | 90 | self.ipython0 = ipython0 |
|
75 | 91 | # Set the pager: |
|
76 | 92 | self.ipython0.set_hook('show_in_pager', |
@@ -86,24 +102,13 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||
|
86 | 102 | 'ls -CF') |
|
87 | 103 | # And now clean up the mess created by ipython0 |
|
88 | 104 | self.release_output() |
|
105 | ||
|
106 | ||
|
89 | 107 | if not 'banner' in kwargs and self.banner is None: |
|
90 |
|
|
|
108 | self.banner = self.ipython0.BANNER + """ | |
|
91 | 109 | This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code.""" |
|
92 | 110 | |
|
93 | LineFrontEndBase.__init__(self, *args, **kwargs) | |
|
94 | # XXX: Hack: mix the two namespaces | |
|
95 | self.shell.user_ns.update(self.ipython0.user_ns) | |
|
96 | self.ipython0.user_ns = self.shell.user_ns | |
|
97 | self.shell.user_global_ns.update(self.ipython0.user_global_ns) | |
|
98 | self.ipython0.user_global_ns = self.shell.user_global_ns | |
|
99 | ||
|
100 | self.shell.output_trap = RedirectorOutputTrap( | |
|
101 | out_callback=self.write, | |
|
102 | err_callback=self.write, | |
|
103 | ) | |
|
104 | self.shell.traceback_trap = SyncTracebackTrap( | |
|
105 | formatters=self.shell.traceback_trap.formatters, | |
|
106 | ) | |
|
111 | self.start() | |
|
107 | 112 | |
|
108 | 113 | #-------------------------------------------------------------------------- |
|
109 | 114 | # FrontEndBase interface |
@@ -113,7 +118,7 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
113 | 118 | """ Use ipython0 to capture the last traceback and display it. |
|
114 | 119 | """ |
|
115 | 120 | self.capture_output() |
|
116 | self.ipython0.showtraceback() | |
|
121 | self.ipython0.showtraceback(tb_offset=-1) | |
|
117 | 122 | self.release_output() |
|
118 | 123 | |
|
119 | 124 | |
@@ -164,6 +169,8 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""' | |||
|
164 | 169 | |
|
165 | 170 | |
|
166 | 171 | def complete(self, line): |
|
172 | # FIXME: This should be factored out in the linefrontendbase | |
|
173 | # method. | |
|
167 | 174 | word = line.split('\n')[-1].split(' ')[-1] |
|
168 | 175 | completions = self.ipython0.complete(word) |
|
169 | 176 | # FIXME: The proper sort should be done in the complete method. |
@@ -20,8 +20,6 b' from IPython.frontend._process import PipedProcess' | |||
|
20 | 20 | from IPython.testing import decorators as testdec |
|
21 | 21 | |
|
22 | 22 | |
|
23 | # FIXME | |
|
24 | @testdec.skip("This doesn't work under Windows") | |
|
25 | 23 | def test_capture_out(): |
|
26 | 24 | """ A simple test to see if we can execute a process and get the output. |
|
27 | 25 | """ |
@@ -33,8 +31,6 b' def test_capture_out():' | |||
|
33 | 31 | assert result == '1' |
|
34 | 32 | |
|
35 | 33 | |
|
36 | # FIXME | |
|
37 | @testdec.skip("This doesn't work under Windows") | |
|
38 | 34 | def test_io(): |
|
39 | 35 | """ Checks that we can send characters on stdin to the process. |
|
40 | 36 | """ |
@@ -51,8 +47,6 b' def test_io():' | |||
|
51 | 47 | assert result == test_string |
|
52 | 48 | |
|
53 | 49 | |
|
54 | # FIXME | |
|
55 | @testdec.skip("This doesn't work under Windows") | |
|
56 | 50 | def test_kill(): |
|
57 | 51 | """ Check that we can kill a process, and its subprocess. |
|
58 | 52 | """ |
@@ -23,6 +23,7 b' import wx' | |||
|
23 | 23 | import wx.stc as stc |
|
24 | 24 | |
|
25 | 25 | from wx.py import editwindow |
|
26 | import time | |
|
26 | 27 | import sys |
|
27 | 28 | LINESEP = '\n' |
|
28 | 29 | if sys.platform == 'win32': |
@@ -115,12 +116,15 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
115 | 116 | # The color of the carret (call _apply_style() after setting) |
|
116 | 117 | carret_color = 'BLACK' |
|
117 | 118 | |
|
119 | # Store the last time a refresh was done | |
|
120 | _last_refresh_time = 0 | |
|
121 | ||
|
118 | 122 | #-------------------------------------------------------------------------- |
|
119 | 123 | # Public API |
|
120 | 124 | #-------------------------------------------------------------------------- |
|
121 | 125 | |
|
122 | 126 | def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, |
|
123 |
size=wx.DefaultSize, style= |
|
|
127 | size=wx.DefaultSize, style=wx.WANTS_CHARS, ): | |
|
124 | 128 | editwindow.EditWindow.__init__(self, parent, id, pos, size, style) |
|
125 | 129 | self._configure_scintilla() |
|
126 | 130 | |
@@ -168,9 +172,14 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
168 | 172 | |
|
169 | 173 | self.GotoPos(self.GetLength()) |
|
170 | 174 | if refresh: |
|
171 | # Maybe this is faster than wx.Yield() | |
|
172 | self.ProcessEvent(wx.PaintEvent()) | |
|
173 | #wx.Yield() | |
|
175 | current_time = time.time() | |
|
176 | if current_time - self._last_refresh_time > 0.03: | |
|
177 | if sys.platform == 'win32': | |
|
178 | wx.SafeYield() | |
|
179 | else: | |
|
180 | wx.Yield() | |
|
181 | # self.ProcessEvent(wx.PaintEvent()) | |
|
182 | self._last_refresh_time = current_time | |
|
174 | 183 | |
|
175 | 184 | |
|
176 | 185 | def new_prompt(self, prompt): |
@@ -183,7 +192,6 b' class ConsoleWidget(editwindow.EditWindow):' | |||
|
183 | 192 | # now we update our cursor giving end of prompt |
|
184 | 193 | self.current_prompt_pos = self.GetLength() |
|
185 | 194 | self.current_prompt_line = self.GetCurrentLine() |
|
186 | wx.Yield() | |
|
187 | 195 | self.EnsureCaretVisible() |
|
188 | 196 | |
|
189 | 197 |
@@ -128,6 +128,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
128 | 128 | # while it is being swapped |
|
129 | 129 | _out_buffer_lock = Lock() |
|
130 | 130 | |
|
131 | # The different line markers used to higlight the prompts. | |
|
131 | 132 | _markers = dict() |
|
132 | 133 | |
|
133 | 134 | #-------------------------------------------------------------------------- |
@@ -135,13 +136,17 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
135 | 136 | #-------------------------------------------------------------------------- |
|
136 | 137 | |
|
137 | 138 | def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, |
|
138 |
size=wx.DefaultSize, |
|
|
139 | size=wx.DefaultSize, | |
|
140 | style=wx.CLIP_CHILDREN|wx.WANTS_CHARS, | |
|
139 | 141 | *args, **kwds): |
|
140 | 142 | """ Create Shell instance. |
|
141 | 143 | """ |
|
142 | 144 | ConsoleWidget.__init__(self, parent, id, pos, size, style) |
|
143 | 145 | PrefilterFrontEnd.__init__(self, **kwds) |
|
144 | 146 | |
|
147 | # Stick in our own raw_input: | |
|
148 | self.ipython0.raw_input = self.raw_input | |
|
149 | ||
|
145 | 150 | # Marker for complete buffer. |
|
146 | 151 | self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND, |
|
147 | 152 | background=_COMPLETE_BUFFER_BG) |
@@ -164,9 +169,11 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
164 | 169 | # Inject self in namespace, for debug |
|
165 | 170 | if self.debug: |
|
166 | 171 | self.shell.user_ns['self'] = self |
|
172 | # Inject our own raw_input in namespace | |
|
173 | self.shell.user_ns['raw_input'] = self.raw_input | |
|
167 | 174 | |
|
168 | 175 | |
|
169 | def raw_input(self, prompt): | |
|
176 | def raw_input(self, prompt=''): | |
|
170 | 177 | """ A replacement from python's raw_input. |
|
171 | 178 | """ |
|
172 | 179 | self.new_prompt(prompt) |
@@ -174,15 +181,13 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
174 | 181 | if hasattr(self, '_cursor'): |
|
175 | 182 | del self._cursor |
|
176 | 183 | self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS)) |
|
177 | self.waiting = True | |
|
178 | 184 | self.__old_on_enter = self._on_enter |
|
185 | event_loop = wx.EventLoop() | |
|
179 | 186 | def my_on_enter(): |
|
180 | self.waiting = False | |
|
187 | event_loop.Exit() | |
|
181 | 188 | self._on_enter = my_on_enter |
|
182 | # XXX: Busy waiting, ugly. | |
|
183 | while self.waiting: | |
|
184 | wx.Yield() | |
|
185 | sleep(0.1) | |
|
189 | # XXX: Running a separate event_loop. Ugly. | |
|
190 | event_loop.Run() | |
|
186 | 191 | self._on_enter = self.__old_on_enter |
|
187 | 192 | self._input_state = 'buffering' |
|
188 | 193 | self._cursor = wx.BusyCursor() |
@@ -191,16 +196,18 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
191 | 196 | |
|
192 | 197 | def system_call(self, command_string): |
|
193 | 198 | self._input_state = 'subprocess' |
|
199 | event_loop = wx.EventLoop() | |
|
200 | def _end_system_call(): | |
|
201 | self._input_state = 'buffering' | |
|
202 | self._running_process = False | |
|
203 | event_loop.Exit() | |
|
204 | ||
|
194 | 205 | self._running_process = PipedProcess(command_string, |
|
195 | 206 | out_callback=self.buffered_write, |
|
196 |
end_callback = |
|
|
207 | end_callback = _end_system_call) | |
|
197 | 208 | self._running_process.start() |
|
198 | # XXX: another one of these polling loops to have a blocking | |
|
199 | # call | |
|
200 | wx.Yield() | |
|
201 | while self._running_process: | |
|
202 | wx.Yield() | |
|
203 | sleep(0.1) | |
|
209 | # XXX: Running a separate event_loop. Ugly. | |
|
210 | event_loop.Run() | |
|
204 | 211 | # Be sure to flush the buffer. |
|
205 | 212 | self._buffer_flush(event=None) |
|
206 | 213 | |
@@ -226,8 +233,9 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
226 | 233 | for name in symbol_string.split('.')[1:] + ['__doc__']: |
|
227 | 234 | symbol = getattr(symbol, name) |
|
228 | 235 | self.AutoCompCancel() |
|
229 | wx.Yield() | |
|
230 | self.CallTipShow(self.GetCurrentPos(), symbol) | |
|
236 | # Check that the symbol can indeed be converted to a string: | |
|
237 | symbol += '' | |
|
238 | wx.CallAfter(self.CallTipShow, self.GetCurrentPos(), symbol) | |
|
231 | 239 | except: |
|
232 | 240 | # The retrieve symbol couldn't be converted to a string |
|
233 | 241 | pass |
@@ -238,9 +246,9 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
238 | 246 | true, open the menu. |
|
239 | 247 | """ |
|
240 | 248 | if self.debug: |
|
241 |
print >>sys.__stdout__, "_popup_completion" |
|
|
249 | print >>sys.__stdout__, "_popup_completion" | |
|
242 | 250 | line = self.input_buffer |
|
243 | if (self.AutoCompActive() and not line[-1] == '.') \ | |
|
251 | if (self.AutoCompActive() and line and not line[-1] == '.') \ | |
|
244 | 252 | or create==True: |
|
245 | 253 | suggestion, completions = self.complete(line) |
|
246 | 254 | offset=0 |
@@ -284,19 +292,21 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
284 | 292 | if i in self._markers: |
|
285 | 293 | self.MarkerDeleteHandle(self._markers[i]) |
|
286 | 294 | self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER) |
|
287 | # Update the display: | |
|
288 | wx.Yield() | |
|
295 | # Use a callafter to update the display robustly under windows | |
|
296 | def callback(): | |
|
289 | 297 | self.GotoPos(self.GetLength()) |
|
290 |
PrefilterFrontEnd.execute(self, python_string, |
|
|
298 | PrefilterFrontEnd.execute(self, python_string, | |
|
299 | raw_string=raw_string) | |
|
300 | wx.CallAfter(callback) | |
|
291 | 301 | |
|
292 | 302 | def save_output_hooks(self): |
|
293 | 303 | self.__old_raw_input = __builtin__.raw_input |
|
294 | 304 | PrefilterFrontEnd.save_output_hooks(self) |
|
295 | 305 | |
|
296 | 306 | def capture_output(self): |
|
297 | __builtin__.raw_input = self.raw_input | |
|
298 | 307 | self.SetLexer(stc.STC_LEX_NULL) |
|
299 | 308 | PrefilterFrontEnd.capture_output(self) |
|
309 | __builtin__.raw_input = self.raw_input | |
|
300 | 310 | |
|
301 | 311 | |
|
302 | 312 | def release_output(self): |
@@ -316,7 +326,19 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
316 | 326 | def show_traceback(self): |
|
317 | 327 | start_line = self.GetCurrentLine() |
|
318 | 328 | PrefilterFrontEnd.show_traceback(self) |
|
319 | wx.Yield() | |
|
329 | self.ProcessEvent(wx.PaintEvent()) | |
|
330 | #wx.Yield() | |
|
331 | for i in range(start_line, self.GetCurrentLine()): | |
|
332 | self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER) | |
|
333 | ||
|
334 | ||
|
335 | #-------------------------------------------------------------------------- | |
|
336 | # FrontEndBase interface | |
|
337 | #-------------------------------------------------------------------------- | |
|
338 | ||
|
339 | def render_error(self, e): | |
|
340 | start_line = self.GetCurrentLine() | |
|
341 | self.write('\n' + e + '\n') | |
|
320 | 342 | for i in range(start_line, self.GetCurrentLine()): |
|
321 | 343 | self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER) |
|
322 | 344 | |
@@ -351,6 +373,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
351 | 373 | if self._input_state == 'subprocess': |
|
352 | 374 | if self.debug: |
|
353 | 375 | print >>sys.__stderr__, 'Killing running process' |
|
376 | if hasattr(self._running_process, 'process'): | |
|
354 | 377 | self._running_process.process.kill() |
|
355 | 378 | elif self._input_state == 'buffering': |
|
356 | 379 | if self.debug: |
@@ -376,7 +399,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
376 | 399 | char = '\04' |
|
377 | 400 | self._running_process.process.stdin.write(char) |
|
378 | 401 | self._running_process.process.stdin.flush() |
|
379 | elif event.KeyCode in (ord('('), 57): | |
|
402 | elif event.KeyCode in (ord('('), 57, 53): | |
|
380 | 403 | # Calltips |
|
381 | 404 | event.Skip() |
|
382 | 405 | self.do_calltip() |
@@ -410,8 +433,8 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
410 | 433 | self.input_buffer = new_buffer |
|
411 | 434 | # Tab-completion |
|
412 | 435 | elif event.KeyCode == ord('\t'): |
|
413 | last_line = self.input_buffer.split('\n')[-1] | |
|
414 |
if not re.match(r'^\s*$', |
|
|
436 | current_line, current_line_number = self.CurLine | |
|
437 | if not re.match(r'^\s*$', current_line): | |
|
415 | 438 | self.complete_current_input() |
|
416 | 439 | if self.AutoCompActive(): |
|
417 | 440 | wx.CallAfter(self._popup_completion, create=True) |
@@ -427,7 +450,7 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
427 | 450 | if event.KeyCode in (59, ord('.')): |
|
428 | 451 | # Intercepting '.' |
|
429 | 452 | event.Skip() |
|
430 |
self._popup_completion |
|
|
453 | wx.CallAfter(self._popup_completion, create=True) | |
|
431 | 454 | else: |
|
432 | 455 | ConsoleWidget._on_key_up(self, event, skip=skip) |
|
433 | 456 | |
@@ -456,13 +479,6 b' class WxController(ConsoleWidget, PrefilterFrontEnd):' | |||
|
456 | 479 | # Private API |
|
457 | 480 | #-------------------------------------------------------------------------- |
|
458 | 481 | |
|
459 | def _end_system_call(self): | |
|
460 | """ Called at the end of a system call. | |
|
461 | """ | |
|
462 | self._input_state = 'buffering' | |
|
463 | self._running_process = False | |
|
464 | ||
|
465 | ||
|
466 | 482 | def _buffer_flush(self, event): |
|
467 | 483 | """ Called by the timer to flush the write buffer. |
|
468 | 484 |
@@ -680,6 +680,13 b' class Interpreter(object):' | |||
|
680 | 680 | # how trailing whitespace is handled, but this seems to work. |
|
681 | 681 | python = python.strip() |
|
682 | 682 | |
|
683 | # The compiler module does not like unicode. We need to convert | |
|
684 | # it encode it: | |
|
685 | if isinstance(python, unicode): | |
|
686 | # Use the utf-8-sig BOM so the compiler detects this a UTF-8 | |
|
687 | # encode string. | |
|
688 | python = '\xef\xbb\xbf' + python.encode('utf-8') | |
|
689 | ||
|
683 | 690 | # The compiler module will parse the code into an abstract syntax tree. |
|
684 | 691 | ast = compiler.parse(python) |
|
685 | 692 |
@@ -1,6 +1,5 b'' | |||
|
1 | 1 | # Set this prefix to where you want to install the plugin |
|
2 |
PREFIX= |
|
|
3 | PREFIX=~/tmp/local | |
|
2 | PREFIX=/usr/local | |
|
4 | 3 | |
|
5 | 4 | NOSE0=nosetests -vs --with-doctest --doctest-tests --detailed-errors |
|
6 | 5 | NOSE=nosetests -vvs --with-ipdoctest --doctest-tests --doctest-extension=txt \ |
@@ -1,14 +1,8 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | """Wrapper to run setup.py using setuptools.""" |
|
3 | 3 | |
|
4 | import os | |
|
5 | 4 | import sys |
|
6 | 5 | |
|
7 | # Add my local path to sys.path | |
|
8 | home = os.environ['HOME'] | |
|
9 | sys.path.insert(0,'%s/usr/local/lib/python%s/site-packages' % | |
|
10 | (home,sys.version[:3])) | |
|
11 | ||
|
12 | 6 | # now, import setuptools and call the actual setup |
|
13 | 7 | import setuptools |
|
14 | 8 | # print sys.argv |
General Comments 0
You need to be logged in to leave comments.
Login now