From 6a18a45adc236343b289455d5f49d12aa7f05719 2011-03-13 12:51:49 From: Thomas Kluyver Date: 2011-03-13 12:51:49 Subject: [PATCH] ipython-qtconsole now calls the right function. --- diff --git a/IPython/core/history.py b/IPython/core/history.py index e5d1922..6b47f15 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -124,12 +124,19 @@ class HistoryManager(Configurable): name='session_number'""", (self.session_number+1,)) self.db.commit() - def get_hist_tail(self, n=10, raw=True): + def get_hist_tail(self, n=10, raw=True, output=False): """Get the last n lines from the history database.""" toget = 'source_raw' if raw else 'source' + sqlfrom = "history" + if output: + sqlfrom = "history LEFT JOIN output_history USING (session, line)" + toget = "history.%s, output_history.output" % toget cur = self.db.execute("SELECT session, line, " + toget +\ - " FROM history ORDER BY session DESC, line DESC LIMIT ?""", (n,)) - return reversed(cur.fetchall()) + " FROM "+sqlfrom+" ORDER BY session DESC, line DESC LIMIT ?", (n,)) + hist = reversed(cur.fetchall()) + if output: + return ((ses, lin, (inp, out)) for ses, lin, inp, out in hist) + return hist def get_hist_search(self, pattern="*", raw=True): """Search the database using unix glob-style matching (wildcards * and @@ -158,7 +165,7 @@ class HistoryManager(Configurable): for i in range(start, stop): if output: - line = (input_hist[i], self.output_hist.get(i)) + line = (input_hist[i], repr(self.output_hist.get(i))) else: line = input_hist[i] yield (0, i, line) @@ -197,7 +204,7 @@ class HistoryManager(Configurable): # Assemble the SQL query: sqlfrom = "history" - toget = "session, line, " +('source_raw' if raw else 'source') + toget = 'source_raw' if raw else 'source' if output: sqlfrom = "history LEFT JOIN output_history USING (session, line)" toget = "history.%s, output_history.output" % toget @@ -208,10 +215,10 @@ class HistoryManager(Configurable): lineclause = "line>=?" params = (session, start) - cur = self.db.execute("SELECT %s FROM %s WHERE session==? AND %s"\ - %(toget, sqlfrom, lineclause), params) + cur = self.db.execute("""SELECT session, line, %s FROM %s WHERE + session==? AND %s""" %(toget, sqlfrom, lineclause), params) if output: # Regroup into 3-tuples - return ((ses, lin (inp, out)) for ses, lin, inp, out in cur) + return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur) return cur def get_hist_from_rangestr(self, rangestr, raw=True, output=False): @@ -278,6 +285,7 @@ class HistoryManager(Configurable): self.db.execute("INSERT INTO output_history VALUES (?,?,?)", db_row) def writeout_cache(self): + #print(self.db_input_cache) with self.db: self.db.executemany("INSERT INTO history VALUES (?, ?, ?, ?)", self.db_input_cache) @@ -295,8 +303,8 @@ class HistoryManager(Configurable): elif lr < lp: self.input_hist_parsed[:lp-lr] = [] - def reset(self): - """Clear all histories managed by this object, and start a new + def reset(self, new_session=True): + """Clear the current session's history, and (optionally) start a new session.""" self.input_hist_parsed[:] = [""] self.input_hist_raw[:] = [""] @@ -304,8 +312,9 @@ class HistoryManager(Configurable): # The directory history can't be completely empty self.dir_hist[:] = [os.getcwd()] - self.writeout_cache() - self.init_db() # New session + if new_session: + self.writeout_cache() + self.init_db() # Get new session number # To match, e.g. ~5/8-~2/3 range_re = re.compile(r""" @@ -463,7 +472,7 @@ def magic_history(self, parameter_s = ''): n = int(args) except ValueError, IndexError: n = 10 - hist = history_manager.get_hist_tail(n, raw=raw) + hist = history_manager.get_hist_tail(n, raw=raw, output=get_output) else: if args: # Get history by ranges hist = history_manager.get_hist_from_rangestr(args, raw, get_output) @@ -471,6 +480,8 @@ def magic_history(self, parameter_s = ''): hist = history_manager.get_history(raw=raw, output=get_output) # Pull hist into a list, so we can get the widest number in it. hist = list(hist) + if not hist: + return width = max(len(_format_lineno(s, l)) for s, l, _ in hist) @@ -496,7 +507,7 @@ def magic_history(self, parameter_s = ''): inline = "\n... ".join(inline.splitlines()) + "\n..." print(inline, file=outfile) if get_output and output: - print(repr(output), file=outfile) + print(output, file=outfile) if close_at_end: outfile.close() diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 7a82d62..7988cdd 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -990,14 +990,16 @@ class InteractiveShell(Configurable, Magic): # Finally, update the real user's namespace self.user_ns.update(ns) - def reset(self): + def reset(self, new_session=True): """Clear all internal namespaces. Note that this is much more aggressive than %reset, since it clears fully all namespaces, as well as all input/output lists. + + If new_session is True, a new history session will be opened. """ # Clear histories - self.history_manager.reset() + self.history_manager.reset(new_session) # Reset counter used to index all histories self.execution_count = 0 @@ -1266,9 +1268,6 @@ class InteractiveShell(Configurable, Magic): self.reload_history() return wrapper - def get_history(self, start=1, stop=None, raw=False, output=True): - return self.history_manager.get_history(start, stop, raw, output) - #------------------------------------------------------------------------- # Things related to exception handling and tracebacks (not debugging) @@ -2194,8 +2193,8 @@ class InteractiveShell(Configurable, Magic): magic calls (%magic), special shell access (!cmd), etc. """ - if isinstance(lines, (list, tuple)): - lines = '\n'.join(lines) + if not isinstance(lines, (list, tuple)): + lines = lines.splitlines() if clean: lines = self._cleanup_ipy_script(lines) @@ -2203,7 +2202,6 @@ class InteractiveShell(Configurable, Magic): # 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() - lines = lines.splitlines() # Since we will prefilter all lines, store the user's raw input too # before we apply any transformations @@ -2533,7 +2531,7 @@ class InteractiveShell(Configurable, Magic): self.history_manager.writeout_cache() # Clear all user namespaces to release all references cleanly. - self.reset() + self.reset(new_session=False) # Run user hooks self.hooks.shutdown_hook() diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index 72f6f66..4fcaee6 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -157,7 +157,6 @@ def test_macro(): cmds = ["a=1", "def b():\n return a**2", "print(a,b())"] for i, cmd in enumerate(cmds, start=1): ip.history_manager.store_inputs(i, cmd) - print i, cmd ip.magic("macro test 1-3") nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n") diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index 626c91f..62e12c3 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -158,15 +158,12 @@ class IPythonWidget(FrontendWidget): else: super(IPythonWidget, self)._handle_execute_reply(msg) - def _handle_history_reply(self, msg): - """ Implemented to handle history replies, which are only supported by - the IPython kernel. + def _handle_history_tail_reply(self, msg): + """ Implemented to handle history tail replies, which are only supported + by the IPython kernel. """ - history_dict = msg['content']['history'] - input_history_dict = {} - for key,val in history_dict.items(): - input_history_dict[int(key)] = val - items = [ val.rstrip() for _, val in sorted(input_history_dict.items()) ] + history_items = msg['content']['history'] + items = [ line.rstrip() for _, _, line in history_items ] self._set_history(items) def _handle_pyout(self, msg): @@ -213,8 +210,7 @@ class IPythonWidget(FrontendWidget): """ Reimplemented to make a history request. """ super(IPythonWidget, self)._started_channels() - self.kernel_manager.xreq_channel.history(raw=True, output=False, - this_session=False) + self.kernel_manager.xreq_channel.history_tail(1000) #--------------------------------------------------------------------------- # 'ConsoleWidget' public interface diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index c3d2754..7460bb2 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -107,7 +107,7 @@ class Kernel(Configurable): # Build dict of handlers for message types msg_types = [ 'execute_request', 'complete_request', - 'object_info_request', 'history_request', + 'object_info_request', 'history_tail_request', 'connect_request', 'shutdown_request'] self.handlers = {} for msg_type in msg_types: @@ -308,12 +308,11 @@ class Kernel(Configurable): oinfo, parent, ident) logger.debug(msg) - def history_request(self, ident, parent): - # parent['content'] should contain keys "index", "raw", "output" and - # "this_session". - hist = self.shell.get_history(**parent['content']) - content = {'history' : hist} - msg = self.session.send(self.reply_socket, 'history_reply', + def history_tail_request(self, ident, parent): + # parent['content'] should contain keys "n", "raw" and "output" + hist = self.shell.history_manager.get_hist_tail(**parent['content']) + content = {'history' : list(hist)} + msg = self.session.send(self.reply_socket, 'history_tail_reply', content, parent, ident) logger.debug(str(msg)) diff --git a/IPython/zmq/kernelmanager.py b/IPython/zmq/kernelmanager.py index b9c8421..e8d9fb5 100644 --- a/IPython/zmq/kernelmanager.py +++ b/IPython/zmq/kernelmanager.py @@ -282,30 +282,24 @@ class XReqSocketChannel(ZmqSocketChannel): self._queue_request(msg) return msg['header']['msg_id'] - def history(self, index=None, raw=False, output=True, this_session=True): + def history_tail(self, n=10, raw=True, output=False): """Get the history list. Parameters ---------- - index : n or (n1, n2) or None - If n, then the last entries. If a tuple, then all in - range(n1, n2). If None, then all entries. Raises IndexError if - the format of index is incorrect. + n : int + The number of lines of history to get. raw : bool If True, return the raw input. output : bool If True, then return the output as well. - this_session : bool - If True, returns only history from the current session. Otherwise, - includes reloaded history from previous sessions. Returns ------- The msg_id of the message sent. """ - content = dict(index=index, raw=raw, output=output, - this_session=this_session) - msg = self.session.msg('history_request', content) + content = dict(n=n, raw=raw, output=output) + msg = self.session.msg('history_tail_request', content) self._queue_request(msg) return msg['header']['msg_id']