Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Qtconsole exit #311

Closed
wants to merge 1 commit into from

2 participants

@takluyver
Owner

Typing 'exit' at the Qt console had stopped working, although 'Exit' still worked. The prefilter system wasn't picking 'exit' up as an automagic, because of the presence of the builtin 'exit' function, which is removed before user code runs.

This does the prefiltering inside our builtin_trap context manager, so it doesn't see the exit builtin, and detects it as an automagic instead.

@fperez
Owner

Thanks a lot! I rebased it on top of Robert's to avoid an unnecessary merge handle in the DAG, but content is unchanged. Commited as 67effcc.

@fperez fperez closed this
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.
Showing with 68 additions and 60 deletions.
  1. +68 −60 IPython/core/interactiveshell.py
View
128 IPython/core/interactiveshell.py
@@ -2094,69 +2094,77 @@ def run_cell(self, cell, store_history=True):
# Store the untransformed code
raw_cell = cell
- # We need to break up the input into executable blocks that can be run
- # in 'single' mode, to provide comfortable user behavior.
- blocks = self.input_splitter.split_blocks(cell)
- if not blocks: # Blank cell
- return
-
- # We only do dynamic transforms on a single line. But a macro can
- # be expanded to several lines, so we need to split it into input
- # blocks again.
- if len(cell.splitlines()) <= 1:
- cell = self.prefilter_manager.prefilter_line(blocks[0])
+ # Code transformation and execution must take place with our
+ # modifications to builtins.
+ with self.builtin_trap:
+
+ # We need to break up the input into executable blocks that can
+ # be runin 'single' mode, to provide comfortable user behavior.
blocks = self.input_splitter.split_blocks(cell)
-
- # Store the 'ipython' version of the cell as well, since that's what
- # needs to go into the translated history and get executed (the
- # original cell may contain non-python syntax).
- cell = ''.join(blocks)
-
- # Store raw and processed history
- if store_history:
- self.history_manager.store_inputs(self.execution_count,
- cell, raw_cell)
-
- self.logger.log(cell, raw_cell)
-
- # 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:
- out = self.run_source(blocks[0])
- # Write output to the database. Does nothing unless
- # history output logging is enabled.
- if store_history:
- self.history_manager.store_output(self.execution_count)
- # since we return here, we need to update the execution count
- 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.
- # Otherwise just run it all in 'exec' mode. This seems like a
- # reasonable usability design.
- last = blocks[-1]
- last_nlines = len(last.splitlines())
- if last_nlines < 2:
- # Here we consider the cell split between 'body' and 'last',
- # store all history and execute 'body', and if successful, then
- # proceed to execute 'last'.
-
- # Get the main body to run as a cell
- ipy_body = ''.join(blocks[:-1])
- retcode = self.run_source(ipy_body, symbol='exec',
- post_execute=False)
- if retcode==0:
- # Last expression compiled as 'single' so it produces output
- self.run_source(last)
- else:
- # Run the whole cell as one entity, storing both raw and
- # processed input in history
- self.run_source(ipy_cell, symbol='exec')
+ if not blocks: # Blank cell
+ return
+
+ # We only do dynamic transforms on a single line. But a macro
+ # can be expanded to several lines, so we need to split it
+ # into input blocks again.
+ if len(cell.splitlines()) <= 1:
+ cell = self.prefilter_manager.prefilter_line(blocks[0])
+ blocks = self.input_splitter.split_blocks(cell)
+
+ # Store the 'ipython' version of the cell as well, since
+ # that's what needs to go into the translated history and get
+ # executed (the original cell may contain non-python syntax).
+ cell = ''.join(blocks)
+
+ # Store raw and processed history
+ if store_history:
+ self.history_manager.store_inputs(self.execution_count,
+ cell, raw_cell)
+
+ self.logger.log(cell, raw_cell)
+
+ # All user code execution should take place with our
+ # modified displayhook.
+ with self.display_trap:
+
+ # Single-block input should behave like an interactive prompt
+ if len(blocks) == 1:
+ out = self.run_source(blocks[0])
+ # Write output to the database. Does nothing unless
+ # history output logging is enabled.
+ if store_history:
+ self.history_manager.store_output(self.execution_count)
+ # Since we return here, we need to update the
+ # execution count
+ 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.
+ # Otherwise just run it all in 'exec' mode. This seems like a
+ # reasonable usability design.
+ last = blocks[-1]
+ last_nlines = len(last.splitlines())
+
+ if last_nlines < 2:
+ # Here we consider the cell split between 'body' and 'last',
+ # store all history and execute 'body', and if successful, then
+ # proceed to execute 'last'.
+
+ # Get the main body to run as a cell
+ ipy_body = ''.join(blocks[:-1])
+ retcode = self.run_source(ipy_body, symbol='exec',
+ post_execute=False)
+ if retcode==0:
+ # Last expression compiled as 'single' so it
+ # produces output
+ self.run_source(last)
+ else:
+ # Run the whole cell as one entity, storing both raw and
+ # processed input in history
+ self.run_source(ipy_cell, symbol='exec')
# Write output to the database. Does nothing unless
# history output logging is enabled.
Something went wrong with that request. Please try again.