Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Remove runlines etc. #373

Merged
merged 7 commits into from

3 participants

@takluyver
Owner

This removes a few old methods, and tidies up the last few calls to ip.runlines().

I think we can also remove the reset_buffer method, and the InteractiveShell's buffer and buffer_raw attributes: grepping through the code, it looks like nothing that remains ever puts anything into those buffers. But there's still a few bits that check the buffers (e.g. in prefilter), and I just wanted to check that those bits are safe to remove.

@ellisonbg
Owner
@takluyver
Owner
@ellisonbg
Owner
@fperez
Owner

go for buffer removal, if it's safe.

Basically, when I wrote inputsplitter and built the new machinery, I was a bit afraid of tearing down everything at the same time: if something went badly wrong with the new system, I wanted to have an easy way to back off (without full version control reverts), so I left all the dead code around. And just hadn't gotten around to removing it...

So aggressive removal of anything there that seems unused is ok. However, in addition to running the test suite, also do a little bit of old-style manual interactive testing just for extra safety: type a few lines, indented stuff, magics, etc... Write out a little file you can paste from to make life easier if you want...

But it will be great to get rid of this old code, so we can actually see our new shiny building :) Thanks!

@takluyver
Owner

Good call, manual testing found one little thing I'd been too hasty to change (in the terminal frontend, now resolved). As far as I can tell, this all behaves properly now, but please do hunt out any corner cases.

@takluyver
Owner

(Once again tagging small changes onto an unrelated pull request - I shall try to stop needing to do this)

@fperez
Owner

Any chance you could add tests for the corner cases you found, or were they the kind of thing that only actual manual, interactive typing would show?

@takluyver
Owner

I don't think it can be automated. Specifically, if you start a multiline cell (e.g. for a in range(5): ), then press Ctrl-C, the existing contents should be discarded. I tried to remove this line, and that broke: #373 (comment)

@fperez
Owner

Ctrl-C can be emulated with a 'raise KeyboardInterrupt', would that help?

@takluyver
Owner
@fperez
Owner
@fperez
Owner

sorry for the delay, had some network problems at the office.

Looks good here, other than a failure in the parallel tests, but that's in master too, so no problem on this side.

Thanks!

@takluyver takluyver merged commit 72be7c7 into ipython:master
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
195 IPython/core/interactiveshell.py
@@ -427,14 +427,6 @@ def init_instance_attrs(self):
# command compiler
self.compile = CachingCompiler()
-
- # User input buffers
- # NOTE: these variables are slated for full removal, once we are 100%
- # sure that the new execution logic is solid. We will delte runlines,
- # push_line and these buffers, as all input will be managed by the
- # frontends via an inputsplitter instance.
- self.buffer = []
- self.buffer_raw = []
# Make an empty namespace, which extension writers can rely on both
# existing and NEVER being used by ipython itself. This gives them a
@@ -1374,7 +1366,7 @@ def dummy_handler(self,etype,value,tb):
print 'Exception type :',etype
print 'Exception value:',value
print 'Traceback :',tb
- print 'Source code :','\n'.join(self.buffer)
+ #print 'Source code :','\n'.join(self.buffer)
if handler is None: handler = dummy_handler
@@ -2224,110 +2216,6 @@ def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
return False
-
- # PENDING REMOVAL: this method is slated for deletion, once our new
- # input logic has been 100% moved to frontends and is stable.
- def runlines(self, lines, clean=False):
- """Run a string of one or more lines of source.
-
- This method is capable of running a string containing multiple source
- lines, as if they had been entered at the IPython prompt. Since it
- exposes IPython's processing machinery, the given strings can contain
- magic calls (%magic), special shell access (!cmd), etc.
- """
-
- if not isinstance(lines, (list, tuple)):
- lines = lines.splitlines()
-
- if clean:
- lines = self._cleanup_ipy_script(lines)
-
- # We must start with a clean buffer, in case this is run from an
- # interactive IPython session (via a magic, for example).
- self.reset_buffer()
-
- # Since we will prefilter all lines, store the user's raw input too
- # before we apply any transformations
- self.buffer_raw[:] = [ l+'\n' for l in lines]
-
- more = False
- prefilter_lines = self.prefilter_manager.prefilter_lines
- with nested(self.builtin_trap, self.display_trap):
- for line in lines:
- # skip blank lines so we don't mess up the prompt counter, but
- # do NOT skip even a blank line if we are in a code block (more
- # is true)
-
- if line or more:
- more = self.push_line(prefilter_lines(line, more))
- # IPython's run_source returns None if there was an error
- # compiling the code. This allows us to stop processing
- # right away, so the user gets the error message at the
- # right place.
- if more is None:
- break
- # final newline in case the input didn't have it, so that the code
- # actually does get executed
- if more:
- self.push_line('\n')
-
- def run_source(self, source, filename=None, symbol='single'):
- """Compile and run some source in the interpreter.
-
- Arguments are as for compile_command().
-
- One several things can happen:
-
- 1) The input is incorrect; compile_command() raised an
- exception (SyntaxError or OverflowError). A syntax traceback
- will be printed by calling the showsyntaxerror() method.
-
- 2) The input is incomplete, and more input is required;
- compile_command() returned None. Nothing happens.
-
- 3) The input is complete; compile_command() returned a code
- object. The code is executed by calling self.run_code() (which
- also handles run-time exceptions, except for SystemExit).
-
- The return value is:
-
- - True in case 2
-
- - False in the other cases, unless an exception is raised, where
- None is returned instead. This can be used by external callers to
- know whether to continue feeding input or not.
-
- The return value can be used to decide whether to use sys.ps1 or
- sys.ps2 to prompt the next line."""
-
- # We need to ensure that the source is unicode from here on.
- if type(source)==str:
- usource = source.decode(self.stdin_encoding)
- else:
- usource = source
-
- try:
- code_name = self.compile.cache(usource, self.execution_count)
- code = self.compile(usource, code_name, symbol)
- except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
- # Case 1
- self.showsyntaxerror(filename)
- return None
-
- if code is None:
- # Case 2
- return True
-
- # Case 3
- # now actually execute the code object
- if not self.run_code(code):
- return False
- else:
- return None
-
- # For backwards compatibility
- runsource = run_source
-
def run_code(self, code_obj):
"""Execute a code object.
@@ -2364,9 +2252,8 @@ def run_code(self, code_obj):
# Reset our crash handler in place
sys.excepthook = old_excepthook
except SystemExit:
- self.reset_buffer()
self.showtraceback(exception_only=True)
- warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
+ warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
except self.custom_exceptions:
etype,value,tb = sys.exc_info()
self.CustomTB(etype,value,tb)
@@ -2382,84 +2269,6 @@ def run_code(self, code_obj):
# For backwards compatibility
runcode = run_code
- # PENDING REMOVAL: this method is slated for deletion, once our new
- # input logic has been 100% moved to frontends and is stable.
- def push_line(self, line):
- """Push a line to the interpreter.
-
- The line should not have a trailing newline; it may have
- internal newlines. The line is appended to a buffer and the
- interpreter's run_source() method is called with the
- concatenated contents of the buffer as source. If this
- indicates that the command was executed or invalid, the buffer
- is reset; otherwise, the command is incomplete, and the buffer
- is left as it was after the line was appended. The return
- value is 1 if more input is required, 0 if the line was dealt
- with in some way (this is the same as run_source()).
- """
-
- # autoindent management should be done here, and not in the
- # interactive loop, since that one is only seen by keyboard input. We
- # need this done correctly even for code run via runlines (which uses
- # push).
-
- #print 'push line: <%s>' % line # dbg
- self.buffer.append(line)
- full_source = '\n'.join(self.buffer)
- more = self.run_source(full_source, self.filename)
- if not more:
- self.history_manager.store_inputs(self.execution_count,
- '\n'.join(self.buffer_raw), full_source)
- self.reset_buffer()
- self.execution_count += 1
- return more
-
- def reset_buffer(self):
- """Reset the input buffer."""
- self.buffer[:] = []
- self.buffer_raw[:] = []
- self.input_splitter.reset()
-
- # For backwards compatibility
- resetbuffer = reset_buffer
-
- def _is_secondary_block_start(self, s):
- if not s.endswith(':'):
- return False
- if (s.startswith('elif') or
- s.startswith('else') or
- s.startswith('except') or
- s.startswith('finally')):
- return True
-
- def _cleanup_ipy_script(self, script):
- """Make a script safe for self.runlines()
-
- Currently, IPython is lines based, with blocks being detected by
- empty lines. This is a problem for block based scripts that may
- not have empty lines after blocks. This script adds those empty
- lines to make scripts safe for running in the current line based
- IPython.
- """
- res = []
- lines = script.splitlines()
- level = 0
-
- for l in lines:
- lstripped = l.lstrip()
- stripped = l.strip()
- if not stripped:
- continue
- newlevel = len(l) - len(lstripped)
- if level > 0 and newlevel == 0 and \
- not self._is_secondary_block_start(stripped):
- # add empty line
- res.append('')
- res.append(l)
- level = newlevel
-
- return '\n'.join(res) + '\n'
-
#-------------------------------------------------------------------------
# Things related to GUI support and pylab
#-------------------------------------------------------------------------
View
13 IPython/core/prefilter.py
@@ -383,10 +383,6 @@ def prefilter_line(self, line, continue_prompt=False):
# previously typed some whitespace that started a continuation
# prompt, he can break out of that loop with just an empty line.
# This is how the default python prompt works.
-
- # Only return if the accumulated input buffer was just whitespace!
- if ''.join(self.shell.buffer).isspace():
- self.shell.buffer[:] = []
return ''
# At this point, we invoke our transformers.
@@ -791,14 +787,7 @@ def handle(self, line_info):
if (continue_prompt and
self.shell.autoindent and
line.isspace() and
-
- (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2
- or
- not self.shell.buffer
- or
- (self.shell.buffer[-1]).isspace()
- )
- ):
+ 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
line = ''
return line
View
8 IPython/core/tests/test_iplib.py
@@ -237,10 +237,10 @@ def doctest_tb_sysexit():
"""
-def test_runlines():
+def test_run_cell():
import textwrap
- ip.runlines(['a = 10', 'a+=1'])
- ip.runlines('assert a == 11\nassert 1')
+ ip.run_cell('a = 10\na+=1')
+ ip.run_cell('assert a == 11\nassert 1')
nt.assert_equals(ip.user_ns['a'], 11)
complex = textwrap.dedent("""
@@ -260,7 +260,7 @@ def test_runlines():
""")
# Simply verifies that this kind of input is run
- ip.runlines(complex)
+ ip.run_cell(complex)
def test_db():
View
4 IPython/core/tests/test_run.py
@@ -151,7 +151,7 @@ def test_simpledef(self):
"def f(): return foo()")
self.mktmp(src)
_ip.magic('run %s' % self.fname)
- _ip.runlines('t = isinstance(f(), foo)')
+ _ip.run_cell('t = isinstance(f(), foo)')
nt.assert_true(_ip.user_ns['t'])
# We have to skip these in win32 because getoutputerr() crashes,
@@ -188,7 +188,7 @@ class secondtmp(tt.TempFileMixin): pass
" print i;break\n" % empty.fname)
self.mktmp(src)
_ip.magic('run %s' % self.fname)
- _ip.runlines('ip == get_ipython()')
+ _ip.run_cell('ip == get_ipython()')
tt.assert_equals(_ip.user_ns['i'], 5)
@dec.skip_win32
View
2  IPython/frontend/terminal/interactiveshell.py
@@ -246,7 +246,7 @@ def interact(self, display_banner=None):
#double-guard against keyboardinterrupts during kbdint handling
try:
self.write('\nKeyboardInterrupt\n')
- self.resetbuffer()
+ self.input_splitter.reset()
more = False
except KeyboardInterrupt:
pass
View
2  IPython/zmq/ipkernel.py
@@ -241,7 +241,7 @@ def execute_request(self, ident, parent):
except:
status = u'error'
# FIXME: this code right now isn't being used yet by default,
- # because the runlines() call above directly fires off exception
+ # because the run_cell() call above directly fires off exception
# reporting. This code, therefore, is only active in the scenario
# where runlines itself has an unhandled exception. We need to
# uniformize this, for all exception construction to come from a
Something went wrong with that request. Please try again.