##// END OF EJS Templates
Rename history retrieval methods, and improve docstrings.
Thomas Kluyver -
Show More
@@ -162,7 +162,7 b' class HistoryManager(Configurable):'
162 ## -------------------------------
162 ## -------------------------------
163 ## Methods for retrieving history:
163 ## Methods for retrieving history:
164 ## -------------------------------
164 ## -------------------------------
165 def _get_hist_sql(self, sql, params, raw=True, output=False):
165 def _run_sql(self, sql, params, raw=True, output=False):
166 """Prepares and runs an SQL query for the history database.
166 """Prepares and runs an SQL query for the history database.
167
167
168 Parameters
168 Parameters
@@ -171,15 +171,12 b' class HistoryManager(Configurable):'
171 Any filtering expressions to go after SELECT ... FROM ...
171 Any filtering expressions to go after SELECT ... FROM ...
172 params : tuple
172 params : tuple
173 Parameters passed to the SQL query (to replace "?")
173 Parameters passed to the SQL query (to replace "?")
174 raw : bool
174 raw, output : bool
175 If True, get raw input.
175 See :meth:`get_range`
176 output : bool
177 If True, include output where available.
178
176
179 Returns
177 Returns
180 -------
178 -------
181 An iterator over 3-tuples: (session, line_number, command), or if output
179 Tuples as :meth:`get_range`
182 is True, (session, line_number, (command, output)).
183 """
180 """
184 toget = 'source_raw' if raw else 'source'
181 toget = 'source_raw' if raw else 'source'
185 sqlfrom = "history"
182 sqlfrom = "history"
@@ -195,41 +192,61 b' class HistoryManager(Configurable):'
195 return cur
192 return cur
196
193
197
194
198 def get_hist_tail(self, n=10, raw=True, output=False, include_latest=False):
195 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
199 """Get the last n lines from the history database.
196 """Get the last n lines from the history database.
200
197
201 If include_latest is False (default), n+1 lines are fetched, and
198 Parameters
202 the latest one is discarded. This is intended to be used where
199 ----------
203 the function is called by a user command, which it should not
200 n : int
204 return."""
201 The number of lines to get
202 raw, output : bool
203 See :meth:`get_range`
204 include_latest : bool
205 If False (default), n+1 lines are fetched, and the latest one
206 is discarded. This is intended to be used where the function
207 is called by a user command, which it should not return.
208
209 Returns
210 -------
211 Tuples as :meth:`get_range`
212 """
205 self.writeout_cache()
213 self.writeout_cache()
206 if not include_latest:
214 if not include_latest:
207 n += 1
215 n += 1
208 cur = self._get_hist_sql("ORDER BY session DESC, line DESC LIMIT ?",
216 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
209 (n,), raw=raw, output=output)
217 (n,), raw=raw, output=output)
210 if not include_latest:
218 if not include_latest:
211 return reversed(list(cur)[1:])
219 return reversed(list(cur)[1:])
212 return reversed(list(cur))
220 return reversed(list(cur))
213
221
214 def get_hist_search(self, pattern="*", raw=True, search_raw=True,
222 def search(self, pattern="*", raw=True, search_raw=True,
215 output=False):
223 output=False):
216 """Search the database using unix glob-style matching (wildcards
224 """Search the database using unix glob-style matching (wildcards
217 * and ?).
225 * and ?).
218
226
227 Parameters
228 ----------
229 pattern : str
230 The wildcarded pattern to match when searching
231 search_raw : bool
232 If True, search the raw input, otherwise, the parsed input
233 raw, output : bool
234 See :meth:`get_range`
235
219 Returns
236 Returns
220 -------
237 -------
221 An iterator over tuples: (session, line_number, command)
238 Tuples as :meth:`get_range`
222 """
239 """
223 tosearch = "source_raw" if search_raw else "source"
240 tosearch = "source_raw" if search_raw else "source"
224 if output:
241 if output:
225 tosearch = "history." + tosearch
242 tosearch = "history." + tosearch
226 self.writeout_cache()
243 self.writeout_cache()
227 return self._get_hist_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
244 return self._run_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
228 raw=raw, output=output)
245 raw=raw, output=output)
229
246
230 def _get_hist_session(self, start=1, stop=None, raw=True, output=False):
247 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
231 """Get input and output history from the current session. Called by
248 """Get input and output history from the current session. Called by
232 get_history, and takes similar parameters."""
249 get_range, and takes similar parameters."""
233 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
250 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
234
251
235 n = len(input_hist)
252 n = len(input_hist)
@@ -247,7 +264,7 b' class HistoryManager(Configurable):'
247 line = input_hist[i]
264 line = input_hist[i]
248 yield (0, i, line)
265 yield (0, i, line)
249
266
250 def get_history(self, session=0, start=1, stop=None, raw=True,output=False):
267 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
251 """Retrieve input by session.
268 """Retrieve input by session.
252
269
253 Parameters
270 Parameters
@@ -275,7 +292,7 b' class HistoryManager(Configurable):'
275 (session, line, (input, output)) if output is True.
292 (session, line, (input, output)) if output is True.
276 """
293 """
277 if session == 0 or session==self.session_number: # Current session
294 if session == 0 or session==self.session_number: # Current session
278 return self._get_hist_session(start, stop, raw, output)
295 return self._get_range_session(start, stop, raw, output)
279 if session < 0:
296 if session < 0:
280 session += self.session_number
297 session += self.session_number
281
298
@@ -286,14 +303,27 b' class HistoryManager(Configurable):'
286 lineclause = "line>=?"
303 lineclause = "line>=?"
287 params = (session, start)
304 params = (session, start)
288
305
289 return self._get_hist_sql("WHERE session==? AND %s""" % lineclause,
306 return self._run_sql("WHERE session==? AND %s""" % lineclause,
290 params, raw=raw, output=output)
307 params, raw=raw, output=output)
291
308
292 def get_hist_from_rangestr(self, rangestr, raw=True, output=False):
309 def get_range_by_str(self, rangestr, raw=True, output=False):
293 """Get lines of history from a string of ranges, as used by magic
310 """Get lines of history from a string of ranges, as used by magic
294 commands %hist, %save, %macro, etc."""
311 commands %hist, %save, %macro, etc.
312
313 Parameters
314 ----------
315 rangestr : str
316 A string specifying ranges, e.g. "5 ~2/1-4". See
317 :func:`magic_history` for full details.
318 raw, output : bool
319 As :meth:`get_range`
320
321 Returns
322 -------
323 Tuples as :meth:`get_range`
324 """
295 for sess, s, e in extract_hist_ranges(rangestr):
325 for sess, s, e in extract_hist_ranges(rangestr):
296 for line in self.get_history(sess, s, e, raw=raw, output=output):
326 for line in self.get_range(sess, s, e, raw=raw, output=output):
297 yield line
327 yield line
298
328
299 ## ----------------------------
329 ## ----------------------------
@@ -350,7 +380,13 b' class HistoryManager(Configurable):'
350 def store_output(self, line_num):
380 def store_output(self, line_num):
351 """If database output logging is enabled, this saves all the
381 """If database output logging is enabled, this saves all the
352 outputs from the indicated prompt number to the database. It's
382 outputs from the indicated prompt number to the database. It's
353 called by run_cell after code has been executed."""
383 called by run_cell after code has been executed.
384
385 Parameters
386 ----------
387 line_num : int
388 The line number from which to save outputs
389 """
354 if (not self.db_log_output) or not self.output_hist_reprs[line_num]:
390 if (not self.db_log_output) or not self.output_hist_reprs[line_num]:
355 return
391 return
356 output = json.dumps(self.output_hist_reprs[line_num])
392 output = json.dumps(self.output_hist_reprs[line_num])
@@ -428,11 +464,18 b" def magic_history(self, parameter_s = ''):"
428 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
464 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
429
465
430 By default, input history is printed without line numbers so it can be
466 By default, input history is printed without line numbers so it can be
431 directly pasted into an editor.
467 directly pasted into an editor. Use -n to show them.
432
468
433 With -n, each input's number <n> is shown, and is accessible as the
469 Ranges of history can be indicated using the syntax:
434 automatically generated variable _i<n> as well as In[<n>]. Multi-line
470 4 : Line 4, current session
435 statements are printed starting at a new line for easy copy/paste.
471 4-6 : Lines 4-6, current session
472 243/1-5: Lines 1-5, session 243
473 ~2/7 : Line 7, session 2 before current
474 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
475 of 6 sessions ago.
476 Multiple ranges can be entered, separated by spaces
477
478 The same syntax is used by %macro, %save, %edit, %rerun
436
479
437 Options:
480 Options:
438
481
@@ -516,19 +559,18 b" def magic_history(self, parameter_s = ''):"
516
559
517 if 'g' in opts: # Glob search
560 if 'g' in opts: # Glob search
518 pattern = "*" + args + "*" if args else "*"
561 pattern = "*" + args + "*" if args else "*"
519 hist = history_manager.get_hist_search(pattern, raw=raw,
562 hist = history_manager.search(pattern, raw=raw, output=get_output)
520 output=get_output)
521 elif 'l' in opts: # Get 'tail'
563 elif 'l' in opts: # Get 'tail'
522 try:
564 try:
523 n = int(args)
565 n = int(args)
524 except ValueError, IndexError:
566 except ValueError, IndexError:
525 n = 10
567 n = 10
526 hist = history_manager.get_hist_tail(n, raw=raw, output=get_output)
568 hist = history_manager.get_tail(n, raw=raw, output=get_output)
527 else:
569 else:
528 if args: # Get history by ranges
570 if args: # Get history by ranges
529 hist = history_manager.get_hist_from_rangestr(args, raw, get_output)
571 hist = history_manager.get_range_by_str(args, raw, get_output)
530 else: # Just get history for the current session
572 else: # Just get history for the current session
531 hist = history_manager.get_history(raw=raw, output=get_output)
573 hist = history_manager.get_range(raw=raw, output=get_output)
532
574
533 # We could be displaying the entire history, so let's not try to pull it
575 # We could be displaying the entire history, so let's not try to pull it
534 # into a list in memory. Anything that needs more space will just misalign.
576 # into a list in memory. Anything that needs more space will just misalign.
@@ -579,10 +621,10 b' def magic_rep(self, arg):'
579 Place history line 45 on the next input prompt. Use %hist to find
621 Place history line 45 on the next input prompt. Use %hist to find
580 out the number.
622 out the number.
581
623
582 %rep 1-4 6-7 3
624 %rep 1-4
583
625
584 Combine the specified lines into one cell, and place it on the next
626 Combine the specified lines into one cell, and place it on the next
585 input prompt. History slice syntax is the same as in %macro and %save.
627 input prompt. See %history for the slice syntax.
586
628
587 %rep foo+bar
629 %rep foo+bar
588
630
@@ -595,7 +637,7 b' def magic_rep(self, arg):'
595 self.set_next_input(str(self.shell.user_ns["_"]))
637 self.set_next_input(str(self.shell.user_ns["_"]))
596 return
638 return
597 # Get history range
639 # Get history range
598 histlines = self.history_manager.get_hist_from_rangestr(arg)
640 histlines = self.history_manager.get_range_by_str(arg)
599 cmd = "\n".join(x[2] for x in histlines)
641 cmd = "\n".join(x[2] for x in histlines)
600 if cmd:
642 if cmd:
601 self.set_next_input(cmd.rstrip())
643 self.set_next_input(cmd.rstrip())
@@ -604,7 +646,7 b' def magic_rep(self, arg):'
604 try: # Variable in user namespace
646 try: # Variable in user namespace
605 cmd = str(eval(arg, self.shell.user_ns))
647 cmd = str(eval(arg, self.shell.user_ns))
606 except Exception: # Search for term in history
648 except Exception: # Search for term in history
607 histlines = self.history_manager.get_hist_search("*"+arg+"*")
649 histlines = self.history_manager.search("*"+arg+"*")
608 for h in reversed([x[2] for x in histlines]):
650 for h in reversed([x[2] for x in histlines]):
609 if 'rep' in h:
651 if 'rep' in h:
610 continue
652 continue
@@ -618,7 +660,7 b" def magic_rerun(self, parameter_s=''):"
618 """Re-run previous input
660 """Re-run previous input
619
661
620 By default, you can specify ranges of input history to be repeated
662 By default, you can specify ranges of input history to be repeated
621 (as with %hist). With no arguments, it will repeat the last line.
663 (as with %history). With no arguments, it will repeat the last line.
622
664
623 Options:
665 Options:
624
666
@@ -630,10 +672,10 b" def magic_rerun(self, parameter_s=''):"
630 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
672 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
631 if "l" in opts: # Last n lines
673 if "l" in opts: # Last n lines
632 n = int(opts['l'])
674 n = int(opts['l'])
633 hist = self.history_manager.get_hist_tail(n)
675 hist = self.history_manager.get_tail(n)
634 elif "g" in opts: # Search
676 elif "g" in opts: # Search
635 p = "*"+opts['g']+"*"
677 p = "*"+opts['g']+"*"
636 hist = list(self.history_manager.get_hist_search(p))
678 hist = list(self.history_manager.search(p))
637 for l in reversed(hist):
679 for l in reversed(hist):
638 if "rerun" not in l[2]:
680 if "rerun" not in l[2]:
639 hist = [l] # The last match which isn't a %rerun
681 hist = [l] # The last match which isn't a %rerun
@@ -641,9 +683,9 b" def magic_rerun(self, parameter_s=''):"
641 else:
683 else:
642 hist = [] # No matches except %rerun
684 hist = [] # No matches except %rerun
643 elif args: # Specify history ranges
685 elif args: # Specify history ranges
644 hist = self.history_manager.get_hist_from_rangestr(args)
686 hist = self.history_manager.get_range_by_str(args)
645 else: # Last line
687 else: # Last line
646 hist = self.history_manager.get_hist_tail(1)
688 hist = self.history_manager.get_tail(1)
647 hist = [x[2] for x in hist]
689 hist = [x[2] for x in hist]
648 if not hist:
690 if not hist:
649 print("No lines in history match specification")
691 print("No lines in history match specification")
@@ -1550,7 +1550,7 b' class InteractiveShell(Configurable, Magic):'
1550 readline.set_history_length(self.history_length)
1550 readline.set_history_length(self.history_length)
1551
1551
1552 # Load the last 1000 lines from history
1552 # Load the last 1000 lines from history
1553 for _, _, cell in self.history_manager.get_hist_tail(1000,
1553 for _, _, cell in self.history_manager.get_tail(1000,
1554 include_latest=True):
1554 include_latest=True):
1555 if cell.strip(): # Ignore blank lines
1555 if cell.strip(): # Ignore blank lines
1556 for line in cell.splitlines():
1556 for line in cell.splitlines():
@@ -186,7 +186,7 b' python-profiler package from non-free.""")'
186
186
187 N-M -> include items N..M (closed endpoint)."""
187 N-M -> include items N..M (closed endpoint)."""
188 lines = self.shell.history_manager.\
188 lines = self.shell.history_manager.\
189 get_hist_from_rangestr(range_str, raw=raw)
189 get_range_by_str(range_str, raw=raw)
190 return "\n".join(x for _, _, x in lines)
190 return "\n".join(x for _, _, x in lines)
191
191
192 def arg_err(self,func):
192 def arg_err(self,func):
@@ -1976,9 +1976,7 b' Currently the magic system has the following functions:\\n"""'
1976 you had typed them. You just type 'name' at the prompt and the code
1976 you had typed them. You just type 'name' at the prompt and the code
1977 executes.
1977 executes.
1978
1978
1979 The notation for indicating number ranges is: n1-n2 means 'use line
1979 The syntax for indicating input ranges is described in %history.
1980 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
1981 using the lines numbered 5,6 and 7.
1982
1980
1983 Note: as a 'hidden' feature, you can also use traditional python slice
1981 Note: as a 'hidden' feature, you can also use traditional python slice
1984 notation, where N:M means numbers N through M-1.
1982 notation, where N:M means numbers N through M-1.
@@ -2048,9 +2046,8 b' Currently the magic system has the following functions:\\n"""'
2048 Python. If this option is given, the raw input as typed as the
2046 Python. If this option is given, the raw input as typed as the
2049 command line is used instead.
2047 command line is used instead.
2050
2048
2051 This function uses the same syntax as %macro for line extraction, but
2049 This function uses the same syntax as %history for input ranges,
2052 instead of creating a macro it saves the resulting string to the
2050 then saves the lines to the filename you specify.
2053 filename you specify.
2054
2051
2055 It adds a '.py' extension to the file if you don't do so yourself, and
2052 It adds a '.py' extension to the file if you don't do so yourself, and
2056 it asks for confirmation before overwriting existing files."""
2053 it asks for confirmation before overwriting existing files."""
@@ -2138,15 +2135,17 b' Currently the magic system has the following functions:\\n"""'
2138 Arguments:
2135 Arguments:
2139
2136
2140 If arguments are given, the following possibilites exist:
2137 If arguments are given, the following possibilites exist:
2138
2139 - If the argument is a filename, IPython will load that into the
2140 editor. It will execute its contents with execfile() when you exit,
2141 loading any code in the file into your interactive namespace.
2141
2142
2142 - The arguments are numbers or pairs of colon-separated numbers (like
2143 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
2143 1 4:8 9). These are interpreted as lines of previous input to be
2144 The syntax is the same as in the %history magic.
2144 loaded into the editor. The syntax is the same of the %macro command.
2145
2145
2146 - If the argument doesn't start with a number, it is evaluated as a
2146 - If the argument is a string variable, its contents are loaded
2147 variable and its contents loaded into the editor. You can thus edit
2147 into the editor. You can thus edit any string which contains
2148 any string which contains python code (including the result of
2148 python code (including the result of previous edits).
2149 previous edits).
2150
2149
2151 - If the argument is the name of an object (other than a string),
2150 - If the argument is the name of an object (other than a string),
2152 IPython will try to locate the file where it was defined and open the
2151 IPython will try to locate the file where it was defined and open the
@@ -2163,11 +2162,6 b' Currently the magic system has the following functions:\\n"""'
2163 '+NUMBER' parameter necessary for this feature. Good editors like
2162 '+NUMBER' parameter necessary for this feature. Good editors like
2164 (X)Emacs, vi, jed, pico and joe all do.
2163 (X)Emacs, vi, jed, pico and joe all do.
2165
2164
2166 - If the argument is not found as a variable, IPython will look for a
2167 file with that name (adding .py if necessary) and load it into the
2168 editor. It will execute its contents with execfile() when you exit,
2169 loading any code in the file into your interactive namespace.
2170
2171 After executing your code, %edit will return as output the code you
2165 After executing your code, %edit will return as output the code you
2172 typed in the editor (except when it was an existing file). This way
2166 typed in the editor (except when it was an existing file). This way
2173 you can reload the code in further invocations of %edit as a variable,
2167 you can reload the code in further invocations of %edit as a variable,
@@ -52,14 +52,14 b' def test_history():'
52 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
52 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
53 for i, cmd in enumerate(newcmds, start=1):
53 for i, cmd in enumerate(newcmds, start=1):
54 ip.history_manager.store_inputs(i, cmd)
54 ip.history_manager.store_inputs(i, cmd)
55 gothist = ip.history_manager.get_history(start=1, stop=4)
55 gothist = ip.history_manager.get_range(start=1, stop=4)
56 nt.assert_equal(list(gothist), zip([0,0,0],[1,2,3], newcmds))
56 nt.assert_equal(list(gothist), zip([0,0,0],[1,2,3], newcmds))
57 # Previous session:
57 # Previous session:
58 gothist = ip.history_manager.get_history(-1, 1, 4)
58 gothist = ip.history_manager.get_range(-1, 1, 4)
59 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
59 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
60
60
61 # Check get_hist_tail
61 # Check get_hist_tail
62 gothist = ip.history_manager.get_hist_tail(4, output=True,
62 gothist = ip.history_manager.get_tail(4, output=True,
63 include_latest=True)
63 include_latest=True)
64 expected = [(1, 3, (hist[-1], ["spam"])),
64 expected = [(1, 3, (hist[-1], ["spam"])),
65 (2, 1, (newcmds[0], None)),
65 (2, 1, (newcmds[0], None)),
@@ -67,15 +67,15 b' def test_history():'
67 (2, 3, (newcmds[2], None)),]
67 (2, 3, (newcmds[2], None)),]
68 nt.assert_equal(list(gothist), expected)
68 nt.assert_equal(list(gothist), expected)
69
69
70 gothist = ip.history_manager.get_hist_tail(2)
70 gothist = ip.history_manager.get_tail(2)
71 expected = [(2, 1, newcmds[0]),
71 expected = [(2, 1, newcmds[0]),
72 (2, 2, newcmds[1])]
72 (2, 2, newcmds[1])]
73 nt.assert_equal(list(gothist), expected)
73 nt.assert_equal(list(gothist), expected)
74
74
75 # Check get_hist_search
75 # Check get_hist_search
76 gothist = ip.history_manager.get_hist_search("*test*")
76 gothist = ip.history_manager.search("*test*")
77 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
77 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
78 gothist = ip.history_manager.get_hist_search("b*", output=True)
78 gothist = ip.history_manager.search("b*", output=True)
79 nt.assert_equal(list(gothist), [(1,3,(hist[2],["spam"]))] )
79 nt.assert_equal(list(gothist), [(1,3,(hist[2],["spam"]))] )
80
80
81 # Cross testing: check that magic %save can get previous session.
81 # Cross testing: check that magic %save can get previous session.
@@ -314,7 +314,7 b' class Kernel(Configurable):'
314 n = parent['content']['n']
314 n = parent['content']['n']
315 raw = parent['content']['raw']
315 raw = parent['content']['raw']
316 output = parent['content']['output']
316 output = parent['content']['output']
317 hist = self.shell.history_manager.get_hist_tail(n, raw=raw, output=output)
317 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output)
318 content = {'history' : list(hist)}
318 content = {'history' : list(hist)}
319 msg = self.session.send(self.reply_socket, 'history_tail_reply',
319 msg = self.session.send(self.reply_socket, 'history_tail_reply',
320 content, parent, ident)
320 content, parent, ident)
General Comments 0
You need to be logged in to leave comments. Login now