diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py index 7868b46..262fe7e 100644 --- a/IPython/core/displayhook.py +++ b/IPython/core/displayhook.py @@ -119,10 +119,6 @@ class DisplayHook(Configurable): def prompt_count(self): return self.shell.execution_count - @prompt_count.setter - def _set_prompt_count(self, val): - raise ValueError('prompt count is read only') - def _set_prompt_str(self,p_str,cache_def,no_cache_def): if p_str is None: if self.do_full_cache: diff --git a/IPython/core/history.py b/IPython/core/history.py index 490643f..9ee3dca 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -180,7 +180,6 @@ class HistoryManager(object): if len(self.input_hist) != len (self.input_hist_raw): self.input_hist_raw = InputList(self.input_hist) - def reset(self): """Clear all histories managed by this object.""" self.input_hist[:] = [] diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py index d1ce545..e81af5f 100644 --- a/IPython/core/inputsplitter.py +++ b/IPython/core/inputsplitter.py @@ -371,15 +371,6 @@ class InputSplitter(object): if self.input_mode == 'cell': self.reset() - # If the source code has leading blanks, add 'if 1:\n' to it - # this allows execution of indented pasted code. It is tempting - # to add '\n' at the end of source to run commands like ' a=1' - # directly, but this fails for more complicated scenarios - - if not self._buffer and lines[:1] in [' ', '\t'] and \ - not comment_line_re.match(lines): - lines = 'if 1:\n%s' % lines - self._store(lines) source = self.source @@ -594,7 +585,7 @@ class InputSplitter(object): #print 'safety' # dbg return indent_spaces, full_dedent - + def _update_indent(self, lines): for line in remove_comments(lines).splitlines(): if line and not line.isspace(): diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 7ed856a..649c049 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -400,7 +400,7 @@ class InteractiveShell(Configurable, Magic): self.indent_current_nsp = 0 # Increasing execution counter - self.execution_count = 0 + self.execution_count = 1 def init_environment(self): """Any changes we need to make to the user's environment.""" @@ -1558,7 +1558,8 @@ class InteractiveShell(Configurable, Magic): def _indent_current_str(self): """return the current level of indentation as a string""" - return self.indent_current_nsp * ' ' + #return self.indent_current_nsp * ' ' + return self.input_splitter.indent_spaces * ' ' #------------------------------------------------------------------------- # Things related to text completion @@ -2095,30 +2096,32 @@ class InteractiveShell(Configurable, Magic): # original cell may contain non-python syntax). ipy_cell = ''.join(blocks) - # Each cell is a *single* input, regardless of how many lines it has - self.execution_count += 1 - # Store raw and processed history self.history_manager.store_inputs(ipy_cell, cell) # dbg code!!! - def myapp(self, val): # dbg - import traceback as tb - stack = ''.join(tb.format_stack()) - print 'Value:', val - print 'Stack:\n', stack - list.append(self, val) - - import new - self.input_hist.append = new.instancemethod(myapp, self.input_hist, - list) + if 0: + def myapp(self, val): # dbg + import traceback as tb + stack = ''.join(tb.format_stack()) + print 'Value:', val + print 'Stack:\n', stack + list.append(self, val) + + import new + self.input_hist.append = new.instancemethod(myapp, self.input_hist, + list) # End dbg # All user code execution must happen with our context managers active with nested(self.builtin_trap, self.display_trap): + # Single-block input should behave like an interactive prompt if len(blocks) == 1: - return self.run_one_block(blocks[0]) + # since we return here, we need to update the execution count + out = self.run_one_block(blocks[0]) + self.execution_count += 1 + return out # In multi-block input, if the last block is a simple (one-two # lines) expression, run it in single mode so it produces output. @@ -2145,6 +2148,9 @@ class InteractiveShell(Configurable, Magic): # processed input in history self.runcode(ipy_cell) + # Each cell is a *single* input, regardless of how many lines it has + self.execution_count += 1 + def run_one_block(self, block): """Run a single interactive block. @@ -2214,7 +2220,7 @@ class InteractiveShell(Configurable, Magic): if more: self.push_line('\n') - def runsource(self, source, filename='', symbol='single'): + def runsource(self, source, filename='', symbol='single'): """Compile and run some source in the interpreter. Arguments are as for compile_command(). @@ -2247,14 +2253,6 @@ class InteractiveShell(Configurable, Magic): if type(source)==str: source = source.decode(self.stdin_encoding) - # if the source code has leading blanks, add 'if 1:\n' to it - # this allows execution of indented pasted code. It is tempting - # to add '\n' at the end of source to run commands like ' a=1' - # directly, but this fails for more complicated scenarios - - if source[:1] in [' ', '\t']: - source = u'if 1:\n%s' % source - try: code = self.compile(source,filename,symbol) except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError): @@ -2361,8 +2359,6 @@ class InteractiveShell(Configurable, Magic): # push). #print 'push line: <%s>' % line # dbg - for subline in line.splitlines(): - self._autoindent_update(subline) self.buffer.append(line) full_source = '\n'.join(self.buffer) more = self.runsource(full_source, self.filename) @@ -2377,6 +2373,7 @@ class InteractiveShell(Configurable, Magic): """Reset the input buffer.""" self.buffer[:] = [] self.buffer_raw[:] = [] + self.input_splitter.reset() def _is_secondary_block_start(self, s): if not s.endswith(':'): @@ -2415,24 +2412,6 @@ class InteractiveShell(Configurable, Magic): return '\n'.join(res) + '\n' - def _autoindent_update(self,line): - """Keep track of the indent level.""" - - #debugx('line') - #debugx('self.indent_current_nsp') - if self.autoindent: - if line: - inisp = num_ini_spaces(line) - if inisp < self.indent_current_nsp: - self.indent_current_nsp = inisp - - if line[-1] == ':': - self.indent_current_nsp += 4 - elif dedent_re.match(line): - self.indent_current_nsp -= 4 - else: - self.indent_current_nsp = 0 - #------------------------------------------------------------------------- # Things related to GUI support and pylab #------------------------------------------------------------------------- diff --git a/IPython/core/prefilter.py b/IPython/core/prefilter.py index dc1d1dc..e427091 100755 --- a/IPython/core/prefilter.py +++ b/IPython/core/prefilter.py @@ -428,7 +428,7 @@ class PrefilterManager(Configurable): which is the case when the user goes back to a multiline history entry and presses enter. """ - llines = lines.rstrip('\n').splitlines() + llines = lines.rstrip('\n').split('\n') # We can get multiple lines in one shot, where multiline input 'blends' # into one line, in cases like recalling from the readline history # buffer. We need to make sure that in such cases, we correctly diff --git a/IPython/core/tests/test_inputsplitter.py b/IPython/core/tests/test_inputsplitter.py index 3a40449..2981c10 100644 --- a/IPython/core/tests/test_inputsplitter.py +++ b/IPython/core/tests/test_inputsplitter.py @@ -162,6 +162,12 @@ class InputSplitterTestCase(unittest.TestCase): self.assertEqual(isp.indent_spaces, 4) isp.push('y=2\n') self.assertEqual(isp.indent_spaces, 0) + + def test_indent2(self): + # In cell mode, inputs must be fed in whole blocks, so skip this test + if self.isp.input_mode == 'cell': return + + isp = self.isp isp.push('if 1:') self.assertEqual(isp.indent_spaces, 4) isp.push(' x=1') @@ -170,7 +176,10 @@ class InputSplitterTestCase(unittest.TestCase): isp.push(' '*2) self.assertEqual(isp.indent_spaces, 4) - def test_indent2(self): + def test_indent3(self): + # In cell mode, inputs must be fed in whole blocks, so skip this test + if self.isp.input_mode == 'cell': return + isp = self.isp # When a multiline statement contains parens or multiline strings, we # shouldn't get confused. @@ -195,13 +204,6 @@ class InputSplitterTestCase(unittest.TestCase): for line in [' x=1', '# a comment', ' y=2']: self.assertTrue(isp.push(line)) - def test_push3(self): - """Test input with leading whitespace""" - isp = self.isp - isp.push(' x=1') - isp.push(' y=2') - self.assertEqual(isp.source, 'if 1:\n x=1\n y=2\n') - def test_replace_mode(self): isp = self.isp isp.input_mode = 'cell' @@ -216,6 +218,9 @@ class InputSplitterTestCase(unittest.TestCase): self.assertFalse(isp.push_accepts_more()) def test_push_accepts_more2(self): + # In cell mode, inputs must be fed in whole blocks, so skip this test + if self.isp.input_mode == 'cell': return + isp = self.isp isp.push('if 1:') self.assertTrue(isp.push_accepts_more()) @@ -230,6 +235,9 @@ class InputSplitterTestCase(unittest.TestCase): self.assertFalse(isp.push_accepts_more()) def test_push_accepts_more4(self): + # In cell mode, inputs must be fed in whole blocks, so skip this test + if self.isp.input_mode == 'cell': return + isp = self.isp # When a multiline statement contains parens or multiline strings, we # shouldn't get confused. diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py index d4c9df8..949f887 100644 --- a/IPython/frontend/terminal/interactiveshell.py +++ b/IPython/frontend/terminal/interactiveshell.py @@ -227,11 +227,6 @@ class TerminalInteractiveShell(InteractiveShell): # exit_now is set by a call to %Exit or %Quit, through the # ask_exit callback. - # Before showing any prompts, if the counter is at zero, we execute an - # empty line to ensure the user only sees prompts starting at one. - if self.execution_count == 0: - self.execution_count += 1 - while not self.exit_now: self.hooks.pre_prompt_hook() if more: @@ -260,11 +255,6 @@ class TerminalInteractiveShell(InteractiveShell): try: self.write('\nKeyboardInterrupt\n') self.resetbuffer() - # keep cache in sync with the prompt counter: - self.displayhook.prompt_count -= 1 - - if self.autoindent: - self.indent_current_nsp = 0 more = False except KeyboardInterrupt: pass @@ -285,14 +275,14 @@ class TerminalInteractiveShell(InteractiveShell): # asynchronously by signal handlers, for example. self.showtraceback() else: - #more = self.push_line(line) self.input_splitter.push(line) more = self.input_splitter.push_accepts_more() if (self.SyntaxTB.last_syntax_error and self.autoedit_syntax): self.edit_syntax_error() if not more: - pass + source_raw = self.input_splitter.source_raw_reset()[1] + self.run_cell(source_raw) # We are off again... __builtin__.__dict__['__IPYTHON__active'] -= 1 @@ -398,69 +388,6 @@ class TerminalInteractiveShell(InteractiveShell): return line - - # TODO: The following three methods are an early attempt to refactor - # the main code execution logic. We don't use them, but they may be - # helpful when we refactor the code execution logic further. - # def interact_prompt(self): - # """ Print the prompt (in read-eval-print loop) - # - # Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not - # used in standard IPython flow. - # """ - # if self.more: - # try: - # prompt = self.hooks.generate_prompt(True) - # except: - # self.showtraceback() - # if self.autoindent: - # self.rl_do_indent = True - # - # else: - # try: - # prompt = self.hooks.generate_prompt(False) - # except: - # self.showtraceback() - # self.write(prompt) - # - # def interact_handle_input(self,line): - # """ Handle the input line (in read-eval-print loop) - # - # Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not - # used in standard IPython flow. - # """ - # if line.lstrip() == line: - # self.shadowhist.add(line.strip()) - # lineout = self.prefilter_manager.prefilter_lines(line,self.more) - # - # if line.strip(): - # if self.more: - # self.input_hist_raw[-1] += '%s\n' % line - # else: - # self.input_hist_raw.append('%s\n' % line) - # - # - # self.more = self.push_line(lineout) - # if (self.SyntaxTB.last_syntax_error and - # self.autoedit_syntax): - # self.edit_syntax_error() - # - # def interact_with_readline(self): - # """ Demo of using interact_handle_input, interact_prompt - # - # This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI), - # it should work like this. - # """ - # self.readline_startup_hook(self.pre_readline) - # while not self.exit_now: - # self.interact_prompt() - # if self.more: - # self.rl_do_indent = True - # else: - # self.rl_do_indent = False - # line = raw_input_original().decode(self.stdin_encoding) - # self.interact_handle_input(line) - #------------------------------------------------------------------------- # Methods to support auto-editing of SyntaxErrors. #------------------------------------------------------------------------- diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index 2c56dd9..b07776f 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -240,7 +240,7 @@ class Kernel(Configurable): reply_content[u'status'] = status # Return the execution counter so clients can display prompts - reply_content['execution_count'] = shell.execution_count + reply_content['execution_count'] = shell.execution_count -1 # FIXME - fish exception info out of shell, possibly left there by # runlines. We'll need to clean up this logic later.