Show More
@@ -290,10 +290,11 b' class InputSplitter(object):' | |||||
290 | isp.push(line) |
|
290 | isp.push(line) | |
291 | print 'Input source was:\n', isp.source_reset(), |
|
291 | print 'Input source was:\n', isp.source_reset(), | |
292 | """ |
|
292 | """ | |
293 | # Number of spaces of indentation computed from input that has been pushed |
|
293 | # A cache for calculating the current indentation. | |
294 | # so far. This is the attributes callers should query to get the current |
|
294 | # If the first value matches self.source, the second value is an integer | |
295 | # indentation level, in order to provide auto-indent facilities. |
|
295 | # number of spaces for the current indentation. If the first value does not | |
296 | indent_spaces = 0 |
|
296 | # match, self.source has changed, and the indentation must be recalculated. | |
|
297 | _indent_spaces_cache = None, None | |||
297 | # String, indicating the default input encoding. It is computed by default |
|
298 | # String, indicating the default input encoding. It is computed by default | |
298 | # at initialization time via get_input_encoding(), but it can be reset by a |
|
299 | # at initialization time via get_input_encoding(), but it can be reset by a | |
299 | # client with specific knowledge of the encoding. |
|
300 | # client with specific knowledge of the encoding. | |
@@ -327,7 +328,6 b' class InputSplitter(object):' | |||||
327 |
|
328 | |||
328 | def reset(self): |
|
329 | def reset(self): | |
329 | """Reset the input buffer and associated state.""" |
|
330 | """Reset the input buffer and associated state.""" | |
330 | self.indent_spaces = 0 |
|
|||
331 | self._buffer[:] = [] |
|
331 | self._buffer[:] = [] | |
332 | self.source = '' |
|
332 | self.source = '' | |
333 | self.code = None |
|
333 | self.code = None | |
@@ -371,7 +371,7 b' class InputSplitter(object):' | |||||
371 | if self._is_invalid: |
|
371 | if self._is_invalid: | |
372 | return 'invalid', None |
|
372 | return 'invalid', None | |
373 | elif self.push_accepts_more(): |
|
373 | elif self.push_accepts_more(): | |
374 | return 'incomplete', self.indent_spaces |
|
374 | return 'incomplete', self.get_indent_spaces() | |
375 | else: |
|
375 | else: | |
376 | return 'complete', None |
|
376 | return 'complete', None | |
377 | finally: |
|
377 | finally: | |
@@ -412,7 +412,6 b' class InputSplitter(object):' | |||||
412 | if source.endswith('\\\n'): |
|
412 | if source.endswith('\\\n'): | |
413 | return False |
|
413 | return False | |
414 |
|
414 | |||
415 | self._update_indent() |
|
|||
416 | try: |
|
415 | try: | |
417 | with warnings.catch_warnings(): |
|
416 | with warnings.catch_warnings(): | |
418 | warnings.simplefilter('error', SyntaxWarning) |
|
417 | warnings.simplefilter('error', SyntaxWarning) | |
@@ -470,7 +469,7 b' class InputSplitter(object):' | |||||
470 | # If there's just a single line or AST node, and we're flush left, as is |
|
469 | # If there's just a single line or AST node, and we're flush left, as is | |
471 | # the case after a simple statement such as 'a=1', we want to execute it |
|
470 | # the case after a simple statement such as 'a=1', we want to execute it | |
472 | # straight away. |
|
471 | # straight away. | |
473 | if self.indent_spaces==0: |
|
472 | if self.get_indent_spaces() == 0: | |
474 | if len(self.source.splitlines()) <= 1: |
|
473 | if len(self.source.splitlines()) <= 1: | |
475 | return False |
|
474 | return False | |
476 |
|
475 | |||
@@ -488,9 +487,15 b' class InputSplitter(object):' | |||||
488 | # General fallback - accept more code |
|
487 | # General fallback - accept more code | |
489 | return True |
|
488 | return True | |
490 |
|
489 | |||
491 |
def |
|
490 | def get_indent_spaces(self): | |
|
491 | sourcefor, n = self._indent_spaces_cache | |||
|
492 | if sourcefor == self.source: | |||
|
493 | return n | |||
|
494 | ||||
492 | # self.source always has a trailing newline |
|
495 | # self.source always has a trailing newline | |
493 |
|
|
496 | n = find_next_indent(self.source[:-1]) | |
|
497 | self._indent_spaces_cache = (self.source, n) | |||
|
498 | return n | |||
494 |
|
499 | |||
495 | def _store(self, lines, buffer=None, store='source'): |
|
500 | def _store(self, lines, buffer=None, store='source'): | |
496 | """Store one or more lines of input. |
|
501 | """Store one or more lines of input. |
@@ -1940,7 +1940,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
1940 |
|
1940 | |||
1941 | def _indent_current_str(self): |
|
1941 | def _indent_current_str(self): | |
1942 | """return the current level of indentation as a string""" |
|
1942 | """return the current level of indentation as a string""" | |
1943 | return self.input_splitter.indent_spaces * ' ' |
|
1943 | return self.input_splitter.get_indent_spaces() * ' ' | |
1944 |
|
1944 | |||
1945 | #------------------------------------------------------------------------- |
|
1945 | #------------------------------------------------------------------------- | |
1946 | # Things related to text completion |
|
1946 | # Things related to text completion |
@@ -37,7 +37,7 b' def mini_interactive_loop(input_func):' | |||||
37 | # input indefinitely, until some exit/quit command was issued. Here we |
|
37 | # input indefinitely, until some exit/quit command was issued. Here we | |
38 | # only illustrate the basic inner loop. |
|
38 | # only illustrate the basic inner loop. | |
39 | while isp.push_accepts_more(): |
|
39 | while isp.push_accepts_more(): | |
40 | indent = ' '*isp.indent_spaces |
|
40 | indent = ' '*isp.get_indent_spaces() | |
41 | prompt = '>>> ' + indent |
|
41 | prompt = '>>> ' + indent | |
42 | line = indent + input_func(prompt) |
|
42 | line = indent + input_func(prompt) | |
43 | isp.push(line) |
|
43 | isp.push(line) | |
@@ -132,7 +132,7 b' class InputSplitterTestCase(unittest.TestCase):' | |||||
132 | isp.push('x=1') |
|
132 | isp.push('x=1') | |
133 | isp.reset() |
|
133 | isp.reset() | |
134 | self.assertEqual(isp._buffer, []) |
|
134 | self.assertEqual(isp._buffer, []) | |
135 | self.assertEqual(isp.indent_spaces, 0) |
|
135 | self.assertEqual(isp.get_indent_spaces(), 0) | |
136 | self.assertEqual(isp.source, '') |
|
136 | self.assertEqual(isp.source, '') | |
137 | self.assertEqual(isp.code, None) |
|
137 | self.assertEqual(isp.code, None) | |
138 | self.assertEqual(isp._is_complete, False) |
|
138 | self.assertEqual(isp._is_complete, False) | |
@@ -149,21 +149,21 b' class InputSplitterTestCase(unittest.TestCase):' | |||||
149 | def test_indent(self): |
|
149 | def test_indent(self): | |
150 | isp = self.isp # shorthand |
|
150 | isp = self.isp # shorthand | |
151 | isp.push('x=1') |
|
151 | isp.push('x=1') | |
152 | self.assertEqual(isp.indent_spaces, 0) |
|
152 | self.assertEqual(isp.get_indent_spaces(), 0) | |
153 | isp.push('if 1:\n x=1') |
|
153 | isp.push('if 1:\n x=1') | |
154 | self.assertEqual(isp.indent_spaces, 4) |
|
154 | self.assertEqual(isp.get_indent_spaces(), 4) | |
155 | isp.push('y=2\n') |
|
155 | isp.push('y=2\n') | |
156 | self.assertEqual(isp.indent_spaces, 0) |
|
156 | self.assertEqual(isp.get_indent_spaces(), 0) | |
157 |
|
157 | |||
158 | def test_indent2(self): |
|
158 | def test_indent2(self): | |
159 | isp = self.isp |
|
159 | isp = self.isp | |
160 | isp.push('if 1:') |
|
160 | isp.push('if 1:') | |
161 | self.assertEqual(isp.indent_spaces, 4) |
|
161 | self.assertEqual(isp.get_indent_spaces(), 4) | |
162 | isp.push(' x=1') |
|
162 | isp.push(' x=1') | |
163 | self.assertEqual(isp.indent_spaces, 4) |
|
163 | self.assertEqual(isp.get_indent_spaces(), 4) | |
164 | # Blank lines shouldn't change the indent level |
|
164 | # Blank lines shouldn't change the indent level | |
165 | isp.push(' '*2) |
|
165 | isp.push(' '*2) | |
166 | self.assertEqual(isp.indent_spaces, 4) |
|
166 | self.assertEqual(isp.get_indent_spaces(), 4) | |
167 |
|
167 | |||
168 | def test_indent3(self): |
|
168 | def test_indent3(self): | |
169 | isp = self.isp |
|
169 | isp = self.isp | |
@@ -171,75 +171,75 b' class InputSplitterTestCase(unittest.TestCase):' | |||||
171 | # shouldn't get confused. |
|
171 | # shouldn't get confused. | |
172 | isp.push("if 1:") |
|
172 | isp.push("if 1:") | |
173 | isp.push(" x = (1+\n 2)") |
|
173 | isp.push(" x = (1+\n 2)") | |
174 | self.assertEqual(isp.indent_spaces, 4) |
|
174 | self.assertEqual(isp.get_indent_spaces(), 4) | |
175 |
|
175 | |||
176 | def test_indent4(self): |
|
176 | def test_indent4(self): | |
177 | isp = self.isp |
|
177 | isp = self.isp | |
178 | # whitespace after ':' should not screw up indent level |
|
178 | # whitespace after ':' should not screw up indent level | |
179 | isp.push('if 1: \n x=1') |
|
179 | isp.push('if 1: \n x=1') | |
180 | self.assertEqual(isp.indent_spaces, 4) |
|
180 | self.assertEqual(isp.get_indent_spaces(), 4) | |
181 | isp.push('y=2\n') |
|
181 | isp.push('y=2\n') | |
182 | self.assertEqual(isp.indent_spaces, 0) |
|
182 | self.assertEqual(isp.get_indent_spaces(), 0) | |
183 | isp.push('if 1:\t\n x=1') |
|
183 | isp.push('if 1:\t\n x=1') | |
184 | self.assertEqual(isp.indent_spaces, 4) |
|
184 | self.assertEqual(isp.get_indent_spaces(), 4) | |
185 | isp.push('y=2\n') |
|
185 | isp.push('y=2\n') | |
186 | self.assertEqual(isp.indent_spaces, 0) |
|
186 | self.assertEqual(isp.get_indent_spaces(), 0) | |
187 |
|
187 | |||
188 | def test_dedent_pass(self): |
|
188 | def test_dedent_pass(self): | |
189 | isp = self.isp # shorthand |
|
189 | isp = self.isp # shorthand | |
190 | # should NOT cause dedent |
|
190 | # should NOT cause dedent | |
191 | isp.push('if 1:\n passes = 5') |
|
191 | isp.push('if 1:\n passes = 5') | |
192 | self.assertEqual(isp.indent_spaces, 4) |
|
192 | self.assertEqual(isp.get_indent_spaces(), 4) | |
193 | isp.push('if 1:\n pass') |
|
193 | isp.push('if 1:\n pass') | |
194 | self.assertEqual(isp.indent_spaces, 0) |
|
194 | self.assertEqual(isp.get_indent_spaces(), 0) | |
195 | isp.push('if 1:\n pass ') |
|
195 | isp.push('if 1:\n pass ') | |
196 | self.assertEqual(isp.indent_spaces, 0) |
|
196 | self.assertEqual(isp.get_indent_spaces(), 0) | |
197 |
|
197 | |||
198 | def test_dedent_break(self): |
|
198 | def test_dedent_break(self): | |
199 | isp = self.isp # shorthand |
|
199 | isp = self.isp # shorthand | |
200 | # should NOT cause dedent |
|
200 | # should NOT cause dedent | |
201 | isp.push('while 1:\n breaks = 5') |
|
201 | isp.push('while 1:\n breaks = 5') | |
202 | self.assertEqual(isp.indent_spaces, 4) |
|
202 | self.assertEqual(isp.get_indent_spaces(), 4) | |
203 | isp.push('while 1:\n break') |
|
203 | isp.push('while 1:\n break') | |
204 | self.assertEqual(isp.indent_spaces, 0) |
|
204 | self.assertEqual(isp.get_indent_spaces(), 0) | |
205 | isp.push('while 1:\n break ') |
|
205 | isp.push('while 1:\n break ') | |
206 | self.assertEqual(isp.indent_spaces, 0) |
|
206 | self.assertEqual(isp.get_indent_spaces(), 0) | |
207 |
|
207 | |||
208 | def test_dedent_continue(self): |
|
208 | def test_dedent_continue(self): | |
209 | isp = self.isp # shorthand |
|
209 | isp = self.isp # shorthand | |
210 | # should NOT cause dedent |
|
210 | # should NOT cause dedent | |
211 | isp.push('while 1:\n continues = 5') |
|
211 | isp.push('while 1:\n continues = 5') | |
212 | self.assertEqual(isp.indent_spaces, 4) |
|
212 | self.assertEqual(isp.get_indent_spaces(), 4) | |
213 | isp.push('while 1:\n continue') |
|
213 | isp.push('while 1:\n continue') | |
214 | self.assertEqual(isp.indent_spaces, 0) |
|
214 | self.assertEqual(isp.get_indent_spaces(), 0) | |
215 | isp.push('while 1:\n continue ') |
|
215 | isp.push('while 1:\n continue ') | |
216 | self.assertEqual(isp.indent_spaces, 0) |
|
216 | self.assertEqual(isp.get_indent_spaces(), 0) | |
217 |
|
217 | |||
218 | def test_dedent_raise(self): |
|
218 | def test_dedent_raise(self): | |
219 | isp = self.isp # shorthand |
|
219 | isp = self.isp # shorthand | |
220 | # should NOT cause dedent |
|
220 | # should NOT cause dedent | |
221 | isp.push('if 1:\n raised = 4') |
|
221 | isp.push('if 1:\n raised = 4') | |
222 | self.assertEqual(isp.indent_spaces, 4) |
|
222 | self.assertEqual(isp.get_indent_spaces(), 4) | |
223 | isp.push('if 1:\n raise TypeError()') |
|
223 | isp.push('if 1:\n raise TypeError()') | |
224 | self.assertEqual(isp.indent_spaces, 0) |
|
224 | self.assertEqual(isp.get_indent_spaces(), 0) | |
225 | isp.push('if 1:\n raise') |
|
225 | isp.push('if 1:\n raise') | |
226 | self.assertEqual(isp.indent_spaces, 0) |
|
226 | self.assertEqual(isp.get_indent_spaces(), 0) | |
227 | isp.push('if 1:\n raise ') |
|
227 | isp.push('if 1:\n raise ') | |
228 | self.assertEqual(isp.indent_spaces, 0) |
|
228 | self.assertEqual(isp.get_indent_spaces(), 0) | |
229 |
|
229 | |||
230 | def test_dedent_return(self): |
|
230 | def test_dedent_return(self): | |
231 | isp = self.isp # shorthand |
|
231 | isp = self.isp # shorthand | |
232 | # should NOT cause dedent |
|
232 | # should NOT cause dedent | |
233 | isp.push('if 1:\n returning = 4') |
|
233 | isp.push('if 1:\n returning = 4') | |
234 | self.assertEqual(isp.indent_spaces, 4) |
|
234 | self.assertEqual(isp.get_indent_spaces(), 4) | |
235 | isp.push('if 1:\n return 5 + 493') |
|
235 | isp.push('if 1:\n return 5 + 493') | |
236 | self.assertEqual(isp.indent_spaces, 0) |
|
236 | self.assertEqual(isp.get_indent_spaces(), 0) | |
237 | isp.push('if 1:\n return') |
|
237 | isp.push('if 1:\n return') | |
238 | self.assertEqual(isp.indent_spaces, 0) |
|
238 | self.assertEqual(isp.get_indent_spaces(), 0) | |
239 | isp.push('if 1:\n return ') |
|
239 | isp.push('if 1:\n return ') | |
240 | self.assertEqual(isp.indent_spaces, 0) |
|
240 | self.assertEqual(isp.get_indent_spaces(), 0) | |
241 | isp.push('if 1:\n return(0)') |
|
241 | isp.push('if 1:\n return(0)') | |
242 | self.assertEqual(isp.indent_spaces, 0) |
|
242 | self.assertEqual(isp.get_indent_spaces(), 0) | |
243 |
|
243 | |||
244 | def test_push(self): |
|
244 | def test_push(self): | |
245 | isp = self.isp |
|
245 | isp = self.isp | |
@@ -508,7 +508,7 b" if __name__ == '__main__':" | |||||
508 | while True: |
|
508 | while True: | |
509 | prompt = start_prompt |
|
509 | prompt = start_prompt | |
510 | while isp.push_accepts_more(): |
|
510 | while isp.push_accepts_more(): | |
511 | indent = ' '*isp.indent_spaces |
|
511 | indent = ' '*isp.get_indent_spaces() | |
512 | if autoindent: |
|
512 | if autoindent: | |
513 | line = indent + input(prompt+indent) |
|
513 | line = indent + input(prompt+indent) | |
514 | else: |
|
514 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now