##// END OF EJS Templates
Work in multiple places to improve state of the test suite....
Fernando Perez -
Show More
@@ -964,26 +964,43 b' class InteractiveShell(Component, Magic):'
964 964 method. If they were not empty before, data will simply be added to
965 965 therm.
966 966 """
967 # Store myself as the public api!!!
968 self.user_ns['get_ipython'] = self.get_ipython
967 # This function works in two parts: first we put a few things in
968 # user_ns, and we sync that contents into user_config_ns so that these
969 # initial variables aren't shown by %who. After the sync, we add the
970 # rest of what we *do* want the user to see with %who even on a new
971 # session.
972 ns = {}
973
974 # Put 'help' in the user namespace
975 try:
976 from site import _Helper
977 ns['help'] = _Helper()
978 except ImportError:
979 warn('help() not available - check site.py')
969 980
970 981 # make global variables for user access to the histories
971 self.user_ns['_ih'] = self.input_hist
972 self.user_ns['_oh'] = self.output_hist
973 self.user_ns['_dh'] = self.dir_hist
982 ns['_ih'] = self.input_hist
983 ns['_oh'] = self.output_hist
984 ns['_dh'] = self.dir_hist
985
986 ns['_sh'] = shadowns
987
988 # Sync what we've added so far to user_config_ns so these aren't seen
989 # by %who
990 self.user_config_ns.update(ns)
991
992 # Now, continue adding more contents
974 993
975 994 # user aliases to input and output histories
976 self.user_ns['In'] = self.input_hist
977 self.user_ns['Out'] = self.output_hist
995 ns['In'] = self.input_hist
996 ns['Out'] = self.output_hist
978 997
979 self.user_ns['_sh'] = shadowns
998 # Store myself as the public api!!!
999 ns['get_ipython'] = self.get_ipython
1000
1001 # And update the real user's namespace
1002 self.user_ns.update(ns)
980 1003
981 # Put 'help' in the user namespace
982 try:
983 from site import _Helper
984 self.user_ns['help'] = _Helper()
985 except ImportError:
986 warn('help() not available - check site.py')
987 1004
988 1005 def reset(self):
989 1006 """Clear all internal namespaces.
@@ -15,7 +15,7 b' import nose.tools as nt'
15 15 # our own packages
16 16 from IPython.core import iplib
17 17 from IPython.core import ipapi
18
18 from IPython.testing import decorators as dec
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Globals
@@ -43,15 +43,33 b' if ip is None:'
43 43 # Test functions
44 44 #-----------------------------------------------------------------------------
45 45
46 @dec.parametric
46 47 def test_reset():
47 48 """reset must clear most namespaces."""
48 ip.reset() # first, it should run without error
49 # Then, check that most namespaces end up empty
49 # The number of variables in the private user_config_ns is not zero, but it
50 # should be constant regardless of what we do
51 nvars_config_ns = len(ip.user_config_ns)
52
53 # Check that reset runs without error
54 ip.reset()
55
56 # Once we've reset it (to clear of any junk that might have been there from
57 # other tests, we can count how many variables are in the user's namespace
58 nvars_user_ns = len(ip.user_ns)
59
60 # Now add a few variables to user_ns, and check that reset clears them
61 ip.user_ns['x'] = 1
62 ip.user_ns['y'] = 1
63 ip.reset()
64
65 # Finally, check that all namespaces have only as many variables as we
66 # expect to find in them:
50 67 for ns in ip.ns_refs_table:
51 68 if ns is ip.user_ns:
52 # The user namespace is reset with some data, so we can't check for
53 # it being empty
54 continue
55 nt.assert_equals(len(ns),0)
56
57 No newline at end of file
69 nvars_expected = nvars_user_ns
70 elif ns is ip.user_config_ns:
71 nvars_expected = nvars_config_ns
72 else:
73 nvars_expected = 0
74
75 yield nt.assert_equals(len(ns), nvars_expected)
@@ -9,7 +9,6 b' functionnality is abstracted out of ipython0 in reusable functions and'
9 9 is added on the interpreter. This class can be a used to guide this
10 10 refactoring.
11 11 """
12 __docformat__ = "restructuredtext en"
13 12
14 13 #-------------------------------------------------------------------------------
15 14 # Copyright (C) 2008 The IPython Development Team
@@ -27,7 +26,7 b' import os'
27 26 import re
28 27 import __builtin__
29 28
30 from IPython.core.ipmaker import make_IPython
29 from IPython.core.ipapp import IPythonApp
31 30 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32 31
33 32 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
@@ -36,6 +35,9 b' from IPython.utils.genutils import Term'
36 35
37 36 from linefrontendbase import LineFrontEndBase, common_prefix
38 37
38 #-----------------------------------------------------------------------------
39 # Utility functions
40 #-----------------------------------------------------------------------------
39 41
40 42 def mk_system_call(system_call_function, command):
41 43 """ given a os.system replacement, and a leading string command,
@@ -74,7 +76,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
74 76 Used as the instance's argv value. If not given, [] is used.
75 77 """
76 78 if argv is None:
77 argv = []
79 argv = ['--no-banner']
78 80 # This is a hack to avoid the IPython exception hook to trigger
79 81 # on exceptions (https://bugs.launchpad.net/bugs/337105)
80 82 # XXX: This is horrible: module-leve monkey patching -> side
@@ -101,12 +103,15 b' class PrefilterFrontEnd(LineFrontEndBase):'
101 103 return '\n'
102 104 old_rawinput = __builtin__.raw_input
103 105 __builtin__.raw_input = my_rawinput
104 # XXX: argv=[] is a bit bold.
105 ipython0 = make_IPython(argv=argv,
106 user_ns=self.shell.user_ns,
107 user_global_ns=self.shell.user_global_ns)
106 ipython0 = IPythonApp(argv=argv,
107 user_ns=self.shell.user_ns,
108 user_global_ns=self.shell.user_global_ns)
109 ipython0.initialize()
108 110 __builtin__.raw_input = old_rawinput
109 self.ipython0 = ipython0
111 # XXX This will need to be updated as we refactor things, but for now,
112 # the .shell attribute of the ipythonapp instance conforms to the old
113 # api.
114 self.ipython0 = ipython0.shell
110 115 # Set the pager:
111 116 self.ipython0.set_hook('show_in_pager',
112 117 lambda s, string: self.write("\n" + string))
@@ -202,8 +207,7 b' class PrefilterFrontEnd(LineFrontEndBase):'
202 207 if completions:
203 208 prefix = common_prefix(completions)
204 209 line = line[:-len(word)] + prefix
205 return line, completions
206
210 return line, completions
207 211
208 212 #--------------------------------------------------------------------------
209 213 # LineFrontEndBase interface
@@ -220,23 +224,11 b' class PrefilterFrontEnd(LineFrontEndBase):'
220 224 self.capture_output()
221 225 self.last_result = dict(number=self.prompt_number)
222 226
223 ## try:
224 ## for line in input_string.split('\n'):
225 ## filtered_lines.append(
226 ## self.ipython0.prefilter(line, False).rstrip())
227 ## except:
228 ## # XXX: probably not the right thing to do.
229 ## self.ipython0.showsyntaxerror()
230 ## self.after_execute()
231 ## finally:
232 ## self.release_output()
233
234
235 227 try:
236 228 try:
237 229 for line in input_string.split('\n'):
238 filtered_lines.append(
239 self.ipython0.prefilter(line, False).rstrip())
230 pf = self.ipython0.prefilter_manager.prefilter_lines
231 filtered_lines.append(pf(line, False).rstrip())
240 232 except:
241 233 # XXX: probably not the right thing to do.
242 234 self.ipython0.showsyntaxerror()
@@ -244,13 +236,10 b' class PrefilterFrontEnd(LineFrontEndBase):'
244 236 finally:
245 237 self.release_output()
246 238
247
248
249 239 # Clean up the trailing whitespace, to avoid indentation errors
250 240 filtered_string = '\n'.join(filtered_lines)
251 241 return filtered_string
252 242
253
254 243 #--------------------------------------------------------------------------
255 244 # PrefilterFrontEnd interface
256 245 #--------------------------------------------------------------------------
@@ -261,13 +250,11 b' class PrefilterFrontEnd(LineFrontEndBase):'
261 250 """
262 251 return os.system(command_string)
263 252
264
265 253 def do_exit(self):
266 254 """ Exit the shell, cleanup and save the history.
267 255 """
268 256 self.ipython0.atexit_operations()
269 257
270
271 258 def _get_completion_text(self, line):
272 259 """ Returns the text to be completed by breaking the line at specified
273 260 delimiters.
@@ -281,4 +268,3 b' class PrefilterFrontEnd(LineFrontEndBase):'
281 268 complete_sep = re.compile(expression)
282 269 text = complete_sep.split(line)[-1]
283 270 return text
284
@@ -23,6 +23,9 b' from IPython.frontend.prefilterfrontend import PrefilterFrontEnd'
23 23 from IPython.core.ipapi import get as get_ipython0
24 24 from IPython.testing.plugin.ipdoctest import default_argv
25 25
26 #-----------------------------------------------------------------------------
27 # Support utilities
28 #-----------------------------------------------------------------------------
26 29
27 30 class TestPrefilterFrontEnd(PrefilterFrontEnd):
28 31
@@ -93,6 +96,9 b' def isolate_ipython0(func):'
93 96 my_func.__name__ = func.__name__
94 97 return my_func
95 98
99 #-----------------------------------------------------------------------------
100 # Tests
101 #-----------------------------------------------------------------------------
96 102
97 103 @isolate_ipython0
98 104 def test_execution():
@@ -166,7 +172,7 b' def test_magic():'
166 172 f.input_buffer += '%who'
167 173 f._on_enter()
168 174 out_value = f.out.getvalue()
169 assert_equal(out_value, 'Interactive namespace is empty.\n')
175 assert_equal(out_value, 'In\tOut\tget_ipython\t\n')
170 176
171 177
172 178 @isolate_ipython0
@@ -31,12 +31,20 b' import warnings'
31 31 import nose.plugins.builtin
32 32 from nose.core import TestProgram
33 33
34 from IPython.utils.platutils import find_cmd
35 # from IPython.testing.plugin.ipdoctest import IPythonDoctest
34 from IPython.utils import genutils
35 from IPython.utils.platutils import find_cmd, FindCmdError
36 36
37 37 pjoin = path.join
38 38
39 39 #-----------------------------------------------------------------------------
40 # Warnings control
41 #-----------------------------------------------------------------------------
42 # Twisted generates annoying warnings with Python 2.6, as will do other code
43 # that imports 'sets' as of today
44 warnings.filterwarnings('ignore', 'the sets module is deprecated',
45 DeprecationWarning )
46
47 #-----------------------------------------------------------------------------
40 48 # Logic for skipping doctests
41 49 #-----------------------------------------------------------------------------
42 50
@@ -63,10 +71,10 b" have_gobject = test_for('gobject')"
63 71
64 72 def make_exclude():
65 73
66 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
67 # testing problems. We should strive to minimize the number of skipped
68 # modules, since this means untested code. As the testing machinery
69 # solidifies, this list should eventually become empty.
74 # For the IPythonDoctest plugin, we need to exclude certain patterns that
75 # cause testing problems. We should strive to minimize the number of
76 # skipped modules, since this means untested code. As the testing
77 # machinery solidifies, this list should eventually become empty.
70 78 EXCLUDE = [pjoin('IPython', 'external'),
71 79 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
72 80 pjoin('IPython_doctest_plugin'),
@@ -137,6 +145,82 b' def make_exclude():'
137 145 # Functions and classes
138 146 #-----------------------------------------------------------------------------
139 147
148 class IPTester(object):
149 """Call that calls iptest or trial in a subprocess.
150 """
151 def __init__(self,runner='iptest',params=None):
152 """ """
153 if runner == 'iptest':
154 # Find our own 'iptest' script OS-level entry point
155 try:
156 iptest_path = find_cmd('iptest')
157 except FindCmdError:
158 # Script not installed (may be the case for testing situations
159 # that are running from a source tree only), pull from internal
160 # path:
161 iptest_path = pjoin(genutils.get_ipython_package_dir(),
162 'scripts','iptest')
163 self.runner = [iptest_path,'-v']
164 else:
165 self.runner = [find_cmd('trial')]
166 if params is None:
167 params = []
168 if isinstance(params,str):
169 params = [params]
170 self.params = params
171
172 # Assemble call
173 self.call_args = self.runner+self.params
174
175 if sys.platform == 'win32':
176 def _run_cmd(self):
177 # On Windows, use os.system instead of subprocess.call, because I
178 # was having problems with subprocess and I just don't know enough
179 # about win32 to debug this reliably. Os.system may be the 'old
180 # fashioned' way to do it, but it works just fine. If someone
181 # later can clean this up that's fine, as long as the tests run
182 # reliably in win32.
183 return os.system(' '.join(self.call_args))
184 else:
185 def _run_cmd(self):
186 return subprocess.call(self.call_args)
187
188 def run(self):
189 """Run the stored commands"""
190 try:
191 return self._run_cmd()
192 except:
193 import traceback
194 traceback.print_exc()
195 return 1 # signal failure
196
197
198 def make_runners():
199 """Define the top-level packages that need to be tested.
200 """
201
202 nose_packages = ['config', 'core', 'extensions', 'frontend', 'lib',
203 'scripts', 'testing', 'utils']
204 trial_packages = ['kernel']
205 #trial_packages = [] # dbg
206
207 if have_wx:
208 nose_packages.append('gui')
209
210 nose_packages = ['IPython.%s' % m for m in nose_packages ]
211 trial_packages = ['IPython.%s' % m for m in trial_packages ]
212
213 # Make runners, most with nose
214 nose_testers = [IPTester(params=v) for v in nose_packages]
215 runners = dict(zip(nose_packages, nose_testers))
216 # And add twisted ones if conditions are met
217 if have_zi and have_twisted and have_foolscap:
218 trial_testers = [IPTester('trial',params=v) for v in trial_packages]
219 runners.update(dict(zip(trial_packages,trial_testers)))
220
221 return runners
222
223
140 224 def run_iptest():
141 225 """Run the IPython test suite using nose.
142 226
@@ -194,81 +278,6 b' def run_iptest():'
194 278 TestProgram(argv=argv,plugins=plugins)
195 279
196 280
197 class IPTester(object):
198 """Call that calls iptest or trial in a subprocess.
199 """
200 def __init__(self,runner='iptest',params=None):
201 """ """
202 if runner == 'iptest':
203 self.runner = ['iptest','-v']
204 else:
205 self.runner = [find_cmd('trial')]
206 if params is None:
207 params = []
208 if isinstance(params,str):
209 params = [params]
210 self.params = params
211
212 # Assemble call
213 self.call_args = self.runner+self.params
214
215 if sys.platform == 'win32':
216 def run(self):
217 """Run the stored commands"""
218 # On Windows, cd to temporary directory to run tests. Otherwise,
219 # Twisted's trial may not be able to execute 'trial IPython', since
220 # it will confuse the IPython module name with the ipython
221 # execution scripts, because the windows file system isn't case
222 # sensitive.
223 # We also use os.system instead of subprocess.call, because I was
224 # having problems with subprocess and I just don't know enough
225 # about win32 to debug this reliably. Os.system may be the 'old
226 # fashioned' way to do it, but it works just fine. If someone
227 # later can clean this up that's fine, as long as the tests run
228 # reliably in win32.
229 curdir = os.getcwd()
230 os.chdir(tempfile.gettempdir())
231 stat = os.system(' '.join(self.call_args))
232 os.chdir(curdir)
233 return stat
234 else:
235 def run(self):
236 """Run the stored commands"""
237 try:
238 return subprocess.call(self.call_args)
239 except:
240 import traceback
241 traceback.print_exc()
242 return 1 # signal failure
243
244
245 def make_runners():
246 """Define the top-level packages that need to be tested.
247 """
248
249 nose_packages = ['config', 'core', 'extensions',
250 'frontend', 'lib',
251 'scripts', 'testing', 'utils']
252 trial_packages = ['kernel']
253
254 if have_wx:
255 nose_packages.append('gui')
256
257 nose_packages = ['IPython.%s' % m for m in nose_packages ]
258 trial_packages = ['IPython.%s' % m for m in trial_packages ]
259
260 # Make runners
261 runners = dict()
262
263 nose_runners = dict(zip(nose_packages, [IPTester(params=v) for v in nose_packages]))
264 if have_zi and have_twisted and have_foolscap:
265 trial_runners = dict(zip(trial_packages, [IPTester('trial',params=v) for v in trial_packages]))
266 runners.update(nose_runners)
267 runners.update(trial_runners)
268
269 return runners
270
271
272 281 def run_iptestall():
273 282 """Run the entire IPython test suite by calling nose and trial.
274 283
@@ -280,15 +289,26 b' def run_iptestall():'
280 289
281 290 runners = make_runners()
282 291
292 # Run the test runners in a temporary dir so we can nuke it when finished
293 # to clean up any junk files left over by accident. This also makes it
294 # robust against being run in non-writeable directories by mistake, as the
295 # temp dir will always be user-writeable.
296 curdir = os.getcwd()
297 testdir = tempfile.gettempdir()
298 os.chdir(testdir)
299
283 300 # Run all test runners, tracking execution time
284 301 failed = {}
285 302 t_start = time.time()
286 for name,runner in runners.iteritems():
287 print '*'*77
288 print 'IPython test group:',name
289 res = runner.run()
290 if res:
291 failed[name] = res
303 try:
304 for name,runner in runners.iteritems():
305 print '*'*77
306 print 'IPython test group:',name
307 res = runner.run()
308 if res:
309 failed[name] = res
310 finally:
311 os.chdir(curdir)
292 312 t_end = time.time()
293 313 t_tests = t_end - t_start
294 314 nrunners = len(runners)
@@ -68,7 +68,8 b' def default_argv():'
68 68 ipcdir = os.path.dirname(default.__file__)
69 69 ipconf = os.path.join(ipcdir,'ipython_config.py')
70 70 #print 'conf:',ipconf # dbg
71 return ['--colors=NoColor','--no-term-title','--config-file=%s' % ipconf]
71 return ['--colors=NoColor', '--no-term-title','--no-banner',
72 '--config-file=%s' % ipconf]
72 73
73 74
74 75 # Hack to modify the %run command so we can sync the user's namespace with the
General Comments 0
You need to be logged in to leave comments. Login now