##// END OF EJS Templates
Merging a number of recent bug fixes in preparation for the 0.10 release....
Fernando Perez -
r2096:f9ec69ca merge
parent child Browse files
Show More
@@ -15,6 +15,7 b' __docformat__ = "restructuredtext en"'
15 from copy import copy, deepcopy
15 from copy import copy, deepcopy
16 from cStringIO import StringIO
16 from cStringIO import StringIO
17 import string
17 import string
18 import sys
18
19
19 from nose.tools import assert_equal
20 from nose.tools import assert_equal
20
21
@@ -23,22 +24,6 b' from IPython.ipapi import get as get_ipython0'
23 from IPython.testing.plugin.ipdoctest import default_argv
24 from IPython.testing.plugin.ipdoctest import default_argv
24
25
25
26
26 def safe_deepcopy(d):
27 """ Deep copy every key of the given dict, when possible. Elsewhere
28 do a copy.
29 """
30 copied_d = dict()
31 for key, value in d.iteritems():
32 try:
33 copied_d[key] = deepcopy(value)
34 except:
35 try:
36 copied_d[key] = copy(value)
37 except:
38 copied_d[key] = value
39 return copied_d
40
41
42 class TestPrefilterFrontEnd(PrefilterFrontEnd):
27 class TestPrefilterFrontEnd(PrefilterFrontEnd):
43
28
44 input_prompt_template = string.Template('')
29 input_prompt_template = string.Template('')
@@ -72,17 +57,34 b' def isolate_ipython0(func):'
72 with arguments.
57 with arguments.
73 """
58 """
74 def my_func():
59 def my_func():
75 iplib = get_ipython0()
60 ip0 = get_ipython0()
76 if iplib is None:
61 if ip0 is None:
77 return func()
62 return func()
78 ipython0 = iplib.IP
63 # We have a real ipython running...
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
64 user_ns = ip0.IP.user_ns
80 user_ns = safe_deepcopy(ipython0.user_ns)
65 user_global_ns = ip0.IP.user_global_ns
66
67 # Previously the isolation was attempted with a deep copy of the user
68 # dicts, but we found cases where this didn't work correctly. I'm not
69 # quite sure why, but basically it did damage the user namespace, such
70 # that later tests stopped working correctly. Instead we use a simpler
71 # approach, just computing the list of added keys to the namespace and
72 # eliminating those afterwards. Existing keys that may have been
73 # modified remain modified. So far this has proven to be robust.
74
75 # Compute set of old local/global keys
76 old_locals = set(user_ns.keys())
77 old_globals = set(user_global_ns.keys())
81 try:
78 try:
82 out = func()
79 out = func()
83 finally:
80 finally:
84 ipython0.user_ns = user_ns
81 # Find new keys, and if any, remove them
85 ipython0.user_global_ns = global_ns
82 new_locals = set(user_ns.keys()) - old_locals
83 new_globals = set(user_global_ns.keys()) - old_globals
84 for k in new_locals:
85 del user_ns[k]
86 for k in new_globals:
87 del user_global_ns[k]
86 # Undo the hack at creation of PrefilterFrontEnd
88 # Undo the hack at creation of PrefilterFrontEnd
87 from IPython import iplib
89 from IPython import iplib
88 iplib.InteractiveShell.isthreaded = False
90 iplib.InteractiveShell.isthreaded = False
@@ -97,7 +99,7 b' def test_execution():'
97 """ Test execution of a command.
99 """ Test execution of a command.
98 """
100 """
99 f = TestPrefilterFrontEnd()
101 f = TestPrefilterFrontEnd()
100 f.input_buffer = 'print 1'
102 f.input_buffer = 'print(1)'
101 f._on_enter()
103 f._on_enter()
102 out_value = f.out.getvalue()
104 out_value = f.out.getvalue()
103 assert_equal(out_value, '1\n')
105 assert_equal(out_value, '1\n')
@@ -228,7 +230,14 b' def test_completion_indexing():'
228 f._on_enter()
230 f._on_enter()
229 f.input_buffer = 'a[0].'
231 f.input_buffer = 'a[0].'
230 f.complete_current_input()
232 f.complete_current_input()
231 assert_equal(f.input_buffer, 'a[0].__')
233
234 if sys.version_info[:2] >= (2,6):
235 # In Python 2.6, ints picked up a few non __ methods, so now there are
236 # no completions.
237 assert_equal(f.input_buffer, 'a[0].')
238 else:
239 # Right answer for 2.4/2.5
240 assert_equal(f.input_buffer, 'a[0].__')
232
241
233
242
234 @isolate_ipython0
243 @isolate_ipython0
@@ -238,8 +247,13 b' def test_completion_equal():'
238 f = TestPrefilterFrontEnd()
247 f = TestPrefilterFrontEnd()
239 f.input_buffer = 'a=1.'
248 f.input_buffer = 'a=1.'
240 f.complete_current_input()
249 f.complete_current_input()
241 assert_equal(f.input_buffer, 'a=1.__')
250 if sys.version_info[:2] >= (2,6):
242
251 # In Python 2.6, ints picked up a few non __ methods, so now there are
252 # no completions.
253 assert_equal(f.input_buffer, 'a=1.')
254 else:
255 # Right answer for 2.4/2.5
256 assert_equal(f.input_buffer, 'a=1.__')
243
257
244
258
245 if __name__ == '__main__':
259 if __name__ == '__main__':
@@ -880,7 +880,7 b' def doctest_reload():'
880
880
881 This routine:
881 This routine:
882
882
883 - reloads doctest
883 - imports doctest but does NOT reload it (see below).
884
884
885 - resets its global 'master' attribute to None, so that multiple uses of
885 - resets its global 'master' attribute to None, so that multiple uses of
886 the module interactively don't produce cumulative reports.
886 the module interactively don't produce cumulative reports.
@@ -889,20 +889,20 b' def doctest_reload():'
889 modified displayhook. Doctest expects the default displayhook behavior
889 modified displayhook. Doctest expects the default displayhook behavior
890 deep down, so our modification breaks it completely. For this reason, a
890 deep down, so our modification breaks it completely. For this reason, a
891 hard monkeypatch seems like a reasonable solution rather than asking
891 hard monkeypatch seems like a reasonable solution rather than asking
892 users to manually use a different doctest runner when under IPython."""
892 users to manually use a different doctest runner when under IPython.
893
893
894 import doctest
894 Note
895 reload(doctest)
895 ----
896 doctest.master=None
897
896
898 try:
897 This function *used to* reload doctest, but this has been disabled because
899 doctest.DocTestRunner
898 reloading doctest unconditionally can cause massive breakage of other
900 except AttributeError:
899 doctest-dependent modules already in memory, such as those for IPython's
901 # This is only for python 2.3 compatibility, remove once we move to
900 own testing system. The name wasn't changed to avoid breaking people's
902 # 2.4 only.
901 code, but the reload call isn't actually made anymore."""
903 pass
902
904 else:
903 import doctest
905 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
904 doctest.master = None
905 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
906
906
907 #----------------------------------------------------------------------------
907 #----------------------------------------------------------------------------
908 class HomeDirError(Error):
908 class HomeDirError(Error):
@@ -90,7 +90,7 b' from inspect import getsourcefile, getfile, getmodule,\\'
90
90
91 # IPython's own modules
91 # IPython's own modules
92 # Modified pdb which doesn't damage IPython's readline handling
92 # Modified pdb which doesn't damage IPython's readline handling
93 from IPython import Debugger, PyColorize
93 from IPython import Debugger, PyColorize, ipapi
94 from IPython.ipstruct import Struct
94 from IPython.ipstruct import Struct
95 from IPython.excolors import exception_colors
95 from IPython.excolors import exception_colors
96 from IPython.genutils import Term,uniq_stable,error,info
96 from IPython.genutils import Term,uniq_stable,error,info
@@ -268,9 +268,7 b' def _formatTracebackLines(lnum, index, lines, Colors, lvals=None,scheme=None):'
268 # This lets us get fully syntax-highlighted tracebacks.
268 # This lets us get fully syntax-highlighted tracebacks.
269 if scheme is None:
269 if scheme is None:
270 try:
270 try:
271 # Again, reference to a global __IPYTHON__ that doesn't exist.
271 scheme = ipapi.get().IP.rc.colors
272 # XXX
273 scheme = __IPYTHON__.rc.colors
274 except:
272 except:
275 scheme = DEFAULT_SCHEME
273 scheme = DEFAULT_SCHEME
276 _line_format = _parser.format2
274 _line_format = _parser.format2
@@ -489,14 +487,10 b' class ListTB(TBTools):'
489 else:
487 else:
490 list.append('%s\n' % str(stype))
488 list.append('%s\n' % str(stype))
491
489
492 # This is being commented out for now as the __IPYTHON__ variable
490 # vds:>>
493 # referenced here is not resolved and causes massive test failures
491 if have_filedata:
494 # and errors. B. Granger, 04/2009. XXX
492 ipapi.get().IP.hooks.synchronize_with_editor(filename, lineno, 0)
495 # See https://bugs.launchpad.net/bugs/362137
493 # vds:<<
496 # # vds:>>
497 # if have_filedata:
498 # __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
499 # # vds:<<
500
494
501 return list
495 return list
502
496
@@ -810,17 +804,13 b' class VerboseTB(TBTools):'
810 value = text_repr(getattr(evalue, name))
804 value = text_repr(getattr(evalue, name))
811 exception.append('\n%s%s = %s' % (indent, name, value))
805 exception.append('\n%s%s = %s' % (indent, name, value))
812
806
813 # This is being commented out for now as the __IPYTHON__ variable
807 # vds: >>
814 # referenced here is not resolved and causes massive test failures
808 if records:
815 # and errors. B. Granger, 04/2009. XXX
809 filepath, lnum = records[-1][1:3]
816 # See https://bugs.launchpad.net/bugs/362137
810 #print "file:", str(file), "linenb", str(lnum) # dbg
817 # # vds: >>
811 filepath = os.path.abspath(filepath)
818 # if records:
812 ipapi.get().IP.hooks.synchronize_with_editor(filepath, lnum, 0)
819 # filepath, lnum = records[-1][1:3]
813 # vds: <<
820 # #print "file:", str(file), "linenb", str(lnum) # dbg
821 # filepath = os.path.abspath(filepath)
822 # __IPYTHON__.hooks.synchronize_with_editor(filepath, lnum, 0)
823 # # vds: <<
824
814
825 # return all our info assembled as a single string
815 # return all our info assembled as a single string
826 return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
816 return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
@@ -50,6 +50,7 b' def test_for(mod):'
50
50
51 have_curses = test_for('_curses')
51 have_curses = test_for('_curses')
52 have_wx = test_for('wx')
52 have_wx = test_for('wx')
53 have_wx_aui = test_for('wx.aui')
53 have_zi = test_for('zope.interface')
54 have_zi = test_for('zope.interface')
54 have_twisted = test_for('twisted')
55 have_twisted = test_for('twisted')
55 have_foolscap = test_for('foolscap')
56 have_foolscap = test_for('foolscap')
@@ -65,14 +66,15 b" EXCLUDE = [pjoin('IPython', 'external'),"
65 pjoin('IPython_doctest_plugin'),
66 pjoin('IPython_doctest_plugin'),
66 pjoin('IPython', 'Gnuplot'),
67 pjoin('IPython', 'Gnuplot'),
67 pjoin('IPython', 'Extensions', 'ipy_'),
68 pjoin('IPython', 'Extensions', 'ipy_'),
68 pjoin('IPython', 'Extensions', 'clearcmd'),
69 pjoin('IPython', 'Extensions', 'PhysicalQInput'),
69 pjoin('IPython', 'Extensions', 'PhysicalQInteractive'),
70 pjoin('IPython', 'Extensions', 'PhysicalQInteractive'),
71 pjoin('IPython', 'Extensions', 'InterpreterPasteInput'),
70 pjoin('IPython', 'Extensions', 'scitedirector'),
72 pjoin('IPython', 'Extensions', 'scitedirector'),
71 pjoin('IPython', 'Extensions', 'numeric_formats'),
73 pjoin('IPython', 'Extensions', 'numeric_formats'),
72 pjoin('IPython', 'testing', 'attic'),
74 pjoin('IPython', 'testing', 'attic'),
73 pjoin('IPython', 'testing', 'tutils'),
75 pjoin('IPython', 'testing', 'tutils'),
74 pjoin('IPython', 'testing', 'tools'),
76 pjoin('IPython', 'testing', 'tools'),
75 pjoin('IPython', 'testing', 'mkdoctests')
77 pjoin('IPython', 'testing', 'mkdoctests'),
76 ]
78 ]
77
79
78 if not have_wx:
80 if not have_wx:
@@ -80,6 +82,9 b' if not have_wx:'
80 EXCLUDE.append(pjoin('IPython', 'gui'))
82 EXCLUDE.append(pjoin('IPython', 'gui'))
81 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
83 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
82
84
85 if not have_wx_aui:
86 EXCLUDE.append(pjoin('IPython', 'gui', 'wx', 'wxIPython'))
87
83 if not have_objc:
88 if not have_objc:
84 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
89 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
85
90
@@ -258,7 +263,7 b' def run_iptestall():'
258 t_start = time.time()
263 t_start = time.time()
259 for name,runner in runners.iteritems():
264 for name,runner in runners.iteritems():
260 print '*'*77
265 print '*'*77
261 print 'IPython test set:',name
266 print 'IPython test group:',name
262 res = runner.run()
267 res = runner.run()
263 if res:
268 if res:
264 failed[name] = res
269 failed[name] = res
@@ -269,14 +274,14 b' def run_iptestall():'
269 # summarize results
274 # summarize results
270 print
275 print
271 print '*'*77
276 print '*'*77
272 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
277 print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
273 print
278 print
274 if not failed:
279 if not failed:
275 print 'OK'
280 print 'OK'
276 else:
281 else:
277 # If anything went wrong, point out what command to rerun manually to
282 # If anything went wrong, point out what command to rerun manually to
278 # see the actual errors and individual summary
283 # see the actual errors and individual summary
279 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
284 print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners)
280 for name in failed:
285 for name in failed:
281 failed_runner = runners[name]
286 failed_runner = runners[name]
282 print '-'*40
287 print '-'*40
@@ -297,4 +302,4 b' def main():'
297
302
298
303
299 if __name__ == '__main__':
304 if __name__ == '__main__':
300 main() No newline at end of file
305 main()
@@ -207,6 +207,15 b' def start_ipython():'
207 _ip.IP.magic_run_ori = _ip.IP.magic_run
207 _ip.IP.magic_run_ori = _ip.IP.magic_run
208 _ip.IP.magic_run = im
208 _ip.IP.magic_run = im
209
209
210 # XXX - For some very bizarre reason, the loading of %history by default is
211 # failing. This needs to be fixed later, but for now at least this ensures
212 # that tests that use %hist run to completion.
213 from IPython import history
214 history.init_ipython(_ip)
215 if not hasattr(_ip.IP,'magic_history'):
216 raise RuntimeError("Can't load magics, aborting")
217
218
210 # The start call MUST be made here. I'm not sure yet why it doesn't work if
219 # The start call MUST be made here. I'm not sure yet why it doesn't work if
211 # it is made later, at plugin initialization time, but in all my tests, that's
220 # it is made later, at plugin initialization time, but in all my tests, that's
212 # the case.
221 # the case.
@@ -25,14 +25,14 b' def test_rehashx():'
25 _ip.magic('rehashx')
25 _ip.magic('rehashx')
26 # Practically ALL ipython development systems will have more than 10 aliases
26 # Practically ALL ipython development systems will have more than 10 aliases
27
27
28 assert len(_ip.IP.alias_table) > 10
28 yield (nt.assert_true, len(_ip.IP.alias_table) > 10)
29 for key, val in _ip.IP.alias_table.items():
29 for key, val in _ip.IP.alias_table.items():
30 # we must strip dots from alias names
30 # we must strip dots from alias names
31 assert '.' not in key
31 nt.assert_true('.' not in key)
32
32
33 # rehashx must fill up syscmdlist
33 # rehashx must fill up syscmdlist
34 scoms = _ip.db['syscmdlist']
34 scoms = _ip.db['syscmdlist']
35 assert len(scoms) > 10
35 yield (nt.assert_true, len(scoms) > 10)
36
36
37
37
38 def doctest_hist_f():
38 def doctest_hist_f():
@@ -42,7 +42,8 b' def doctest_hist_f():'
42
42
43 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
43 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
44
44
45 In [11]: %history -n -f $tfile 3
45 In [11]: %hist -n -f $tfile 3
46
46 """
47 """
47
48
48
49
@@ -51,9 +52,12 b' def doctest_hist_r():'
51
52
52 XXX - This test is not recording the output correctly. Not sure why...
53 XXX - This test is not recording the output correctly. Not sure why...
53
54
55 In [20]: 'hist' in _ip.IP.lsmagic()
56 Out[20]: True
57
54 In [6]: x=1
58 In [6]: x=1
55
59
56 In [7]: hist -n -r 2
60 In [7]: %hist -n -r 2
57 x=1 # random
61 x=1 # random
58 hist -n -r 2 # random
62 hist -n -r 2 # random
59 """
63 """
@@ -94,12 +98,13 b' def test_shist():'
94
98
95 @dec.skipif_not_numpy
99 @dec.skipif_not_numpy
96 def test_numpy_clear_array_undec():
100 def test_numpy_clear_array_undec():
101 from IPython.Extensions import clearcmd
102
97 _ip.ex('import numpy as np')
103 _ip.ex('import numpy as np')
98 _ip.ex('a = np.empty(2)')
104 _ip.ex('a = np.empty(2)')
99
105 yield (nt.assert_true, 'a' in _ip.user_ns)
100 yield nt.assert_true,'a' in _ip.user_ns
101 _ip.magic('clear array')
106 _ip.magic('clear array')
102 yield nt.assert_false,'a' in _ip.user_ns
107 yield (nt.assert_false, 'a' in _ip.user_ns)
103
108
104
109
105 @dec.skip()
110 @dec.skip()
@@ -90,7 +90,7 b' from inspect import getsourcefile, getfile, getmodule,\\'
90
90
91 # IPython's own modules
91 # IPython's own modules
92 # Modified pdb which doesn't damage IPython's readline handling
92 # Modified pdb which doesn't damage IPython's readline handling
93 from IPython import Debugger, PyColorize
93 from IPython import Debugger, PyColorize, ipapi
94 from IPython.ipstruct import Struct
94 from IPython.ipstruct import Struct
95 from IPython.excolors import exception_colors
95 from IPython.excolors import exception_colors
96 from IPython.genutils import Term,uniq_stable,error,info
96 from IPython.genutils import Term,uniq_stable,error,info
@@ -268,7 +268,7 b' def _formatTracebackLines(lnum, index, lines, Colors, lvals=None,scheme=None):'
268 # This lets us get fully syntax-highlighted tracebacks.
268 # This lets us get fully syntax-highlighted tracebacks.
269 if scheme is None:
269 if scheme is None:
270 try:
270 try:
271 scheme = __IPYTHON__.rc.colors
271 scheme = ipapi.get().IP.rc.colors
272 except:
272 except:
273 scheme = DEFAULT_SCHEME
273 scheme = DEFAULT_SCHEME
274 _line_format = _parser.format2
274 _line_format = _parser.format2
@@ -489,7 +489,7 b' class ListTB(TBTools):'
489
489
490 # vds:>>
490 # vds:>>
491 if have_filedata:
491 if have_filedata:
492 __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0)
492 ipapi.get().IP.hooks.synchronize_with_editor(filename, lineno, 0)
493 # vds:<<
493 # vds:<<
494
494
495 return list
495 return list
@@ -809,7 +809,7 b' class VerboseTB(TBTools):'
809 filepath, lnum = records[-1][1:3]
809 filepath, lnum = records[-1][1:3]
810 #print "file:", str(file), "linenb", str(lnum) # dbg
810 #print "file:", str(file), "linenb", str(lnum) # dbg
811 filepath = os.path.abspath(filepath)
811 filepath = os.path.abspath(filepath)
812 __IPYTHON__.hooks.synchronize_with_editor(filepath, lnum, 0)
812 ipapi.get().IP.hooks.synchronize_with_editor(filepath, lnum, 0)
813 # vds: <<
813 # vds: <<
814
814
815 # return all our info assembled as a single string
815 # return all our info assembled as a single string
@@ -3,6 +3,8 b''
3
3
4 from IPython.kernel import client
4 from IPython.kernel import client
5 import time
5 import time
6 import sys
7 flush = sys.stdout.flush
6
8
7 tc = client.TaskClient()
9 tc = client.TaskClient()
8 mec = client.MultiEngineClient()
10 mec = client.MultiEngineClient()
@@ -16,6 +18,7 b' for i in range(6):'
16 time.sleep(1.0)
18 time.sleep(1.0)
17 print "Queue status (vebose=False)"
19 print "Queue status (vebose=False)"
18 print tc.queue_status()
20 print tc.queue_status()
21 flush()
19
22
20 for i in range(24):
23 for i in range(24):
21 tc.run(client.StringTask('time.sleep(1)'))
24 tc.run(client.StringTask('time.sleep(1)'))
@@ -24,12 +27,14 b' for i in range(6):'
24 time.sleep(1.0)
27 time.sleep(1.0)
25 print "Queue status (vebose=True)"
28 print "Queue status (vebose=True)"
26 print tc.queue_status(True)
29 print tc.queue_status(True)
30 flush()
27
31
28 for i in range(12):
32 for i in range(12):
29 tc.run(client.StringTask('time.sleep(2)'))
33 tc.run(client.StringTask('time.sleep(2)'))
30
34
31 print "Queue status (vebose=True)"
35 print "Queue status (vebose=True)"
32 print tc.queue_status(True)
36 print tc.queue_status(True)
37 flush()
33
38
34 qs = tc.queue_status(True)
39 qs = tc.queue_status(True)
35 sched = qs['scheduled']
40 sched = qs['scheduled']
@@ -41,4 +46,5 b' for i in range(6):'
41 time.sleep(1.0)
46 time.sleep(1.0)
42 print "Queue status (vebose=True)"
47 print "Queue status (vebose=True)"
43 print tc.queue_status(True)
48 print tc.queue_status(True)
49 flush()
44
50
General Comments 0
You need to be logged in to leave comments. Login now