##// END OF EJS Templates
Addressed issues: renamed ZMQHistoryManager (appears to do need to do more than just an Accessor) in IPython/terminal/console/zmqhistory.py; added abc methods; rewrote access methods to load the history from the kernel client; works with 'ipython console' and with 'ipython console --kernel'
Doug Blank -
Show More
@@ -0,0 +1,111 b''
1 """ ZMQ Kernel History accessor and manager. """
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2010-2011 The IPython Development Team.
4 #
5 # Distributed under the terms of the BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 from IPython.core.history import HistoryAccessorBase
15 from IPython.utils import py3compat
16 from IPython.utils.traitlets import Dict, List
17
18 try:
19 from queue import Empty # Py 3
20 except ImportError:
21 from Queue import Empty # Py 2
22
23 class ZMQHistoryManager(HistoryAccessorBase):
24 """History accessor and manager for ZMQ-based kernels"""
25 input_hist_parsed = List([""])
26 output_hist = Dict()
27 dir_hist = List()
28 output_hist_reprs = Dict()
29
30 def __init__(self, client):
31 """
32 Class to load the command-line history from a ZMQ-based kernel,
33 and access the history.
34
35 Parameters
36 ----------
37
38 client: `IPython.kernel.KernelClient`
39 The kernel client in order to request the history.
40 """
41 self.client = client
42
43 def _load_history(self, raw=True, output=False, hist_access_type='range',
44 **kwargs):
45 """
46 Load the history over ZMQ from the kernel. Wraps the history
47 messaging with loop to wait to get history results.
48 """
49 # 'range' (fill in session, start and stop params),
50 # 'tail' (fill in n)
51 # 'search' (fill in pattern param).
52 msg_id = self.client.history(raw=raw, output=output,
53 hist_access_type=hist_access_type,
54 **kwargs)
55 history = []
56 while True:
57 try:
58 reply = self.client.get_shell_msg(timeout=1)
59 except Empty:
60 break
61 else:
62 if reply['parent_header'].get('msg_id') == msg_id:
63 history = reply['content'].get('history', [])
64 break
65 return history
66
67 def writeout_cache(self):
68 """
69 Not needed for ZMQ-based histories.
70 """
71 pass
72
73 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
74 return self._load_history(hist_access_type='tail', n=n, raw=raw,
75 output=output)
76
77 def search(self, pattern="*", raw=True, search_raw=True,
78 output=False, n=None, unique=False):
79 return self._load_history(hist_access_type='search', pattern=pattern,
80 raw=raw, search_raw=search_raw,
81 output=output, n=n, unique=unique)
82
83 def get_range(self, session, start=1, stop=None, raw=True,output=False):
84 return self._load_history(hist_access_type='range', raw=raw,
85 output=output, start=start, stop=stop,
86 session=session)
87
88 def get_range_by_str(self, rangestr, raw=True, output=False):
89 return self._load_history(hist_access_type='range', raw=raw,
90 output=output, rangestr=rangetr)
91
92 def end_session(self):
93 """
94 Nothing to do for ZMQ-based histories.
95 """
96 pass
97
98 def reset(self, new_session=True):
99 """Clear the session history, releasing all object references, and
100 optionally open a new session."""
101 self.output_hist.clear()
102 # The directory history can't be completely empty
103 self.dir_hist[:] = [py3compat.getcwd()]
104
105 if new_session:
106 if self.session_number:
107 self.end_session()
108 self.input_hist_parsed[:] = [""]
109 self.input_hist_raw[:] = [""]
110 self.new_session()
111
@@ -15,6 +15,7 b' from __future__ import print_function'
15 # Stdlib imports
15 # Stdlib imports
16 import atexit
16 import atexit
17 import datetime
17 import datetime
18 import abc
18 import os
19 import os
19 import re
20 import re
20 try:
21 try:
@@ -26,17 +27,13 b' except ImportError:'
26 sqlite3 = None
27 sqlite3 = None
27 import threading
28 import threading
28
29
29 try:
30 from queue import Empty # Py 3
31 except ImportError:
32 from Queue import Empty # Py 2
33
34 # Our own packages
30 # Our own packages
35 from IPython.config.configurable import Configurable
31 from IPython.config.configurable import Configurable
36 from IPython.external.decorator import decorator
32 from IPython.external.decorator import decorator
37 from IPython.utils.decorators import undoc
33 from IPython.utils.decorators import undoc
38 from IPython.utils.path import locate_profile
34 from IPython.utils.path import locate_profile
39 from IPython.utils import py3compat
35 from IPython.utils import py3compat
36 from IPython.utils.py3compat import with_metaclass
40 from IPython.utils.traitlets import (
37 from IPython.utils.traitlets import (
41 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
38 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
42 )
39 )
@@ -104,52 +101,23 b' def catch_corrupt_db(f, self, *a, **kw):'
104 raise
101 raise
105
102
106 class HistoryAccessorBase(Configurable):
103 class HistoryAccessorBase(Configurable):
107 input_hist_parsed = List([""])
104 """An abstract class for History Accessors """
108 input_hist_raw = List([""])
109 output_hist = Dict()
110 dir_hist = List()
111 output_hist_reprs = Dict()
112
113 def end_session(self):
114 pass
115
116 def reset(self, new_session=True):
117 """Clear the session history, releasing all object references, and
118 optionally open a new session."""
119 self.output_hist.clear()
120 # The directory history can't be completely empty
121 self.dir_hist[:] = [py3compat.getcwd()]
122
123 if new_session:
124 if self.session_number:
125 self.end_session()
126 self.input_hist_parsed[:] = [""]
127 self.input_hist_raw[:] = [""]
128 self.new_session()
129
130 def new_session(self, conn=None):
131 pass
132
133 def writeout_cache(self):
134 pass
135
105
106 @abc.abstractmethod
136 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
107 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
137 return []
108 pass
138
109
110 @abc.abstractmethod
139 def search(self, pattern="*", raw=True, search_raw=True,
111 def search(self, pattern="*", raw=True, search_raw=True,
140 output=False, n=None, unique=False):
112 output=False, n=None, unique=False):
141 return []
113 pass
142
114
115 @abc.abstractmethod
143 def get_range(self, session, start=1, stop=None, raw=True,output=False):
116 def get_range(self, session, start=1, stop=None, raw=True,output=False):
144 return []
145
146 def get_range_by_str(self, rangestr, raw=True, output=False):
147 return []
148
149 def store_inputs(self, line_num, source, source_raw=None):
150 pass
117 pass
151
118
152 def store_output(self, line_num):
119 @abc.abstractmethod
120 def get_range_by_str(self, rangestr, raw=True, output=False):
153 pass
121 pass
154
122
155 class HistoryAccessor(HistoryAccessorBase):
123 class HistoryAccessor(HistoryAccessorBase):
@@ -800,54 +768,6 b' class HistoryManager(HistoryAccessor):'
800 finally:
768 finally:
801 self.db_output_cache = []
769 self.db_output_cache = []
802
770
803 class KernelHistoryManager(HistoryAccessorBase):
804 def __init__(self, client):
805 self.client = client
806 self._load_history()
807
808 def _load_history(self):
809 msg_id = self.client.history()
810 while True:
811 try:
812 reply = self.client.get_shell_msg(timeout=1)
813 except Empty:
814 break
815 else:
816 if reply['parent_header'].get('msg_id') == msg_id:
817 history = reply['content'].get('history', [])
818 break
819 self.history = history
820 print("_load_history:", self.history)
821
822 def writeout_cache(self):
823 """dump cache before certain database lookups."""
824 print("write_cache")
825
826 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
827 print("get_tail: ", n)
828 return self.history[-n:]
829
830 def search(self, pattern="*", raw=True, search_raw=True,
831 output=False, n=None, unique=False):
832 print("search: ", pattern)
833 return []
834
835 def get_range(self, session, start=1, stop=None, raw=True,output=False):
836 print("get_range: ", start, stop)
837 if stop is None:
838 stop = -1
839 return self.history[start:stop]
840
841 def get_range_by_str(self, rangestr, raw=True, output=False):
842 print("get_range_by_str: " + rangestr)
843 return []
844
845 def store_inputs(self, line_num, source, source_raw=None):
846 print("store_inputs")
847
848 def store_output(self, line_num):
849 print("store_output")
850
851
771
852 class HistorySavingThread(threading.Thread):
772 class HistorySavingThread(threading.Thread):
853 """This thread takes care of writing history to the database, so that
773 """This thread takes care of writing history to the database, so that
@@ -23,7 +23,7 b' except ImportError:'
23
23
24 from IPython.core import page
24 from IPython.core import page
25 from IPython.core import release
25 from IPython.core import release
26 from IPython.core.history import KernelHistoryManager
26 from IPython.terminal.console.zmqhistory import ZMQHistoryManager
27 from IPython.utils.warn import warn, error
27 from IPython.utils.warn import warn, error
28 from IPython.utils import io
28 from IPython.utils import io
29 from IPython.utils.py3compat import string_types, input
29 from IPython.utils.py3compat import string_types, input
@@ -573,6 +573,6 b' class ZMQTerminalInteractiveShell(TerminalInteractiveShell):'
573
573
574 def init_history(self):
574 def init_history(self):
575 """Sets up the command history. """
575 """Sets up the command history. """
576 self.history_manager = KernelHistoryManager(client=self.client)
576 self.history_manager = ZMQHistoryManager(client=self.client)
577 self.configurables.append(self.history_manager)
577 self.configurables.append(self.history_manager)
578
578
General Comments 0
You need to be logged in to leave comments. Login now