##// END OF EJS Templates
Changes for demos and access to raw history in %macro, %save and %edit....
fperez -
Show More
@@ -1,7 +1,7 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Magic functions for InteractiveShell.
3 3
4 $Id: Magic.py 1121 2006-02-01 21:12:20Z vivainio $"""
4 $Id: Magic.py 1126 2006-02-06 02:31:40Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
@@ -98,7 +98,7 b' license. To use profiling, please install"python2.3-profiler" from non-free.""")'
98 98
99 99 def default_option(self,fn,optstr):
100 100 """Make an entry in the options_table for fn, with value optstr"""
101
101
102 102 if fn not in self.lsmagic():
103 103 error("%s is not a magic function" % fn)
104 104 self.options_table[fn] = optstr
@@ -129,12 +129,19 b' license. To use profiling, please install"python2.3-profiler" from non-free.""")'
129 129 out.sort()
130 130 return out
131 131
132 def extract_input_slices(self,slices):
132 def extract_input_slices(self,slices,raw=False):
133 133 """Return as a string a set of input history slices.
134 134
135 The set of slices is given as a list of strings (like ['1','4:8','9'],
136 since this function is for use by magic functions which get their
137 arguments as strings.
135 Inputs:
136
137 - slices: the set of slices is given as a list of strings (like
138 ['1','4:8','9'], since this function is for use by magic functions
139 which get their arguments as strings.
140
141 Optional inputs:
142
143 - raw(False): by default, the processed input is used. If this is
144 true, the raw input history is used instead.
138 145
139 146 Note that slices can be called with two notations:
140 147
@@ -142,6 +149,11 b' license. To use profiling, please install"python2.3-profiler" from non-free.""")'
142 149
143 150 N-M -> include items N..M (closed endpoint)."""
144 151
152 if raw:
153 hist = self.shell.input_hist_raw
154 else:
155 hist = self.shell.input_hist
156
145 157 cmds = []
146 158 for chunk in slices:
147 159 if ':' in chunk:
@@ -152,7 +164,7 b' license. To use profiling, please install"python2.3-profiler" from non-free.""")'
152 164 else:
153 165 ini = int(chunk)
154 166 fin = ini+1
155 cmds.append(self.shell.input_hist[ini:fin])
167 cmds.append(hist[ini:fin])
156 168 return cmds
157 169
158 170 def _ofind(self,oname):
@@ -1606,7 +1618,14 b' Currently the magic system has the following functions:\\n"""'
1606 1618 """Define a set of input lines as a macro for future re-execution.
1607 1619
1608 1620 Usage:\\
1609 %macro name n1-n2 n3-n4 ... n5 .. n6 ...
1621 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1622
1623 Options:
1624
1625 -r: use 'raw' input. By default, the 'processed' history is used,
1626 so that magics are loaded in their transformed version to valid
1627 Python. If this option is given, the raw input as typed as the
1628 command line is used instead.
1610 1629
1611 1630 This will define a global variable called `name` which is a string
1612 1631 made of joining the slices and lines you specify (n1,n2,... numbers
@@ -1657,10 +1676,10 b' Currently the magic system has the following functions:\\n"""'
1657 1676
1658 1677 In [60]: exec In[44:48]+In[49]"""
1659 1678
1660 args = parameter_s.split()
1679 opts,args = self.parse_options(parameter_s,'r')
1661 1680 name,ranges = args[0], args[1:]
1662 1681 #print 'rng',ranges # dbg
1663 lines = self.extract_input_slices(ranges)
1682 lines = self.extract_input_slices(ranges,opts.has_key('r'))
1664 1683 macro = Macro(lines)
1665 1684 self.shell.user_ns.update({name:macro})
1666 1685 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
@@ -1671,7 +1690,14 b' Currently the magic system has the following functions:\\n"""'
1671 1690 """Save a set of lines to a given filename.
1672 1691
1673 1692 Usage:\\
1674 %save filename n1-n2 n3-n4 ... n5 .. n6 ...
1693 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
1694
1695 Options:
1696
1697 -r: use 'raw' input. By default, the 'processed' history is used,
1698 so that magics are loaded in their transformed version to valid
1699 Python. If this option is given, the raw input as typed as the
1700 command line is used instead.
1675 1701
1676 1702 This function uses the same syntax as %macro for line extraction, but
1677 1703 instead of creating a macro it saves the resulting string to the
@@ -1680,7 +1706,7 b' Currently the magic system has the following functions:\\n"""'
1680 1706 It adds a '.py' extension to the file if you don't do so yourself, and
1681 1707 it asks for confirmation before overwriting existing files."""
1682 1708
1683 args = parameter_s.split()
1709 opts,args = self.parse_options(parameter_s,'r')
1684 1710 fname,ranges = args[0], args[1:]
1685 1711 if not fname.endswith('.py'):
1686 1712 fname += '.py'
@@ -1689,7 +1715,7 b' Currently the magic system has the following functions:\\n"""'
1689 1715 if ans.lower() not in ['y','yes']:
1690 1716 print 'Operation cancelled.'
1691 1717 return
1692 cmds = ''.join(self.extract_input_slices(ranges))
1718 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
1693 1719 f = file(fname,'w')
1694 1720 f.write(cmds)
1695 1721 f.close()
@@ -1742,6 +1768,13 b' Currently the magic system has the following functions:\\n"""'
1742 1768 it was used, regardless of how long ago (in your current session) it
1743 1769 was.
1744 1770
1771 -r: use 'raw' input. This option only applies to input taken from the
1772 user's history. By default, the 'processed' history is used, so that
1773 magics are loaded in their transformed version to valid Python. If
1774 this option is given, the raw input as typed as the command line is
1775 used instead. When you exit the editor, it will be executed by
1776 IPython's own processor.
1777
1745 1778 -x: do not execute the edited code immediately upon exit. This is
1746 1779 mainly useful if you are editing programs which need to be called with
1747 1780 command line arguments, which you can then do using %run.
@@ -1860,11 +1893,14 b' Currently the magic system has the following functions:\\n"""'
1860 1893 # custom exceptions
1861 1894 class DataIsObject(Exception): pass
1862 1895
1863 opts,args = self.parse_options(parameter_s,'px')
1896 opts,args = self.parse_options(parameter_s,'prx')
1897 # Set a few locals from the options for convenience:
1898 opts_p = opts.has_key('p')
1899 opts_r = opts.has_key('r')
1864 1900
1865 1901 # Default line number value
1866 1902 lineno = None
1867 if opts.has_key('p'):
1903 if opts_p:
1868 1904 args = '_%s' % last_call[0]
1869 1905 if not self.shell.user_ns.has_key(args):
1870 1906 args = last_call[1]
@@ -1873,7 +1909,7 b' Currently the magic system has the following functions:\\n"""'
1873 1909 # let it be clobbered by successive '-p' calls.
1874 1910 try:
1875 1911 last_call[0] = self.shell.outputcache.prompt_count
1876 if not opts.has_key('p'):
1912 if not opts_p:
1877 1913 last_call[1] = parameter_s
1878 1914 except:
1879 1915 pass
@@ -1887,7 +1923,7 b' Currently the magic system has the following functions:\\n"""'
1887 1923 # This means that you can't edit files whose names begin with
1888 1924 # numbers this way. Tough.
1889 1925 ranges = args.split()
1890 data = ''.join(self.extract_input_slices(ranges))
1926 data = ''.join(self.extract_input_slices(ranges,opts_r))
1891 1927 elif args.endswith('.py'):
1892 1928 filename = make_filename(args)
1893 1929 data = ''
@@ -1955,7 +1991,10 b' Currently the magic system has the following functions:\\n"""'
1955 1991 print
1956 1992 else:
1957 1993 print 'done. Executing edited code...'
1958 self.shell.safe_execfile(filename,self.shell.user_ns)
1994 if opts_r:
1995 self.shell.runlines(file_read(filename))
1996 else:
1997 self.shell.safe_execfile(filename,self.shell.user_ns)
1959 1998 if use_temp:
1960 1999 try:
1961 2000 return open(filename).read()
@@ -1,9 +1,24 b''
1 1 """Module for interactive demos using IPython.
2 2
3 This module implements a single class, Demo, for running Python scripts
4 interactively in IPython for demonstrations. With very simple markup (a few
5 tags in comments), you can control points where the script stops executing and
6 returns control to IPython.
3 This module implements a few classes for running Python scripts interactively
4 in IPython for demonstrations. With very simple markup (a few tags in
5 comments), you can control points where the script stops executing and returns
6 control to IPython.
7
8 The classes are (see their docstrings for further details):
9
10 - Demo: pure python demos
11
12 - IPythonDemo: demos with input to be processed by IPython as if it had been
13 typed interactively (so magics work, as well as any other special syntax you
14 may have added via input prefilters).
15
16 - LineDemo: single-line version of the Demo class. These demos are executed
17 one line at a time, and require no markup.
18
19 - IPythonLineDemo: IPython version of the LineDemo class (the demo is
20 executed a line at a time, but processed via IPython).
21
7 22
8 23 The file is run in its own empty namespace (though you can pass it a string of
9 24 arguments as if in a command line environment, and it will see those as
@@ -54,12 +69,12 b' copy this into a file named ex_demo.py, and try running it via:'
54 69
55 70 from IPython.demo import Demo
56 71 d = Demo('ex_demo.py')
57 d() <--- Call the d object (omit the parens if you have autocall on).
72 d() <--- Call the d object (omit the parens if you have autocall set to 2).
58 73
59 74 Each time you call the demo object, it runs the next block. The demo object
60 has a few useful methods for navigation, like again(), jump(), seek() and
61 back(). It can be reset for a new run via reset() or reloaded from disk (in
62 case you've edited the source) via reload(). See their docstrings below.
75 has a few useful methods for navigation, like again(), edit(), jump(), seek()
76 and back(). It can be reset for a new run via reset() or reloaded from disk
77 (in case you've edited the source) via reload(). See their docstrings below.
63 78
64 79 #################### EXAMPLE DEMO <ex_demo.py> ###############################
65 80 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
@@ -95,9 +110,6 b" print 'z is now:', z"
95 110
96 111 print 'bye!'
97 112 ################### END EXAMPLE DEMO <ex_demo.py> ############################
98
99 WARNING: this module uses Python 2.3 features, so it won't work in 2.2
100 environments.
101 113 """
102 114 #*****************************************************************************
103 115 # Copyright (C) 2005-2006 Fernando Perez. <Fernando.Perez@colorado.edu>
@@ -108,13 +120,14 b' environments.'
108 120 #*****************************************************************************
109 121
110 122 import exceptions
123 import os
111 124 import re
112 125 import sys
113 126
114 127 from IPython.PyColorize import Parser
115 from IPython.genutils import marquee, shlex_split, file_read
128 from IPython.genutils import marquee, shlex_split, file_read, file_readlines
116 129
117 __all__ = ['Demo','DemoError']
130 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
118 131
119 132 class DemoError(exceptions.Exception): pass
120 133
@@ -150,7 +163,7 b' class Demo:'
150 163 can be changed at runtime simply by reassigning it to a boolean
151 164 value.
152 165 """
153
166
154 167 self.fname = fname
155 168 self.sys_argv = [fname] + shlex_split(arg_str)
156 169 self.auto_all = auto_all
@@ -159,9 +172,11 b' class Demo:'
159 172 # it ensures that things like color scheme and the like are always in
160 173 # sync with the ipython mode being used. This class is only meant to
161 174 # be used inside ipython anyways, so it's OK.
162 self.ip_showtb = __IPYTHON__.showtraceback
163 175 self.ip_ns = __IPYTHON__.user_ns
164 176 self.ip_colorize = __IPYTHON__.pycolorize
177 self.ip_showtb = __IPYTHON__.showtraceback
178 self.ip_runlines = __IPYTHON__.runlines
179 self.shell = __IPYTHON__
165 180
166 181 # load user data and initialize data structures
167 182 self.reload()
@@ -211,6 +226,20 b' class Demo:'
211 226 if index<0 or index>=self.nblocks:
212 227 raise ValueError('invalid block index %s' % index)
213 228
229 def _get_index(self,index):
230 """Get the current block index, validating and checking status.
231
232 Returns None if the demo is finished"""
233
234 if index is None:
235 if self.finished:
236 print 'Demo finished. Use reset() if you want to rerun it.'
237 return None
238 index = self.block_index
239 else:
240 self._validate_index(index)
241 return index
242
214 243 def seek(self,index):
215 244 """Move the current seek pointer to the given block"""
216 245 self._validate_index(index)
@@ -230,15 +259,42 b' class Demo:'
230 259 self.back(1)
231 260 self()
232 261
262 def edit(self,index=None):
263 """Edit a block.
264
265 If no number is given, use the last block executed.
266
267 This edits the in-memory copy of the demo, it does NOT modify the
268 original source file. If you want to do that, simply open the file in
269 an editor and use reload() when you make changes to the file. This
270 method is meant to let you change a block during a demonstration for
271 explanatory purposes, without damaging your original script."""
272
273 index = self._get_index(index)
274 if index is None:
275 return
276 # decrease the index by one (unless we're at the very beginning), so
277 # that the default demo.edit() call opens up the sblock we've last run
278 if index>0:
279 index -= 1
280
281 filename = self.shell.mktempfile(self.src_blocks[index])
282 self.shell.hooks.editor(filename,1)
283 new_block = file_read(filename)
284 # update the source and colored block
285 self.src_blocks[index] = new_block
286 self.src_blocks_colored[index] = self.ip_colorize(new_block)
287 self.block_index = index
288 # call to run with the newly edited index
289 self()
290
233 291 def show(self,index=None):
234 292 """Show a single block on screen"""
293
294 index = self._get_index(index)
235 295 if index is None:
236 if self.finished:
237 print 'Demo finished. Use reset() if you want to rerun it.'
238 return
239 index = self.block_index
240 else:
241 self._validate_index(index)
296 return
297
242 298 print marquee('<%s> block # %s (%s remaining)' %
243 299 (self.fname,index,self.nblocks-index-1))
244 300 print self.src_blocks_colored[index],
@@ -259,7 +315,12 b' class Demo:'
259 315 (fname,index,nblocks-index-1))
260 316 print block,
261 317 sys.stdout.flush()
262
318
319 def runlines(self,source):
320 """Execute a string with one or more lines of code"""
321
322 exec source in self.user_ns
323
263 324 def __call__(self,index=None):
264 325 """run a block of the demo.
265 326
@@ -269,12 +330,9 b' class Demo:'
269 330 prints 'Block n/N, and N is the total, so it would be very odd to use
270 331 zero-indexing here."""
271 332
272 if index is None and self.finished:
273 print 'Demo finished. Use reset() if you want to rerun it.'
274 return
333 index = self._get_index(index)
275 334 if index is None:
276 index = self.block_index
277 self._validate_index(index)
335 return
278 336 try:
279 337 next_block = self.src_blocks[index]
280 338 self.block_index += 1
@@ -294,7 +352,7 b' class Demo:'
294 352 try:
295 353 save_argv = sys.argv
296 354 sys.argv = self.sys_argv
297 exec next_block in self.user_ns
355 self.runlines(next_block)
298 356 finally:
299 357 sys.argv = save_argv
300 358
@@ -309,3 +367,52 b' class Demo:'
309 367 print marquee('Use reset() if you want to rerun it.')
310 368 self.finished = True
311 369
370 class IPythonDemo(Demo):
371 """Class for interactive demos with IPython's input processing applied.
372
373 This subclasses Demo, but instead of executing each block by the Python
374 interpreter (via exec), it actually calls IPython on it, so that any input
375 filters which may be in place are applied to the input block.
376
377 If you have an interactive environment which exposes special input
378 processing, you can use this class instead to write demo scripts which
379 operate exactly as if you had typed them interactively. The default Demo
380 class requires the input to be valid, pure Python code.
381 """
382
383 def runlines(self,source):
384 """Execute a string with one or more lines of code"""
385
386 self.runlines(source)
387
388 class LineDemo(Demo):
389 """Demo where each line is executed as a separate block.
390
391 The input script should be valid Python code.
392
393 This class doesn't require any markup at all, and it's meant for simple
394 scripts (with no nesting or any kind of indentation) which consist of
395 multiple lines of input to be executed, one at a time, as if they had been
396 typed in the interactive prompt."""
397
398 def reload(self):
399 """Reload source from disk and initialize state."""
400 # read data and parse into blocks
401 src_b = [l for l in file_readlines(self.fname) if l.strip()]
402 nblocks = len(src_b)
403 self.src = os.linesep.join(file_readlines(self.fname))
404 self._silent = [False]*nblocks
405 self._auto = [True]*nblocks
406 self.auto_all = True
407 self.nblocks = nblocks
408 self.src_blocks = src_b
409
410 # also build syntax-highlighted source
411 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
412
413 # ensure clean namespace and seek offset
414 self.reset()
415
416 class IPythonLineDemo(IPythonDemo,LineDemo):
417 """Variant of the LineDemo class whose input is processed by IPython."""
418 pass
@@ -5,7 +5,7 b' General purpose utilities.'
5 5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 6 these things are also convenient when working at the command line.
7 7
8 $Id: genutils.py 1110 2006-01-30 20:43:30Z vivainio $"""
8 $Id: genutils.py 1126 2006-02-06 02:31:40Z fperez $"""
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
@@ -529,11 +529,18 b' def filefind(fname,alt_dirs = None):'
529 529 #----------------------------------------------------------------------------
530 530 def file_read(filename):
531 531 """Read a file and close it. Returns the file source."""
532 fobj=open(filename,'r');
532 fobj = open(filename,'r');
533 533 source = fobj.read();
534 534 fobj.close()
535 535 return source
536 536
537 def file_readlines(filename):
538 """Read a file and close it. Returns the file source using readlines()."""
539 fobj = open(filename,'r');
540 lines = fobj.readlines();
541 fobj.close()
542 return lines
543
537 544 #----------------------------------------------------------------------------
538 545 def target_outdated(target,deps):
539 546 """Determine whether a target is out of date.
@@ -1,3 +1,20 b''
1 2006-02-05 Fernando Perez <Fernando.Perez@colorado.edu>
2
3 * IPython/demo.py (IPythonDemo): Add new classes to the demo
4 facilities, for demos processed by the IPython input filter
5 (IPythonDemo), and for running a script one-line-at-a-time as a
6 demo, both for pure Python (LineDemo) and for IPython-processed
7 input (IPythonLineDemo). After a request by Dave Kohel, from the
8 SAGE team.
9 (Demo.edit): added and edit() method to the demo objects, to edit
10 the in-memory copy of the last executed block.
11
12 * IPython/Magic.py (magic_edit): add '-r' option for 'raw'
13 processing to %edit, %macro and %save. These commands can now be
14 invoked on the unprocessed input as it was typed by the user
15 (without any prefilters applied). After requests by the SAGE team
16 at SAGE days 2006: http://modular.ucsd.edu/sage/days1/schedule.html.
17
1 18 2006-02-01 Ville Vainio <vivainio@gmail.com>
2 19
3 20 * setup.py, eggsetup.py: easy_install ipython==dev works
General Comments 0
You need to be logged in to leave comments. Login now