Show More
@@ -1,5 +1,4 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
||||
3 | """ History related magics and functionality """ |
|
2 | """ History related magics and functionality """ | |
4 |
|
3 | |||
5 | # Stdlib imports |
|
4 | # Stdlib imports | |
@@ -7,7 +6,7 b' import fnmatch' | |||||
7 | import os |
|
6 | import os | |
8 |
|
7 | |||
9 | # IPython imports |
|
8 | # IPython imports | |
10 | from IPython.genutils import Term, ask_yes_no |
|
9 | from IPython.genutils import Term, ask_yes_no, warn | |
11 | import IPython.ipapi |
|
10 | import IPython.ipapi | |
12 |
|
11 | |||
13 | def magic_history(self, parameter_s = ''): |
|
12 | def magic_history(self, parameter_s = ''): | |
@@ -47,8 +46,6 b" def magic_history(self, parameter_s = ''):" | |||||
47 | -f FILENAME: instead of printing the output to the screen, redirect it to |
|
46 | -f FILENAME: instead of printing the output to the screen, redirect it to | |
48 | the given file. The file is always overwritten, though IPython asks for |
|
47 | the given file. The file is always overwritten, though IPython asks for | |
49 | confirmation first if it already exists. |
|
48 | confirmation first if it already exists. | |
50 |
|
||||
51 |
|
||||
52 | """ |
|
49 | """ | |
53 |
|
50 | |||
54 | ip = self.api |
|
51 | ip = self.api | |
@@ -62,31 +59,28 b" def magic_history(self, parameter_s = ''):" | |||||
62 | try: |
|
59 | try: | |
63 | outfname = opts['f'] |
|
60 | outfname = opts['f'] | |
64 | except KeyError: |
|
61 | except KeyError: | |
65 | outfile = Term.cout |
|
62 | outfile = Term.cout # default | |
66 | # We don't want to close stdout at the end! |
|
63 | # We don't want to close stdout at the end! | |
67 | close_at_end = False |
|
64 | close_at_end = False | |
68 | else: |
|
65 | else: | |
69 | if os.path.exists(outfname): |
|
66 | if os.path.exists(outfname): | |
70 |
|
|
67 | if not ask_yes_no("File %r exists. Overwrite?" % outfname): | |
71 | if not ans: |
|
|||
72 | print 'Aborting.' |
|
68 | print 'Aborting.' | |
73 | return |
|
69 | return | |
74 | else: |
|
|||
75 | outfile = open(outfname,'w') |
|
|||
76 | close_at_end = True |
|
|||
77 |
|
||||
78 |
|
70 | |||
79 | if opts.has_key('t'): |
|
71 | outfile = open(outfname,'w') | |
|
72 | close_at_end = True | |||
|
73 | ||||
|
74 | if 't' in opts: | |||
80 | input_hist = shell.input_hist |
|
75 | input_hist = shell.input_hist | |
81 | elif opts.has_key('r'): |
|
76 | elif 'r' in opts: | |
82 | input_hist = shell.input_hist_raw |
|
77 | input_hist = shell.input_hist_raw | |
83 | else: |
|
78 | else: | |
84 | input_hist = shell.input_hist |
|
79 | input_hist = shell.input_hist | |
85 |
|
80 | |||
86 |
|
||||
87 | default_length = 40 |
|
81 | default_length = 40 | |
88 | pattern = None |
|
82 | pattern = None | |
89 | if opts.has_key('g'): |
|
83 | if 'g' in opts: | |
90 | init = 1 |
|
84 | init = 1 | |
91 | final = len(input_hist) |
|
85 | final = len(input_hist) | |
92 | parts = parameter_s.split(None,1) |
|
86 | parts = parameter_s.split(None,1) | |
@@ -138,13 +132,11 b" def magic_history(self, parameter_s = ''):" | |||||
138 | outfile.close() |
|
132 | outfile.close() | |
139 |
|
133 | |||
140 |
|
134 | |||
141 |
|
||||
142 | def magic_hist(self, parameter_s=''): |
|
135 | def magic_hist(self, parameter_s=''): | |
143 | """Alternate name for %history.""" |
|
136 | """Alternate name for %history.""" | |
144 | return self.magic_history(parameter_s) |
|
137 | return self.magic_history(parameter_s) | |
145 |
|
138 | |||
146 |
|
139 | |||
147 |
|
||||
148 | def rep_f(self, arg): |
|
140 | def rep_f(self, arg): | |
149 | r""" Repeat a command, or get command to input line for editing |
|
141 | r""" Repeat a command, or get command to input line for editing | |
150 |
|
142 | |||
@@ -173,11 +165,9 b' def rep_f(self, arg):' | |||||
173 | %rep foo |
|
165 | %rep foo | |
174 |
|
166 | |||
175 | Place the most recent line that has the substring "foo" to next input. |
|
167 | Place the most recent line that has the substring "foo" to next input. | |
176 | (e.g. 'svn ci -m foobar'). |
|
168 | (e.g. 'svn ci -m foobar'). | |
177 |
|
||||
178 | """ |
|
169 | """ | |
179 |
|
170 | |||
180 |
|
||||
181 | opts,args = self.parse_options(arg,'',mode='list') |
|
171 | opts,args = self.parse_options(arg,'',mode='list') | |
182 | ip = self.api |
|
172 | ip = self.api | |
183 | if not args: |
|
173 | if not args: | |
@@ -206,7 +196,6 b' def rep_f(self, arg):' | |||||
206 | ip.set_next_input(str(h).rstrip()) |
|
196 | ip.set_next_input(str(h).rstrip()) | |
207 | return |
|
197 | return | |
208 |
|
198 | |||
209 |
|
||||
210 | try: |
|
199 | try: | |
211 | lines = self.extract_input_slices(args, True) |
|
200 | lines = self.extract_input_slices(args, True) | |
212 | print "lines",lines |
|
201 | print "lines",lines | |
@@ -215,7 +204,6 b' def rep_f(self, arg):' | |||||
215 | print "Not found in recent history:", args |
|
204 | print "Not found in recent history:", args | |
216 |
|
205 | |||
217 |
|
206 | |||
218 |
|
||||
219 | _sentinel = object() |
|
207 | _sentinel = object() | |
220 |
|
208 | |||
221 | class ShadowHist: |
|
209 | class ShadowHist: | |
@@ -259,23 +247,12 b' class ShadowHist:' | |||||
259 | if k == idx: |
|
247 | if k == idx: | |
260 | return v |
|
248 | return v | |
261 |
|
249 | |||
262 | def test_shist(): |
|
|||
263 | from IPython.Extensions import pickleshare |
|
|||
264 | db = pickleshare.PickleShareDB('~/shist') |
|
|||
265 | s = ShadowHist(db) |
|
|||
266 | s.add('hello') |
|
|||
267 | s.add('world') |
|
|||
268 | s.add('hello') |
|
|||
269 | s.add('hello') |
|
|||
270 | s.add('karhu') |
|
|||
271 | print "all",s.all() |
|
|||
272 | print s.get(2) |
|
|||
273 |
|
250 | |||
274 | def init_ipython(ip): |
|
251 | def init_ipython(ip): | |
|
252 | import ipy_completers | |||
|
253 | ||||
275 | ip.expose_magic("rep",rep_f) |
|
254 | ip.expose_magic("rep",rep_f) | |
276 | ip.expose_magic("hist",magic_hist) |
|
255 | ip.expose_magic("hist",magic_hist) | |
277 | ip.expose_magic("history",magic_history) |
|
256 | ip.expose_magic("history",magic_history) | |
278 |
|
257 | |||
279 | import ipy_completers |
|
|||
280 | ipy_completers.quick_completer('%hist' ,'-g -t -r -n') |
|
258 | ipy_completers.quick_completer('%hist' ,'-g -t -r -n') | |
281 | #test_shist() |
|
@@ -65,13 +65,28 b' log = logging.getLogger(__name__)' | |||||
65 | # test globals. Once we move over to a clean magic system, this will be done |
|
65 | # test globals. Once we move over to a clean magic system, this will be done | |
66 | # with much less ugliness. |
|
66 | # with much less ugliness. | |
67 |
|
67 | |||
|
68 | class py_file_finder(object): | |||
|
69 | def __init__(self,test_filename): | |||
|
70 | self.test_filename = test_filename | |||
|
71 | ||||
|
72 | def __call__(self,name): | |||
|
73 | from IPython.genutils import get_py_filename | |||
|
74 | try: | |||
|
75 | get_py_filename(name) | |||
|
76 | except IOError: | |||
|
77 | test_dir = os.path.dirname(self.test_filename) | |||
|
78 | new_path = os.path.join(test_dir,name) | |||
|
79 | return get_py_filename(new_path) | |||
|
80 | ||||
|
81 | ||||
68 | def _run_ns_sync(self,arg_s,runner=None): |
|
82 | def _run_ns_sync(self,arg_s,runner=None): | |
69 | """Modified version of %run that syncs testing namespaces. |
|
83 | """Modified version of %run that syncs testing namespaces. | |
70 |
|
84 | |||
71 | This is strictly needed for running doctests that call %run. |
|
85 | This is strictly needed for running doctests that call %run. | |
72 | """ |
|
86 | """ | |
73 |
|
87 | |||
74 | out = _ip.IP.magic_run_ori(arg_s,runner) |
|
88 | finder = py_file_finder(_run_ns_sync.test_filename) | |
|
89 | out = _ip.IP.magic_run_ori(arg_s,runner,finder) | |||
75 | _run_ns_sync.test_globs.update(_ip.user_ns) |
|
90 | _run_ns_sync.test_globs.update(_ip.user_ns) | |
76 | return out |
|
91 | return out | |
77 |
|
92 | |||
@@ -129,8 +144,7 b' def start_ipython():' | |||||
129 |
|
144 | |||
130 | # Start IPython instance. We customize it to start with minimal frills. |
|
145 | # Start IPython instance. We customize it to start with minimal frills. | |
131 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) |
|
146 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) | |
132 |
|
147 | IPython.Shell.IPShell(['--colors=NoColor','--noterm_title'], | ||
133 | IPython.Shell.IPShell(['--classic','--noterm_title'], |
|
|||
134 | user_ns,global_ns) |
|
148 | user_ns,global_ns) | |
135 |
|
149 | |||
136 | # Deactivate the various python system hooks added by ipython for |
|
150 | # Deactivate the various python system hooks added by ipython for | |
@@ -638,7 +652,8 b' class IPDocTestRunner(doctest.DocTestRunner,object):' | |||||
638 | # when called (rather than unconconditionally updating test.globs here |
|
652 | # when called (rather than unconconditionally updating test.globs here | |
639 | # for all examples, most of which won't be calling %run anyway). |
|
653 | # for all examples, most of which won't be calling %run anyway). | |
640 | _run_ns_sync.test_globs = test.globs |
|
654 | _run_ns_sync.test_globs = test.globs | |
641 |
|
655 | _run_ns_sync.test_filename = test.filename | ||
|
656 | ||||
642 | return super(IPDocTestRunner,self).run(test, |
|
657 | return super(IPDocTestRunner,self).run(test, | |
643 | compileflags,out,clear_globs) |
|
658 | compileflags,out,clear_globs) | |
644 |
|
659 |
@@ -1,8 +1,10 b'' | |||||
1 | """ Tests for various magic functions |
|
1 | """ Tests for various magic functions | |
2 |
|
2 | |||
3 | Needs to be run by nose (to make ipython session available) |
|
3 | Needs to be run by nose (to make ipython session available) | |
4 |
|
||||
5 | """ |
|
4 | """ | |
|
5 | ||||
|
6 | from IPython.testing import decorators as dec | |||
|
7 | ||||
6 | def test_rehashx(): |
|
8 | def test_rehashx(): | |
7 | # clear up everything |
|
9 | # clear up everything | |
8 | _ip.IP.alias_table.clear() |
|
10 | _ip.IP.alias_table.clear() | |
@@ -19,3 +21,72 b' def test_rehashx():' | |||||
19 | # rehashx must fill up syscmdlist |
|
21 | # rehashx must fill up syscmdlist | |
20 | scoms = _ip.db['syscmdlist'] |
|
22 | scoms = _ip.db['syscmdlist'] | |
21 | assert len(scoms) > 10 |
|
23 | assert len(scoms) > 10 | |
|
24 | ||||
|
25 | ||||
|
26 | def doctest_run_ns(): | |||
|
27 | """Classes declared %run scripts must be instantiable afterwards. | |||
|
28 | ||||
|
29 | In [3]: run tclass.py | |||
|
30 | ||||
|
31 | In [4]: f() | |||
|
32 | """ | |||
|
33 | pass # doctest only | |||
|
34 | ||||
|
35 | ||||
|
36 | def doctest_hist_f(): | |||
|
37 | """Test %hist -f with temporary filename. | |||
|
38 | ||||
|
39 | In [9]: import tempfile | |||
|
40 | ||||
|
41 | In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-') | |||
|
42 | ||||
|
43 | In [11]: %history -n -f $tfile 3 | |||
|
44 | """ | |||
|
45 | ||||
|
46 | ||||
|
47 | def doctest_hist_r(): | |||
|
48 | """Test %hist -r | |||
|
49 | ||||
|
50 | XXX - This test is not recording the output correctly. Not sure why... | |||
|
51 | ||||
|
52 | In [6]: x=1 | |||
|
53 | ||||
|
54 | In [7]: hist -n -r 2 | |||
|
55 | x=1 # random | |||
|
56 | hist -n -r 2 # random | |||
|
57 | """ | |||
|
58 | ||||
|
59 | ||||
|
60 | def test_shist(): | |||
|
61 | # Simple tests of ShadowHist class | |||
|
62 | import os, shutil, tempfile | |||
|
63 | import nose.tools as nt | |||
|
64 | ||||
|
65 | from IPython.Extensions import pickleshare | |||
|
66 | from IPython.history import ShadowHist | |||
|
67 | ||||
|
68 | ||||
|
69 | tfile = tempfile.mktemp('','tmp-ipython-') | |||
|
70 | ||||
|
71 | db = pickleshare.PickleShareDB(tfile) | |||
|
72 | s = ShadowHist(db) | |||
|
73 | s.add('hello') | |||
|
74 | s.add('world') | |||
|
75 | s.add('hello') | |||
|
76 | s.add('hello') | |||
|
77 | s.add('karhu') | |||
|
78 | ||||
|
79 | yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')] | |||
|
80 | ||||
|
81 | yield nt.assert_equal,s.get(2),'world' | |||
|
82 | ||||
|
83 | shutil.rmtree(tfile) | |||
|
84 | ||||
|
85 | ||||
|
86 | @dec.skip_numpy_not_avail | |||
|
87 | def doctest_clear_array(): | |||
|
88 | """Check that array clearing works. | |||
|
89 | ||||
|
90 | >>> 1/0 | |||
|
91 | """ | |||
|
92 | pass # doctest only |
General Comments 0
You need to be logged in to leave comments.
Login now