From 6a7882f7944eac08b5080cec556c63ac38010526 2014-11-13 01:44:54 From: Doug Blank Date: 2014-11-13 01:44:54 Subject: [PATCH] Working draft of KernelHistoryManager --- diff --git a/IPython/core/history.py b/IPython/core/history.py index c9b8435..64c0e16 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -26,6 +26,11 @@ except ImportError: sqlite3 = None import threading +try: + from queue import Empty # Py 3 +except ImportError: + from Queue import Empty # Py 2 + # Our own packages from IPython.config.configurable import Configurable from IPython.external.decorator import decorator @@ -98,9 +103,56 @@ def catch_corrupt_db(f, self, *a, **kw): # The hist_file is probably :memory: or something else. raise +class HistoryAccessorBase(Configurable): + input_hist_parsed = List([""]) + input_hist_raw = List([""]) + output_hist = Dict() + dir_hist = List() + output_hist_reprs = Dict() + + def end_session(self): + pass + + def reset(self, new_session=True): + """Clear the session history, releasing all object references, and + optionally open a new session.""" + self.output_hist.clear() + # The directory history can't be completely empty + self.dir_hist[:] = [py3compat.getcwd()] + + if new_session: + if self.session_number: + self.end_session() + self.input_hist_parsed[:] = [""] + self.input_hist_raw[:] = [""] + self.new_session() + + def new_session(self, conn=None): + pass + + def writeout_cache(self): + pass + + def get_tail(self, n=10, raw=True, output=False, include_latest=False): + return [] + + def search(self, pattern="*", raw=True, search_raw=True, + output=False, n=None, unique=False): + return [] + + def get_range(self, session, start=1, stop=None, raw=True,output=False): + return [] + + def get_range_by_str(self, rangestr, raw=True, output=False): + return [] + + def store_inputs(self, line_num, source, source_raw=None): + pass + def store_output(self, line_num): + pass -class HistoryAccessor(Configurable): +class HistoryAccessor(HistoryAccessorBase): """Access the history database without adding to it. This is intended for use by standalone history tools. IPython shells use @@ -544,7 +596,7 @@ class HistoryManager(HistoryAccessor): self.input_hist_parsed[:] = [""] self.input_hist_raw[:] = [""] self.new_session() - + # ------------------------------ # Methods for retrieving history # ------------------------------ @@ -748,6 +800,54 @@ class HistoryManager(HistoryAccessor): finally: self.db_output_cache = [] +class KernelHistoryManager(HistoryAccessorBase): + def __init__(self, client): + self.client = client + self._load_history() + + def _load_history(self): + msg_id = self.client.history() + while True: + try: + reply = self.client.get_shell_msg(timeout=1) + except Empty: + break + else: + if reply['parent_header'].get('msg_id') == msg_id: + history = reply['content'].get('history', []) + break + self.history = history + print("_load_history:", self.history) + + def writeout_cache(self): + """dump cache before certain database lookups.""" + print("write_cache") + + def get_tail(self, n=10, raw=True, output=False, include_latest=False): + print("get_tail: ", n) + return self.history[-n:] + + def search(self, pattern="*", raw=True, search_raw=True, + output=False, n=None, unique=False): + print("search: ", pattern) + return [] + + def get_range(self, session, start=1, stop=None, raw=True,output=False): + print("get_range: ", start, stop) + if stop is None: + stop = -1 + return self.history[start:stop] + + def get_range_by_str(self, rangestr, raw=True, output=False): + print("get_range_by_str: " + rangestr) + return [] + + def store_inputs(self, line_num, source, source_raw=None): + print("store_inputs") + + def store_output(self, line_num): + print("store_output") + class HistorySavingThread(threading.Thread): """This thread takes care of writing history to the database, so that diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 2e27f80..06752ba 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -424,7 +424,7 @@ class InteractiveShell(SingletonConfigurable): display_trap = Instance('IPython.core.display_trap.DisplayTrap') extension_manager = Instance('IPython.core.extensions.ExtensionManager') payload_manager = Instance('IPython.core.payload.PayloadManager') - history_manager = Instance('IPython.core.history.HistoryManager') + history_manager = Instance('IPython.core.history.HistoryAccessorBase') magics_manager = Instance('IPython.core.magic.MagicsManager') profile_dir = Instance('IPython.core.application.ProfileDir') diff --git a/IPython/terminal/console/interactiveshell.py b/IPython/terminal/console/interactiveshell.py index f0d7b73..3a68cb4 100644 --- a/IPython/terminal/console/interactiveshell.py +++ b/IPython/terminal/console/interactiveshell.py @@ -23,6 +23,7 @@ except ImportError: from IPython.core import page from IPython.core import release +from IPython.core.history import KernelHistoryManager from IPython.utils.warn import warn, error from IPython.utils import io from IPython.utils.py3compat import string_types, input @@ -32,7 +33,6 @@ from IPython.utils.tempdir import NamedFileInTemporaryDirectory from IPython.terminal.interactiveshell import TerminalInteractiveShell from IPython.terminal.console.completer import ZMQCompleter - class ZMQTerminalInteractiveShell(TerminalInteractiveShell): """A subclass of TerminalInteractiveShell that uses the 0MQ kernel""" _executing = False @@ -570,3 +570,9 @@ class ZMQTerminalInteractiveShell(TerminalInteractiveShell): # Turn off the exit flag, so the mainloop can be restarted if desired self.exit_now = False + + def init_history(self): + """Sets up the command history. """ + self.history_manager = KernelHistoryManager(client=self.client) + self.configurables.append(self.history_manager) +