From 0da365682b64396002a183e2956f37baf14ac30d 2010-01-12 11:12:25 From: Fernando Perez Date: 2010-01-12 11:12:25 Subject: [PATCH] Changed %hist to default to NOT printing numbers, added -p and -o options. -p: print python prompts before inputs -o: print output as well Together, these two make '%hist -op' an easy way to get doctest-valid sessions generated from prior input. --- diff --git a/IPython/core/history.py b/IPython/core/history.py index db08d1e..ca290ca 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -14,20 +14,25 @@ def magic_history(self, parameter_s = ''): %history -> print at most 40 inputs (some may be multi-line)\\ %history n -> print at most n inputs\\ %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\ - - Each input's number is shown, and is accessible as the - automatically generated variable _i. Multi-line statements are - printed starting at a new line for easy copy/paste. - - Options: + By default, input history is printed without line numbers so it can be + directly pasted into an editor. + + With -n, each input's number is shown, and is accessible as the + automatically generated variable _i as well as In[]. Multi-line + statements are printed starting at a new line for easy copy/paste. - -n: do NOT print line numbers. This is useful if you want to get a - printout of many lines which can be directly pasted into a text - editor. + Options: + -n: print line numbers for each input. This feature is only available if numbered prompts are in use. + -o: also print outputs for each input. + + -p: print classic '>>>' python prompts before each input. This is useful + for making documentation, and in conjunction with -o, for producing + doctest-ready output. + -t: (default) print the 'translated' history, as IPython understands it. IPython filters your input and converts it all into valid Python source before executing it (things like magics or aliases are turned into @@ -50,7 +55,7 @@ def magic_history(self, parameter_s = ''): if not self.outputcache.do_full_cache: print 'This feature is only available if numbered prompts are in use.' return - opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list') + opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list') # Check if output to specific file was requested. try: @@ -97,9 +102,12 @@ def magic_history(self, parameter_s = ''): warn('%hist takes 0, 1 or 2 arguments separated by spaces.') print self.magic_hist.__doc__ return + width = len(str(final)) line_sep = ['','\n'] - print_nums = not opts.has_key('n') + print_nums = 'n' in opts + print_outputs = 'o' in opts + pyprompts = 'p' in opts found = False if pattern is not None: @@ -123,7 +131,19 @@ def magic_history(self, parameter_s = ''): if print_nums: print >> outfile, \ '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]), - print >> outfile, inline, + if pyprompts: + print >> outfile, '>>>', + if multiline: + lines = inline.splitlines() + print >> outfile, '\n... '.join(lines) + print >> outfile, '... ' + else: + print >> outfile, inline, + else: + print >> outfile, inline, + output = self.shell.user_ns['Out'].get(in_num) + if output is not None: + print repr(output) if close_at_end: outfile.close() diff --git a/IPython/core/iplib.py b/IPython/core/iplib.py index 163a299..f03546f 100644 --- a/IPython/core/iplib.py +++ b/IPython/core/iplib.py @@ -1619,7 +1619,6 @@ class InteractiveShell(Component, Magic): valid Python code you can type at the interpreter, including loops and compound statements. """ - args = arg_s.split(' ',1) magic_name = args[0] magic_name = magic_name.lstrip(prefilter.ESC_MAGIC) diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index 919880e..a84014a 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -60,18 +60,86 @@ def doctest_hist_f(): def doctest_hist_r(): """Test %hist -r - XXX - This test is not recording the output correctly. Not sure why... + XXX - This test is not recording the output correctly. For some reason, in + testing mode the raw history isn't getting populated. No idea why. + Disabling the output checking for now, though at least we do run it. - In [20]: 'hist' in _ip.lsmagic() - Out[20]: True + In [1]: 'hist' in _ip.lsmagic() + Out[1]: True - In [6]: x=1 + In [2]: x=1 - In [7]: %hist -n -r 2 - x=1 # random - hist -n -r 2 # random + In [3]: %hist -r 2 + x=1 # random + %hist -r 2 """ +def doctest_hist_op(): + """Test %hist -op + + In [1]: class b: + ...: pass + ...: + + In [2]: class s(b): + ...: def __str__(self): + ...: return 's' + ...: + + In [3]: + + In [4]: class r(b): + ...: def __repr__(self): + ...: return 'r' + ...: + + In [5]: class sr(s,r): pass + ...: + + In [6]: + + In [7]: bb=b() + + In [8]: ss=s() + + In [9]: rr=r() + + In [10]: ssrr=sr() + + In [11]: bb + Out[11]: <...b instance at ...> + + In [12]: ss + Out[12]: <...s instance at ...> + + In [13]: + + In [14]: %hist -op + >>> class b: + ... pass + ... + >>> class s(b): + ... def __str__(self): + ... return 's' + ... + >>> + >>> class r(b): + ... def __repr__(self): + ... return 'r' + ... + >>> class sr(s,r): pass + >>> + >>> bb=b() + >>> ss=s() + >>> rr=r() + >>> ssrr=sr() + >>> bb + <...b instance at ...> + >>> ss + <...s instance at ...> + >>> + >>> get_ipython().magic("hist -op") + """ def test_shist(): # Simple tests of ShadowHist class - test generator. diff --git a/IPython/testing/globalipapp.py b/IPython/testing/globalipapp.py index 222c28a..936bb62 100644 --- a/IPython/testing/globalipapp.py +++ b/IPython/testing/globalipapp.py @@ -134,12 +134,9 @@ def start_ipython(): ip = ipapp.IPythonApp(argv, user_ns=user_ns, user_global_ns=global_ns) ip.initialize() ip.shell.builtin_trap.set() - # Set stderr to stdout so nose can doctest exceptions - ## Term.cerr = sys.stdout - ## sys.stderr = sys.stdout + + # Set error printing to stdout so nose can doctest exceptions ip.shell.InteractiveTB.out_stream = 'stdout' - # Butcher the logger - ip.shell.log = lambda *a,**k: None # Deactivate the various python system hooks added by ipython for # interactive convenience so we don't confuse the doctest system @@ -160,12 +157,4 @@ def start_ipython(): # doctest machinery would miss them. ip.shell.system = xsys - # XXX - For some very bizarre reason, the loading of %history by default is - # failing. This needs to be fixed later, but for now at least this ensures - # that tests that use %hist run to completion. - from IPython.core import history - history.init_ipython(ip.shell) - if not hasattr(ip.shell,'magic_history'): - raise RuntimeError("Can't load magics, aborting") - return _ip