From 7425745bce7a04ad0dce41b22f03bebe1d2cdd20 2010-08-19 04:58:55 From: Brian Granger Date: 2010-08-19 04:58:55 Subject: [PATCH] First draft of history msg. * Added get_history method of InteractiveShell. * Added history_request/reply msg in ipkernel. I have changed the msg format slightly and changed the docs to reflect that. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index d48b407..fd335d9 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1081,6 +1081,54 @@ class InteractiveShell(Configurable, Magic): readline.read_history_file(self.histfile) return wrapper + def get_history(self, index=None, raw=False, output=True): + """Get the history list. + + Get the input and output history. + + 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. + raw : bool + If True, return the raw input. + output : bool + If True, then return the output as well. + + Returns + ------- + If output is True, then return a dict of tuples, keyed by the prompt + numbers and with values of (input, output). If output is False, then + a dict, keyed by the prompt number with the values of input. Raises + IndexError if no history is found. + """ + if raw: + input_hist = self.input_hist_raw + else: + input_hist = self.input_hist + if output: + output_hist = self.user_ns['Out'] + n = len(input_hist) + if index is None: + start=0; stop=n + elif isinstance(index, int): + start=n-index; stop=n + elif isinstance(index, tuple) and len(index) == 2: + start=index[0]; stop=index[1] + else: + raise IndexError('Not a valid index for the input history: %r' % index) + hist = {} + for i in range(start, stop): + if output: + hist[i] = (input_hist[i], output_hist.get(i)) + else: + hist[i] = input_hist[i] + if len(hist)==0: + raise IndexError('No history for range of indices: %r' % index) + return hist + #------------------------------------------------------------------------- # Things related to exception handling and tracebacks (not debugging) #------------------------------------------------------------------------- diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index d9f9afc..1a96697 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -55,7 +55,8 @@ class Kernel(Configurable): # Build dict of handlers for message types msg_types = [ 'execute_request', 'complete_request', - 'object_info_request', 'prompt_request' ] + 'object_info_request', 'prompt_request', + 'history_request' ] self.handlers = {} for msg_type in msg_types: self.handlers[msg_type] = getattr(self, msg_type) @@ -214,6 +215,16 @@ class Kernel(Configurable): content, parent, ident) print >> sys.__stdout__, msg + def history_request(self, ident, parent): + output = parent['content'].get('output', True) + index = parent['content'].get('index') + raw = parent['content'].get('raw', False) + hist = self.shell.get_history(index=index, raw=raw, output=output) + content = {'history' : hist} + msg = self.session.send(self.reply_socket, 'history_reply', + content, parent, ident) + print >> sys.__stdout__, msg + def start(self): while True: ident = self.reply_socket.recv() diff --git a/docs/source/development/messaging.txt b/docs/source/development/messaging.txt index e2c0dc4..bd5a80a 100644 --- a/docs/source/development/messaging.txt +++ b/docs/source/development/messaging.txt @@ -372,15 +372,18 @@ Message type: ``history_request``:: content = { - # If true, also return output history in the resulting dict. + # If True, also return output history in the resulting dict. 'output' : bool, - # This parameter can be one of: A number, a pair of numbers, 'all' + # If True, return the raw input history, else the transformed input. + 'raw' : bool, + + # This parameter can be one of: A number, a pair of numbers, None # If not given, last 40 are returned. # - number n: return the last n entries. # - pair n1, n2: return entries in the range(n1, n2). - # - 'all': return all history - 'range' : n or (n1, n2) or 'all', + # - None: return all history + 'range' : n or (n1, n2) or None, # If a filter is given, it is treated as a regular expression and only # matching entries are returned. re.search() is used to find matches. @@ -390,14 +393,11 @@ Message type: ``history_request``:: Message type: ``history_reply``:: content = { - # A list of (number, input) pairs - 'input' : list, - - # A list of (number, output) pairs - 'output' : list, - } - - + # A dict with prompt numbers as keys and either (input, output) or input + # as the value depending on whether output was True or False, + # respectively. + 'history' : dict, + } Messages on the PUB/SUB socket ==============================