##// END OF EJS Templates
Merge branch 'single-output' into takluyver-single-output
Thomas Kluyver -
r3751:bb384816 merge
parent child Browse files
Show More
@@ -282,9 +282,8 b' class DisplayHook(Configurable):'
282 282 """Log the output."""
283 283 if self.shell.logger.log_output:
284 284 self.shell.logger.log_write(format_dict['text/plain'], 'output')
285 # This is a defaultdict of lists, so we can always append
286 self.shell.history_manager.output_hist_reprs[self.prompt_count]\
287 .append(format_dict['text/plain'])
285 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
286 format_dict['text/plain']
288 287
289 288 def finish_displayhook(self):
290 289 """Finish up all displayhook activities."""
@@ -15,14 +15,11 b' from __future__ import print_function'
15 15 # Stdlib imports
16 16 import atexit
17 17 import datetime
18 import json
19 18 import os
20 19 import re
21 20 import sqlite3
22 21 import threading
23 22
24 from collections import defaultdict
25
26 23 # Our own packages
27 24 from IPython.config.configurable import Configurable
28 25 import IPython.utils.io
@@ -56,11 +53,10 b' class HistoryManager(Configurable):'
56 53 return []
57 54
58 55 # A dict of output history, keyed with ints from the shell's
59 # execution count. If there are several outputs from one command,
60 # only the last one is stored.
56 # execution count.
61 57 output_hist = Dict()
62 # Contains all outputs, in lists of reprs.
63 output_hist_reprs = Instance(defaultdict, args=(list,))
58 # The text/plain repr of outputs.
59 output_hist_reprs = Dict()
64 60
65 61 # String holding the path to the history file
66 62 hist_file = Unicode(config=True)
@@ -92,11 +88,10 b' class HistoryManager(Configurable):'
92 88 _ii = Unicode(u'')
93 89 _iii = Unicode(u'')
94 90
95 # A set with all forms of the exit command, so that we don't store them in
96 # the history (it's annoying to rewind the first entry and land on an exit
97 # call).
98 _exit_commands = Instance(set, args=(['Quit', 'quit', 'Exit', 'exit',
99 '%Quit', '%quit', '%Exit', '%exit'],))
91 # A regex matching all forms of the exit command, so that we don't store
92 # them in the history (it's annoying to rewind the first entry and land on
93 # an exit call).
94 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
100 95
101 96 def __init__(self, shell, config=None, **traits):
102 97 """Create a new history manager associated with a shell instance.
@@ -218,9 +213,7 b' class HistoryManager(Configurable):'
218 213 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
219 214 (toget, sqlfrom) + sql, params)
220 215 if output: # Regroup into 3-tuples, and parse JSON
221 loads = lambda out: json.loads(out) if out else None
222 return ((ses, lin, (inp, loads(out))) \
223 for ses, lin, inp, out in cur)
216 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
224 217 return cur
225 218
226 219
@@ -383,7 +376,7 b' class HistoryManager(Configurable):'
383 376 source_raw = source_raw.rstrip('\n')
384 377
385 378 # do not store exit/quit commands
386 if source_raw.strip() in self._exit_commands:
379 if self._exit_re.match(source_raw.strip()):
387 380 return
388 381
389 382 self.input_hist_parsed.append(source)
@@ -419,9 +412,9 b' class HistoryManager(Configurable):'
419 412 line_num : int
420 413 The line number from which to save outputs
421 414 """
422 if (not self.db_log_output) or not self.output_hist_reprs[line_num]:
415 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
423 416 return
424 output = json.dumps(self.output_hist_reprs[line_num])
417 output = self.output_hist_reprs[line_num]
425 418
426 419 with self.db_output_cache_lock:
427 420 self.db_output_cache.append((line_num, output))
@@ -696,7 +689,7 b" def magic_history(self, parameter_s = ''):"
696 689 inline = "\n... ".join(inline.splitlines()) + "\n..."
697 690 print(inline, file=outfile)
698 691 if get_output and output:
699 print("\n".join(output), file=outfile)
692 print(output, file=outfile)
700 693
701 694 if close_at_end:
702 695 outfile.close()
@@ -2150,12 +2150,9 b' class InteractiveShell(Configurable, Magic):'
2150 2150 self.showsyntaxerror()
2151 2151 self.execution_count += 1
2152 2152 return None
2153
2154 interactivity = 'last' # Last node to be run interactive
2155 if len(cell.splitlines()) == 1:
2156 interactivity = 'all' # Single line; run fully interactive
2157 2153
2158 self.run_ast_nodes(code_ast.body, cell_name, interactivity)
2154 self.run_ast_nodes(code_ast.body, cell_name,
2155 interactivity="last_expr")
2159 2156
2160 2157 # Execute any registered post-execution functions.
2161 2158 for func, status in self._post_execute.iteritems():
@@ -2175,7 +2172,7 b' class InteractiveShell(Configurable, Magic):'
2175 2172 # Each cell is a *single* input, regardless of how many lines it has
2176 2173 self.execution_count += 1
2177 2174
2178 def run_ast_nodes(self, nodelist, cell_name, interactivity='last'):
2175 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2179 2176 """Run a sequence of AST nodes. The execution mode depends on the
2180 2177 interactivity parameter.
2181 2178
@@ -2187,13 +2184,21 b' class InteractiveShell(Configurable, Magic):'
2187 2184 Will be passed to the compiler as the filename of the cell. Typically
2188 2185 the value returned by ip.compile.cache(cell).
2189 2186 interactivity : str
2190 'all', 'last' or 'none', specifying which nodes should be run
2191 interactively (displaying output from expressions). Other values for
2192 this parameter will raise a ValueError.
2187 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2188 run interactively (displaying output from expressions). 'last_expr'
2189 will run the last node interactively only if it is an expression (i.e.
2190 expressions in loops or other blocks are not displayed. Other values
2191 for this parameter will raise a ValueError.
2193 2192 """
2194 2193 if not nodelist:
2195 2194 return
2196 2195
2196 if interactivity == 'last_expr':
2197 if isinstance(nodelist[-1], ast.Expr):
2198 interactivity = "last"
2199 else:
2200 interactivity = "none"
2201
2197 2202 if interactivity == 'none':
2198 2203 to_run_exec, to_run_interactive = nodelist, []
2199 2204 elif interactivity == 'last':
@@ -33,7 +33,7 b' def test_history():'
33 33
34 34 ip.history_manager.db_log_output = True
35 35 # Doesn't match the input, but we'll just check it's stored.
36 ip.history_manager.output_hist_reprs[3].append("spam")
36 ip.history_manager.output_hist_reprs[3] = "spam"
37 37 ip.history_manager.store_output(3)
38 38
39 39 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
@@ -53,7 +53,7 b' def test_history():'
53 53 # Check get_hist_tail
54 54 gothist = ip.history_manager.get_tail(4, output=True,
55 55 include_latest=True)
56 expected = [(1, 3, (hist[-1], ["spam"])),
56 expected = [(1, 3, (hist[-1], "spam")),
57 57 (2, 1, (newcmds[0], None)),
58 58 (2, 2, (newcmds[1], None)),
59 59 (2, 3, (newcmds[2], None)),]
@@ -68,7 +68,7 b' def test_history():'
68 68 gothist = ip.history_manager.search("*test*")
69 69 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
70 70 gothist = ip.history_manager.search("b*", output=True)
71 nt.assert_equal(list(gothist), [(1,3,(hist[2],["spam"]))] )
71 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
72 72
73 73 # Cross testing: check that magic %save can get previous session.
74 74 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
General Comments 0
You need to be logged in to leave comments. Login now