##// END OF EJS Templates
ConfigLoader.py => config/configloader.py and updated all imports.
Brian Granger -
Show More
@@ -0,0 +1,6 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3
4 def test_import_configloader():
5 from IPython.config import configloader
6
1 NO CONTENT: file renamed from IPython/ConfigLoader.py to IPython/config/configloader.py
NO CONTENT: file renamed from IPython/ConfigLoader.py to IPython/config/configloader.py
@@ -1,773 +1,771 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 Requires Python 2.1 or better.
5 Requires Python 2.1 or better.
6
6
7 This file contains the main make_IPython() starter function.
7 This file contains the main make_IPython() starter function.
8 """
8 """
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #*****************************************************************************
16 #*****************************************************************************
17
17
18 try:
18 try:
19 credits._Printer__data = """
19 credits._Printer__data = """
20 Python: %s
20 Python: %s
21
21
22 IPython: The IPython Development Team.
22 IPython: The IPython Development Team.
23 See http://ipython.scipy.org for more information.""" \
23 See http://ipython.scipy.org for more information.""" \
24 % credits._Printer__data
24 % credits._Printer__data
25
25
26 copyright._Printer__data += """
26 copyright._Printer__data += """
27
27
28 Copyright (c) 2008-2009 The IPython Development Team.
28 Copyright (c) 2008-2009 The IPython Development Team.
29 Copyright (c) 2001-2007 Fernando Perez, Janko Hauser, Nathan Gray.
29 Copyright (c) 2001-2007 Fernando Perez, Janko Hauser, Nathan Gray.
30 All Rights Reserved."""
30 All Rights Reserved."""
31 except NameError:
31 except NameError:
32 # Can happen if ipython was started with 'python -S', so that site.py is
32 # Can happen if ipython was started with 'python -S', so that site.py is
33 # not loaded
33 # not loaded
34 pass
34 pass
35
35
36 #****************************************************************************
36 #****************************************************************************
37 # Required modules
37 # Required modules
38
38
39 # From the standard library
39 # From the standard library
40 import __main__
40 import __main__
41 import __builtin__
41 import __builtin__
42 import os
42 import os
43 import re
44 import sys
43 import sys
45 import types
44 from pprint import pprint
46 from pprint import pprint,pformat
47
45
48 # Our own
46 # Our own
49 from IPython import DPyGetOpt
47 from IPython import DPyGetOpt
50 from IPython import Release
48 from IPython import Release
51 from IPython.ipstruct import Struct
49 from IPython.ipstruct import Struct
52 from IPython.OutputTrap import OutputTrap
50 from IPython.OutputTrap import OutputTrap
53 from IPython.ConfigLoader import ConfigLoader
51 from IPython.config.configloader import ConfigLoader
54 from IPython.iplib import InteractiveShell
52 from IPython.iplib import InteractiveShell
55 from IPython.usage import cmd_line_usage,interactive_usage
53 from IPython.usage import cmd_line_usage,interactive_usage
56 from IPython.genutils import *
54 from IPython.genutils import *
57
55
58 def force_import(modname,force_reload=False):
56 def force_import(modname,force_reload=False):
59 if modname in sys.modules and force_reload:
57 if modname in sys.modules and force_reload:
60 info("reloading: %s" % modname)
58 info("reloading: %s" % modname)
61 reload(sys.modules[modname])
59 reload(sys.modules[modname])
62 else:
60 else:
63 __import__(modname)
61 __import__(modname)
64
62
65
63
66 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
67 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
65 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
68 rc_override=None,shell_class=InteractiveShell,
66 rc_override=None,shell_class=InteractiveShell,
69 embedded=False,**kw):
67 embedded=False,**kw):
70 """This is a dump of IPython into a single function.
68 """This is a dump of IPython into a single function.
71
69
72 Later it will have to be broken up in a sensible manner.
70 Later it will have to be broken up in a sensible manner.
73
71
74 Arguments:
72 Arguments:
75
73
76 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
74 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
77 script name, b/c DPyGetOpt strips the first argument only for the real
75 script name, b/c DPyGetOpt strips the first argument only for the real
78 sys.argv.
76 sys.argv.
79
77
80 - user_ns: a dict to be used as the user's namespace."""
78 - user_ns: a dict to be used as the user's namespace."""
81
79
82 #----------------------------------------------------------------------
80 #----------------------------------------------------------------------
83 # Defaults and initialization
81 # Defaults and initialization
84
82
85 # For developer debugging, deactivates crash handler and uses pdb.
83 # For developer debugging, deactivates crash handler and uses pdb.
86 DEVDEBUG = False
84 DEVDEBUG = False
87
85
88 if argv is None:
86 if argv is None:
89 argv = sys.argv
87 argv = sys.argv
90
88
91 # __IP is the main global that lives throughout and represents the whole
89 # __IP is the main global that lives throughout and represents the whole
92 # application. If the user redefines it, all bets are off as to what
90 # application. If the user redefines it, all bets are off as to what
93 # happens.
91 # happens.
94
92
95 # __IP is the name of he global which the caller will have accessible as
93 # __IP is the name of he global which the caller will have accessible as
96 # __IP.name. We set its name via the first parameter passed to
94 # __IP.name. We set its name via the first parameter passed to
97 # InteractiveShell:
95 # InteractiveShell:
98
96
99 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
97 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
100 embedded=embedded,**kw)
98 embedded=embedded,**kw)
101
99
102 # Put 'help' in the user namespace
100 # Put 'help' in the user namespace
103 try:
101 try:
104 from site import _Helper
102 from site import _Helper
105 IP.user_ns['help'] = _Helper()
103 IP.user_ns['help'] = _Helper()
106 except ImportError:
104 except ImportError:
107 warn('help() not available - check site.py')
105 warn('help() not available - check site.py')
108
106
109 if DEVDEBUG:
107 if DEVDEBUG:
110 # For developer debugging only (global flag)
108 # For developer debugging only (global flag)
111 from IPython import ultraTB
109 from IPython import ultraTB
112 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
110 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
113
111
114 IP.BANNER_PARTS = ['Python %s\n'
112 IP.BANNER_PARTS = ['Python %s\n'
115 'Type "copyright", "credits" or "license" '
113 'Type "copyright", "credits" or "license" '
116 'for more information.\n'
114 'for more information.\n'
117 % (sys.version.split('\n')[0],),
115 % (sys.version.split('\n')[0],),
118 "IPython %s -- An enhanced Interactive Python."
116 "IPython %s -- An enhanced Interactive Python."
119 % (Release.version,),
117 % (Release.version,),
120 """\
118 """\
121 ? -> Introduction and overview of IPython's features.
119 ? -> Introduction and overview of IPython's features.
122 %quickref -> Quick reference.
120 %quickref -> Quick reference.
123 help -> Python's own help system.
121 help -> Python's own help system.
124 object? -> Details about 'object'. ?object also works, ?? prints more.
122 object? -> Details about 'object'. ?object also works, ?? prints more.
125 """ ]
123 """ ]
126
124
127 IP.usage = interactive_usage
125 IP.usage = interactive_usage
128
126
129 # Platform-dependent suffix.
127 # Platform-dependent suffix.
130 if os.name == 'posix':
128 if os.name == 'posix':
131 rc_suffix = ''
129 rc_suffix = ''
132 else:
130 else:
133 rc_suffix = '.ini'
131 rc_suffix = '.ini'
134
132
135 # default directory for configuration
133 # default directory for configuration
136 ipythondir_def = get_ipython_dir()
134 ipythondir_def = get_ipython_dir()
137
135
138 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
136 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
139
137
140 # we need the directory where IPython itself is installed
138 # we need the directory where IPython itself is installed
141 import IPython
139 import IPython
142 IPython_dir = os.path.dirname(IPython.__file__)
140 IPython_dir = os.path.dirname(IPython.__file__)
143 del IPython
141 del IPython
144
142
145 #-------------------------------------------------------------------------
143 #-------------------------------------------------------------------------
146 # Command line handling
144 # Command line handling
147
145
148 # Valid command line options (uses DPyGetOpt syntax, like Perl's
146 # Valid command line options (uses DPyGetOpt syntax, like Perl's
149 # GetOpt::Long)
147 # GetOpt::Long)
150
148
151 # Any key not listed here gets deleted even if in the file (like session
149 # Any key not listed here gets deleted even if in the file (like session
152 # or profile). That's deliberate, to maintain the rc namespace clean.
150 # or profile). That's deliberate, to maintain the rc namespace clean.
153
151
154 # Each set of options appears twice: under _conv only the names are
152 # Each set of options appears twice: under _conv only the names are
155 # listed, indicating which type they must be converted to when reading the
153 # listed, indicating which type they must be converted to when reading the
156 # ipythonrc file. And under DPyGetOpt they are listed with the regular
154 # ipythonrc file. And under DPyGetOpt they are listed with the regular
157 # DPyGetOpt syntax (=s,=i,:f,etc).
155 # DPyGetOpt syntax (=s,=i,:f,etc).
158
156
159 # Make sure there's a space before each end of line (they get auto-joined!)
157 # Make sure there's a space before each end of line (they get auto-joined!)
160 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
158 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
161 'c=s classic|cl color_info! colors=s confirm_exit! '
159 'c=s classic|cl color_info! colors=s confirm_exit! '
162 'debug! deep_reload! editor=s log|l messages! nosep '
160 'debug! deep_reload! editor=s log|l messages! nosep '
163 'object_info_string_level=i pdb! '
161 'object_info_string_level=i pdb! '
164 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
162 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
165 'pydb! '
163 'pydb! '
166 'pylab_import_all! '
164 'pylab_import_all! '
167 'quick screen_length|sl=i prompts_pad_left=i '
165 'quick screen_length|sl=i prompts_pad_left=i '
168 'logfile|lf=s logplay|lp=s profile|p=s '
166 'logfile|lf=s logplay|lp=s profile|p=s '
169 'readline! readline_merge_completions! '
167 'readline! readline_merge_completions! '
170 'readline_omit__names! '
168 'readline_omit__names! '
171 'rcfile=s separate_in|si=s separate_out|so=s '
169 'rcfile=s separate_in|si=s separate_out|so=s '
172 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
170 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
173 'magic_docstrings system_verbose! '
171 'magic_docstrings system_verbose! '
174 'multi_line_specials! '
172 'multi_line_specials! '
175 'term_title! wxversion=s '
173 'term_title! wxversion=s '
176 'autoedit_syntax!')
174 'autoedit_syntax!')
177
175
178 # Options that can *only* appear at the cmd line (not in rcfiles).
176 # Options that can *only* appear at the cmd line (not in rcfiles).
179
177
180 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
178 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
181 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
179 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
182 # 'twisted!' # disabled for now.
180 # 'twisted!' # disabled for now.
183 )
181 )
184
182
185 # Build the actual name list to be used by DPyGetOpt
183 # Build the actual name list to be used by DPyGetOpt
186 opts_names = qw(cmdline_opts) + qw(cmdline_only)
184 opts_names = qw(cmdline_opts) + qw(cmdline_only)
187
185
188 # Set sensible command line defaults.
186 # Set sensible command line defaults.
189 # This should have everything from cmdline_opts and cmdline_only
187 # This should have everything from cmdline_opts and cmdline_only
190 opts_def = Struct(autocall = 1,
188 opts_def = Struct(autocall = 1,
191 autoedit_syntax = 0,
189 autoedit_syntax = 0,
192 autoindent = 0,
190 autoindent = 0,
193 automagic = 1,
191 automagic = 1,
194 autoexec = [],
192 autoexec = [],
195 banner = 1,
193 banner = 1,
196 c = '',
194 c = '',
197 cache_size = 1000,
195 cache_size = 1000,
198 classic = 0,
196 classic = 0,
199 color_info = 0,
197 color_info = 0,
200 colors = 'NoColor',
198 colors = 'NoColor',
201 confirm_exit = 1,
199 confirm_exit = 1,
202 debug = 0,
200 debug = 0,
203 deep_reload = 0,
201 deep_reload = 0,
204 editor = '0',
202 editor = '0',
205 gthread = 0,
203 gthread = 0,
206 help = 0,
204 help = 0,
207 interact = 0,
205 interact = 0,
208 ipythondir = ipythondir_def,
206 ipythondir = ipythondir_def,
209 log = 0,
207 log = 0,
210 logfile = '',
208 logfile = '',
211 logplay = '',
209 logplay = '',
212 messages = 1,
210 messages = 1,
213 multi_line_specials = 1,
211 multi_line_specials = 1,
214 nosep = 0,
212 nosep = 0,
215 object_info_string_level = 0,
213 object_info_string_level = 0,
216 pdb = 0,
214 pdb = 0,
217 pprint = 0,
215 pprint = 0,
218 profile = '',
216 profile = '',
219 prompt_in1 = 'In [\\#]: ',
217 prompt_in1 = 'In [\\#]: ',
220 prompt_in2 = ' .\\D.: ',
218 prompt_in2 = ' .\\D.: ',
221 prompt_out = 'Out[\\#]: ',
219 prompt_out = 'Out[\\#]: ',
222 prompts_pad_left = 1,
220 prompts_pad_left = 1,
223 pydb = 0,
221 pydb = 0,
224 pylab = 0,
222 pylab = 0,
225 pylab_import_all = 1,
223 pylab_import_all = 1,
226 q4thread = 0,
224 q4thread = 0,
227 qthread = 0,
225 qthread = 0,
228 quick = 0,
226 quick = 0,
229 quiet = 0,
227 quiet = 0,
230 rcfile = 'ipythonrc' + rc_suffix,
228 rcfile = 'ipythonrc' + rc_suffix,
231 readline = 1,
229 readline = 1,
232 readline_merge_completions = 1,
230 readline_merge_completions = 1,
233 readline_omit__names = 0,
231 readline_omit__names = 0,
234 screen_length = 0,
232 screen_length = 0,
235 separate_in = '\n',
233 separate_in = '\n',
236 separate_out = '\n',
234 separate_out = '\n',
237 separate_out2 = '',
235 separate_out2 = '',
238 system_header = 'IPython system call: ',
236 system_header = 'IPython system call: ',
239 system_verbose = 0,
237 system_verbose = 0,
240 term_title = 1,
238 term_title = 1,
241 tk = 0,
239 tk = 0,
242 #twisted= 0, # disabled for now
240 #twisted= 0, # disabled for now
243 upgrade = 0,
241 upgrade = 0,
244 Version = 0,
242 Version = 0,
245 wildcards_case_sensitive = 1,
243 wildcards_case_sensitive = 1,
246 wthread = 0,
244 wthread = 0,
247 wxversion = '0',
245 wxversion = '0',
248 xmode = 'Context',
246 xmode = 'Context',
249 magic_docstrings = 0, # undocumented, for doc generation
247 magic_docstrings = 0, # undocumented, for doc generation
250 )
248 )
251
249
252 # Things that will *only* appear in rcfiles (not at the command line).
250 # Things that will *only* appear in rcfiles (not at the command line).
253 # Make sure there's a space before each end of line (they get auto-joined!)
251 # Make sure there's a space before each end of line (they get auto-joined!)
254 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
252 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
255 qw_lol: 'import_some ',
253 qw_lol: 'import_some ',
256 # for things with embedded whitespace:
254 # for things with embedded whitespace:
257 list_strings:'execute alias readline_parse_and_bind ',
255 list_strings:'execute alias readline_parse_and_bind ',
258 # Regular strings need no conversion:
256 # Regular strings need no conversion:
259 None:'readline_remove_delims ',
257 None:'readline_remove_delims ',
260 }
258 }
261 # Default values for these
259 # Default values for these
262 rc_def = Struct(include = [],
260 rc_def = Struct(include = [],
263 import_mod = [],
261 import_mod = [],
264 import_all = [],
262 import_all = [],
265 import_some = [[]],
263 import_some = [[]],
266 execute = [],
264 execute = [],
267 execfile = [],
265 execfile = [],
268 alias = [],
266 alias = [],
269 readline_parse_and_bind = [],
267 readline_parse_and_bind = [],
270 readline_remove_delims = '',
268 readline_remove_delims = '',
271 )
269 )
272
270
273 # Build the type conversion dictionary from the above tables:
271 # Build the type conversion dictionary from the above tables:
274 typeconv = rcfile_opts.copy()
272 typeconv = rcfile_opts.copy()
275 typeconv.update(optstr2types(cmdline_opts))
273 typeconv.update(optstr2types(cmdline_opts))
276
274
277 # FIXME: the None key appears in both, put that back together by hand. Ugly!
275 # FIXME: the None key appears in both, put that back together by hand. Ugly!
278 typeconv[None] += ' ' + rcfile_opts[None]
276 typeconv[None] += ' ' + rcfile_opts[None]
279
277
280 # Remove quotes at ends of all strings (used to protect spaces)
278 # Remove quotes at ends of all strings (used to protect spaces)
281 typeconv[unquote_ends] = typeconv[None]
279 typeconv[unquote_ends] = typeconv[None]
282 del typeconv[None]
280 del typeconv[None]
283
281
284 # Build the list we'll use to make all config decisions with defaults:
282 # Build the list we'll use to make all config decisions with defaults:
285 opts_all = opts_def.copy()
283 opts_all = opts_def.copy()
286 opts_all.update(rc_def)
284 opts_all.update(rc_def)
287
285
288 # Build conflict resolver for recursive loading of config files:
286 # Build conflict resolver for recursive loading of config files:
289 # - preserve means the outermost file maintains the value, it is not
287 # - preserve means the outermost file maintains the value, it is not
290 # overwritten if an included file has the same key.
288 # overwritten if an included file has the same key.
291 # - add_flip applies + to the two values, so it better make sense to add
289 # - add_flip applies + to the two values, so it better make sense to add
292 # those types of keys. But it flips them first so that things loaded
290 # those types of keys. But it flips them first so that things loaded
293 # deeper in the inclusion chain have lower precedence.
291 # deeper in the inclusion chain have lower precedence.
294 conflict = {'preserve': ' '.join([ typeconv[int],
292 conflict = {'preserve': ' '.join([ typeconv[int],
295 typeconv[unquote_ends] ]),
293 typeconv[unquote_ends] ]),
296 'add_flip': ' '.join([ typeconv[qwflat],
294 'add_flip': ' '.join([ typeconv[qwflat],
297 typeconv[qw_lol],
295 typeconv[qw_lol],
298 typeconv[list_strings] ])
296 typeconv[list_strings] ])
299 }
297 }
300
298
301 # Now actually process the command line
299 # Now actually process the command line
302 getopt = DPyGetOpt.DPyGetOpt()
300 getopt = DPyGetOpt.DPyGetOpt()
303 getopt.setIgnoreCase(0)
301 getopt.setIgnoreCase(0)
304
302
305 getopt.parseConfiguration(opts_names)
303 getopt.parseConfiguration(opts_names)
306
304
307 try:
305 try:
308 getopt.processArguments(argv)
306 getopt.processArguments(argv)
309 except DPyGetOpt.ArgumentError, exc:
307 except DPyGetOpt.ArgumentError, exc:
310 print cmd_line_usage
308 print cmd_line_usage
311 warn('\nError in Arguments: "%s"' % exc)
309 warn('\nError in Arguments: "%s"' % exc)
312 sys.exit(1)
310 sys.exit(1)
313
311
314 # convert the options dict to a struct for much lighter syntax later
312 # convert the options dict to a struct for much lighter syntax later
315 opts = Struct(getopt.optionValues)
313 opts = Struct(getopt.optionValues)
316 args = getopt.freeValues
314 args = getopt.freeValues
317
315
318 # this is the struct (which has default values at this point) with which
316 # this is the struct (which has default values at this point) with which
319 # we make all decisions:
317 # we make all decisions:
320 opts_all.update(opts)
318 opts_all.update(opts)
321
319
322 # Options that force an immediate exit
320 # Options that force an immediate exit
323 if opts_all.help:
321 if opts_all.help:
324 page(cmd_line_usage)
322 page(cmd_line_usage)
325 sys.exit()
323 sys.exit()
326
324
327 if opts_all.Version:
325 if opts_all.Version:
328 print Release.version
326 print Release.version
329 sys.exit()
327 sys.exit()
330
328
331 if opts_all.magic_docstrings:
329 if opts_all.magic_docstrings:
332 IP.magic_magic('-latex')
330 IP.magic_magic('-latex')
333 sys.exit()
331 sys.exit()
334
332
335 # add personal ipythondir to sys.path so that users can put things in
333 # add personal ipythondir to sys.path so that users can put things in
336 # there for customization
334 # there for customization
337 sys.path.append(os.path.abspath(opts_all.ipythondir))
335 sys.path.append(os.path.abspath(opts_all.ipythondir))
338
336
339 # Create user config directory if it doesn't exist. This must be done
337 # Create user config directory if it doesn't exist. This must be done
340 # *after* getting the cmd line options.
338 # *after* getting the cmd line options.
341 if not os.path.isdir(opts_all.ipythondir):
339 if not os.path.isdir(opts_all.ipythondir):
342 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
340 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
343
341
344 # upgrade user config files while preserving a copy of the originals
342 # upgrade user config files while preserving a copy of the originals
345 if opts_all.upgrade:
343 if opts_all.upgrade:
346 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
344 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
347
345
348 # check mutually exclusive options in the *original* command line
346 # check mutually exclusive options in the *original* command line
349 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
347 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
350 qw('classic profile'),qw('classic rcfile')])
348 qw('classic profile'),qw('classic rcfile')])
351
349
352 #---------------------------------------------------------------------------
350 #---------------------------------------------------------------------------
353 # Log replay
351 # Log replay
354
352
355 # if -logplay, we need to 'become' the other session. That basically means
353 # if -logplay, we need to 'become' the other session. That basically means
356 # replacing the current command line environment with that of the old
354 # replacing the current command line environment with that of the old
357 # session and moving on.
355 # session and moving on.
358
356
359 # this is needed so that later we know we're in session reload mode, as
357 # this is needed so that later we know we're in session reload mode, as
360 # opts_all will get overwritten:
358 # opts_all will get overwritten:
361 load_logplay = 0
359 load_logplay = 0
362
360
363 if opts_all.logplay:
361 if opts_all.logplay:
364 load_logplay = opts_all.logplay
362 load_logplay = opts_all.logplay
365 opts_debug_save = opts_all.debug
363 opts_debug_save = opts_all.debug
366 try:
364 try:
367 logplay = open(opts_all.logplay)
365 logplay = open(opts_all.logplay)
368 except IOError:
366 except IOError:
369 if opts_all.debug: IP.InteractiveTB()
367 if opts_all.debug: IP.InteractiveTB()
370 warn('Could not open logplay file '+`opts_all.logplay`)
368 warn('Could not open logplay file '+`opts_all.logplay`)
371 # restore state as if nothing had happened and move on, but make
369 # restore state as if nothing had happened and move on, but make
372 # sure that later we don't try to actually load the session file
370 # sure that later we don't try to actually load the session file
373 logplay = None
371 logplay = None
374 load_logplay = 0
372 load_logplay = 0
375 del opts_all.logplay
373 del opts_all.logplay
376 else:
374 else:
377 try:
375 try:
378 logplay.readline()
376 logplay.readline()
379 logplay.readline();
377 logplay.readline();
380 # this reloads that session's command line
378 # this reloads that session's command line
381 cmd = logplay.readline()[6:]
379 cmd = logplay.readline()[6:]
382 exec cmd
380 exec cmd
383 # restore the true debug flag given so that the process of
381 # restore the true debug flag given so that the process of
384 # session loading itself can be monitored.
382 # session loading itself can be monitored.
385 opts.debug = opts_debug_save
383 opts.debug = opts_debug_save
386 # save the logplay flag so later we don't overwrite the log
384 # save the logplay flag so later we don't overwrite the log
387 opts.logplay = load_logplay
385 opts.logplay = load_logplay
388 # now we must update our own structure with defaults
386 # now we must update our own structure with defaults
389 opts_all.update(opts)
387 opts_all.update(opts)
390 # now load args
388 # now load args
391 cmd = logplay.readline()[6:]
389 cmd = logplay.readline()[6:]
392 exec cmd
390 exec cmd
393 logplay.close()
391 logplay.close()
394 except:
392 except:
395 logplay.close()
393 logplay.close()
396 if opts_all.debug: IP.InteractiveTB()
394 if opts_all.debug: IP.InteractiveTB()
397 warn("Logplay file lacking full configuration information.\n"
395 warn("Logplay file lacking full configuration information.\n"
398 "I'll try to read it, but some things may not work.")
396 "I'll try to read it, but some things may not work.")
399
397
400 #-------------------------------------------------------------------------
398 #-------------------------------------------------------------------------
401 # set up output traps: catch all output from files, being run, modules
399 # set up output traps: catch all output from files, being run, modules
402 # loaded, etc. Then give it to the user in a clean form at the end.
400 # loaded, etc. Then give it to the user in a clean form at the end.
403
401
404 msg_out = 'Output messages. '
402 msg_out = 'Output messages. '
405 msg_err = 'Error messages. '
403 msg_err = 'Error messages. '
406 msg_sep = '\n'
404 msg_sep = '\n'
407 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
405 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
408 msg_err,msg_sep,debug,
406 msg_err,msg_sep,debug,
409 quiet_out=1),
407 quiet_out=1),
410 user_exec = OutputTrap('User File Execution',msg_out,
408 user_exec = OutputTrap('User File Execution',msg_out,
411 msg_err,msg_sep,debug),
409 msg_err,msg_sep,debug),
412 logplay = OutputTrap('Log Loader',msg_out,
410 logplay = OutputTrap('Log Loader',msg_out,
413 msg_err,msg_sep,debug),
411 msg_err,msg_sep,debug),
414 summary = ''
412 summary = ''
415 )
413 )
416
414
417 #-------------------------------------------------------------------------
415 #-------------------------------------------------------------------------
418 # Process user ipythonrc-type configuration files
416 # Process user ipythonrc-type configuration files
419
417
420 # turn on output trapping and log to msg.config
418 # turn on output trapping and log to msg.config
421 # remember that with debug on, trapping is actually disabled
419 # remember that with debug on, trapping is actually disabled
422 msg.config.trap_all()
420 msg.config.trap_all()
423
421
424 # look for rcfile in current or default directory
422 # look for rcfile in current or default directory
425 try:
423 try:
426 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
424 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
427 except IOError:
425 except IOError:
428 if opts_all.debug: IP.InteractiveTB()
426 if opts_all.debug: IP.InteractiveTB()
429 warn('Configuration file %s not found. Ignoring request.'
427 warn('Configuration file %s not found. Ignoring request.'
430 % (opts_all.rcfile) )
428 % (opts_all.rcfile) )
431
429
432 # 'profiles' are a shorthand notation for config filenames
430 # 'profiles' are a shorthand notation for config filenames
433 profile_handled_by_legacy = False
431 profile_handled_by_legacy = False
434 if opts_all.profile:
432 if opts_all.profile:
435
433
436 try:
434 try:
437 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
435 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
438 + rc_suffix,
436 + rc_suffix,
439 opts_all.ipythondir)
437 opts_all.ipythondir)
440 profile_handled_by_legacy = True
438 profile_handled_by_legacy = True
441 except IOError:
439 except IOError:
442 if opts_all.debug: IP.InteractiveTB()
440 if opts_all.debug: IP.InteractiveTB()
443 opts.profile = '' # remove profile from options if invalid
441 opts.profile = '' # remove profile from options if invalid
444 # We won't warn anymore, primary method is ipy_profile_PROFNAME
442 # We won't warn anymore, primary method is ipy_profile_PROFNAME
445 # which does trigger a warning.
443 # which does trigger a warning.
446
444
447 # load the config file
445 # load the config file
448 rcfiledata = None
446 rcfiledata = None
449 if opts_all.quick:
447 if opts_all.quick:
450 print 'Launching IPython in quick mode. No config file read.'
448 print 'Launching IPython in quick mode. No config file read.'
451 elif opts_all.rcfile:
449 elif opts_all.rcfile:
452 try:
450 try:
453 cfg_loader = ConfigLoader(conflict)
451 cfg_loader = ConfigLoader(conflict)
454 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
452 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
455 'include',opts_all.ipythondir,
453 'include',opts_all.ipythondir,
456 purge = 1,
454 purge = 1,
457 unique = conflict['preserve'])
455 unique = conflict['preserve'])
458 except:
456 except:
459 IP.InteractiveTB()
457 IP.InteractiveTB()
460 warn('Problems loading configuration file '+
458 warn('Problems loading configuration file '+
461 `opts_all.rcfile`+
459 `opts_all.rcfile`+
462 '\nStarting with default -bare bones- configuration.')
460 '\nStarting with default -bare bones- configuration.')
463 else:
461 else:
464 warn('No valid configuration file found in either currrent directory\n'+
462 warn('No valid configuration file found in either currrent directory\n'+
465 'or in the IPython config. directory: '+`opts_all.ipythondir`+
463 'or in the IPython config. directory: '+`opts_all.ipythondir`+
466 '\nProceeding with internal defaults.')
464 '\nProceeding with internal defaults.')
467
465
468 #------------------------------------------------------------------------
466 #------------------------------------------------------------------------
469 # Set exception handlers in mode requested by user.
467 # Set exception handlers in mode requested by user.
470 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
468 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
471 IP.magic_xmode(opts_all.xmode)
469 IP.magic_xmode(opts_all.xmode)
472 otrap.release_out()
470 otrap.release_out()
473
471
474 #------------------------------------------------------------------------
472 #------------------------------------------------------------------------
475 # Execute user config
473 # Execute user config
476
474
477 # Create a valid config structure with the right precedence order:
475 # Create a valid config structure with the right precedence order:
478 # defaults < rcfile < command line. This needs to be in the instance, so
476 # defaults < rcfile < command line. This needs to be in the instance, so
479 # that method calls below that rely on it find it.
477 # that method calls below that rely on it find it.
480 IP.rc = rc_def.copy()
478 IP.rc = rc_def.copy()
481
479
482 # Work with a local alias inside this routine to avoid unnecessary
480 # Work with a local alias inside this routine to avoid unnecessary
483 # attribute lookups.
481 # attribute lookups.
484 IP_rc = IP.rc
482 IP_rc = IP.rc
485
483
486 IP_rc.update(opts_def)
484 IP_rc.update(opts_def)
487 if rcfiledata:
485 if rcfiledata:
488 # now we can update
486 # now we can update
489 IP_rc.update(rcfiledata)
487 IP_rc.update(rcfiledata)
490 IP_rc.update(opts)
488 IP_rc.update(opts)
491 IP_rc.update(rc_override)
489 IP_rc.update(rc_override)
492
490
493 # Store the original cmd line for reference:
491 # Store the original cmd line for reference:
494 IP_rc.opts = opts
492 IP_rc.opts = opts
495 IP_rc.args = args
493 IP_rc.args = args
496
494
497 # create a *runtime* Struct like rc for holding parameters which may be
495 # create a *runtime* Struct like rc for holding parameters which may be
498 # created and/or modified by runtime user extensions.
496 # created and/or modified by runtime user extensions.
499 IP.runtime_rc = Struct()
497 IP.runtime_rc = Struct()
500
498
501 # from this point on, all config should be handled through IP_rc,
499 # from this point on, all config should be handled through IP_rc,
502 # opts* shouldn't be used anymore.
500 # opts* shouldn't be used anymore.
503
501
504
502
505 # update IP_rc with some special things that need manual
503 # update IP_rc with some special things that need manual
506 # tweaks. Basically options which affect other options. I guess this
504 # tweaks. Basically options which affect other options. I guess this
507 # should just be written so that options are fully orthogonal and we
505 # should just be written so that options are fully orthogonal and we
508 # wouldn't worry about this stuff!
506 # wouldn't worry about this stuff!
509
507
510 if IP_rc.classic:
508 if IP_rc.classic:
511 IP_rc.quick = 1
509 IP_rc.quick = 1
512 IP_rc.cache_size = 0
510 IP_rc.cache_size = 0
513 IP_rc.pprint = 0
511 IP_rc.pprint = 0
514 IP_rc.prompt_in1 = '>>> '
512 IP_rc.prompt_in1 = '>>> '
515 IP_rc.prompt_in2 = '... '
513 IP_rc.prompt_in2 = '... '
516 IP_rc.prompt_out = ''
514 IP_rc.prompt_out = ''
517 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
515 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
518 IP_rc.colors = 'NoColor'
516 IP_rc.colors = 'NoColor'
519 IP_rc.xmode = 'Plain'
517 IP_rc.xmode = 'Plain'
520
518
521 IP.pre_config_initialization()
519 IP.pre_config_initialization()
522 # configure readline
520 # configure readline
523
521
524 # update exception handlers with rc file status
522 # update exception handlers with rc file status
525 otrap.trap_out() # I don't want these messages ever.
523 otrap.trap_out() # I don't want these messages ever.
526 IP.magic_xmode(IP_rc.xmode)
524 IP.magic_xmode(IP_rc.xmode)
527 otrap.release_out()
525 otrap.release_out()
528
526
529 # activate logging if requested and not reloading a log
527 # activate logging if requested and not reloading a log
530 if IP_rc.logplay:
528 if IP_rc.logplay:
531 IP.magic_logstart(IP_rc.logplay + ' append')
529 IP.magic_logstart(IP_rc.logplay + ' append')
532 elif IP_rc.logfile:
530 elif IP_rc.logfile:
533 IP.magic_logstart(IP_rc.logfile)
531 IP.magic_logstart(IP_rc.logfile)
534 elif IP_rc.log:
532 elif IP_rc.log:
535 IP.magic_logstart()
533 IP.magic_logstart()
536
534
537 # find user editor so that it we don't have to look it up constantly
535 # find user editor so that it we don't have to look it up constantly
538 if IP_rc.editor.strip()=='0':
536 if IP_rc.editor.strip()=='0':
539 try:
537 try:
540 ed = os.environ['EDITOR']
538 ed = os.environ['EDITOR']
541 except KeyError:
539 except KeyError:
542 if os.name == 'posix':
540 if os.name == 'posix':
543 ed = 'vi' # the only one guaranteed to be there!
541 ed = 'vi' # the only one guaranteed to be there!
544 else:
542 else:
545 ed = 'notepad' # same in Windows!
543 ed = 'notepad' # same in Windows!
546 IP_rc.editor = ed
544 IP_rc.editor = ed
547
545
548 # Keep track of whether this is an embedded instance or not (useful for
546 # Keep track of whether this is an embedded instance or not (useful for
549 # post-mortems).
547 # post-mortems).
550 IP_rc.embedded = IP.embedded
548 IP_rc.embedded = IP.embedded
551
549
552 # Recursive reload
550 # Recursive reload
553 try:
551 try:
554 from IPython import deep_reload
552 from IPython import deep_reload
555 if IP_rc.deep_reload:
553 if IP_rc.deep_reload:
556 __builtin__.reload = deep_reload.reload
554 __builtin__.reload = deep_reload.reload
557 else:
555 else:
558 __builtin__.dreload = deep_reload.reload
556 __builtin__.dreload = deep_reload.reload
559 del deep_reload
557 del deep_reload
560 except ImportError:
558 except ImportError:
561 pass
559 pass
562
560
563 # Save the current state of our namespace so that the interactive shell
561 # Save the current state of our namespace so that the interactive shell
564 # can later know which variables have been created by us from config files
562 # can later know which variables have been created by us from config files
565 # and loading. This way, loading a file (in any way) is treated just like
563 # and loading. This way, loading a file (in any way) is treated just like
566 # defining things on the command line, and %who works as expected.
564 # defining things on the command line, and %who works as expected.
567
565
568 # DON'T do anything that affects the namespace beyond this point!
566 # DON'T do anything that affects the namespace beyond this point!
569 IP.internal_ns.update(__main__.__dict__)
567 IP.internal_ns.update(__main__.__dict__)
570
568
571 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
569 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
572
570
573 # Now run through the different sections of the users's config
571 # Now run through the different sections of the users's config
574 if IP_rc.debug:
572 if IP_rc.debug:
575 print 'Trying to execute the following configuration structure:'
573 print 'Trying to execute the following configuration structure:'
576 print '(Things listed first are deeper in the inclusion tree and get'
574 print '(Things listed first are deeper in the inclusion tree and get'
577 print 'loaded first).\n'
575 print 'loaded first).\n'
578 pprint(IP_rc.__dict__)
576 pprint(IP_rc.__dict__)
579
577
580 for mod in IP_rc.import_mod:
578 for mod in IP_rc.import_mod:
581 try:
579 try:
582 exec 'import '+mod in IP.user_ns
580 exec 'import '+mod in IP.user_ns
583 except :
581 except :
584 IP.InteractiveTB()
582 IP.InteractiveTB()
585 import_fail_info(mod)
583 import_fail_info(mod)
586
584
587 for mod_fn in IP_rc.import_some:
585 for mod_fn in IP_rc.import_some:
588 if not mod_fn == []:
586 if not mod_fn == []:
589 mod,fn = mod_fn[0],','.join(mod_fn[1:])
587 mod,fn = mod_fn[0],','.join(mod_fn[1:])
590 try:
588 try:
591 exec 'from '+mod+' import '+fn in IP.user_ns
589 exec 'from '+mod+' import '+fn in IP.user_ns
592 except :
590 except :
593 IP.InteractiveTB()
591 IP.InteractiveTB()
594 import_fail_info(mod,fn)
592 import_fail_info(mod,fn)
595
593
596 for mod in IP_rc.import_all:
594 for mod in IP_rc.import_all:
597 try:
595 try:
598 exec 'from '+mod+' import *' in IP.user_ns
596 exec 'from '+mod+' import *' in IP.user_ns
599 except :
597 except :
600 IP.InteractiveTB()
598 IP.InteractiveTB()
601 import_fail_info(mod)
599 import_fail_info(mod)
602
600
603 for code in IP_rc.execute:
601 for code in IP_rc.execute:
604 try:
602 try:
605 exec code in IP.user_ns
603 exec code in IP.user_ns
606 except:
604 except:
607 IP.InteractiveTB()
605 IP.InteractiveTB()
608 warn('Failure executing code: ' + `code`)
606 warn('Failure executing code: ' + `code`)
609
607
610 # Execute the files the user wants in ipythonrc
608 # Execute the files the user wants in ipythonrc
611 for file in IP_rc.execfile:
609 for file in IP_rc.execfile:
612 try:
610 try:
613 file = filefind(file,sys.path+[IPython_dir])
611 file = filefind(file,sys.path+[IPython_dir])
614 except IOError:
612 except IOError:
615 warn(itpl('File $file not found. Skipping it.'))
613 warn(itpl('File $file not found. Skipping it.'))
616 else:
614 else:
617 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
615 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
618
616
619 # finally, try importing ipy_*_conf for final configuration
617 # finally, try importing ipy_*_conf for final configuration
620 try:
618 try:
621 import ipy_system_conf
619 import ipy_system_conf
622 except ImportError:
620 except ImportError:
623 if opts_all.debug: IP.InteractiveTB()
621 if opts_all.debug: IP.InteractiveTB()
624 warn("Could not import 'ipy_system_conf'")
622 warn("Could not import 'ipy_system_conf'")
625 except:
623 except:
626 IP.InteractiveTB()
624 IP.InteractiveTB()
627 import_fail_info('ipy_system_conf')
625 import_fail_info('ipy_system_conf')
628
626
629 # only import prof module if ipythonrc-PROF was not found
627 # only import prof module if ipythonrc-PROF was not found
630 if opts_all.profile and not profile_handled_by_legacy:
628 if opts_all.profile and not profile_handled_by_legacy:
631 profmodname = 'ipy_profile_' + opts_all.profile
629 profmodname = 'ipy_profile_' + opts_all.profile
632 try:
630 try:
633 force_import(profmodname)
631 force_import(profmodname)
634 except:
632 except:
635 IP.InteractiveTB()
633 IP.InteractiveTB()
636 print "Error importing",profmodname,\
634 print "Error importing",profmodname,\
637 "- perhaps you should run %upgrade?"
635 "- perhaps you should run %upgrade?"
638 import_fail_info(profmodname)
636 import_fail_info(profmodname)
639 else:
637 else:
640 opts.profile = opts_all.profile
638 opts.profile = opts_all.profile
641 else:
639 else:
642 force_import('ipy_profile_none')
640 force_import('ipy_profile_none')
643 # XXX - this is wrong: ipy_user_conf should not be loaded unconditionally,
641 # XXX - this is wrong: ipy_user_conf should not be loaded unconditionally,
644 # since the user could have specified a config file path by hand.
642 # since the user could have specified a config file path by hand.
645 try:
643 try:
646 force_import('ipy_user_conf')
644 force_import('ipy_user_conf')
647 except:
645 except:
648 conf = opts_all.ipythondir + "/ipy_user_conf.py"
646 conf = opts_all.ipythondir + "/ipy_user_conf.py"
649 IP.InteractiveTB()
647 IP.InteractiveTB()
650 if not os.path.isfile(conf):
648 if not os.path.isfile(conf):
651 warn(conf + ' does not exist, please run %upgrade!')
649 warn(conf + ' does not exist, please run %upgrade!')
652
650
653 import_fail_info("ipy_user_conf")
651 import_fail_info("ipy_user_conf")
654
652
655 # Define the history file for saving commands in between sessions
653 # Define the history file for saving commands in between sessions
656 try:
654 try:
657 histfname = 'history-%s' % opts.profile
655 histfname = 'history-%s' % opts.profile
658 except AttributeError:
656 except AttributeError:
659 histfname = 'history'
657 histfname = 'history'
660 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
658 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
661
659
662 # finally, push the argv to options again to ensure highest priority
660 # finally, push the argv to options again to ensure highest priority
663 IP_rc.update(opts)
661 IP_rc.update(opts)
664
662
665 # release stdout and stderr and save config log into a global summary
663 # release stdout and stderr and save config log into a global summary
666 msg.config.release_all()
664 msg.config.release_all()
667 if IP_rc.messages:
665 if IP_rc.messages:
668 msg.summary += msg.config.summary_all()
666 msg.summary += msg.config.summary_all()
669
667
670 #------------------------------------------------------------------------
668 #------------------------------------------------------------------------
671 # Setup interactive session
669 # Setup interactive session
672
670
673 # Now we should be fully configured. We can then execute files or load
671 # Now we should be fully configured. We can then execute files or load
674 # things only needed for interactive use. Then we'll open the shell.
672 # things only needed for interactive use. Then we'll open the shell.
675
673
676 # Take a snapshot of the user namespace before opening the shell. That way
674 # Take a snapshot of the user namespace before opening the shell. That way
677 # we'll be able to identify which things were interactively defined and
675 # we'll be able to identify which things were interactively defined and
678 # which were defined through config files.
676 # which were defined through config files.
679 IP.user_config_ns.update(IP.user_ns)
677 IP.user_config_ns.update(IP.user_ns)
680
678
681 # Force reading a file as if it were a session log. Slower but safer.
679 # Force reading a file as if it were a session log. Slower but safer.
682 if load_logplay:
680 if load_logplay:
683 print 'Replaying log...'
681 print 'Replaying log...'
684 try:
682 try:
685 if IP_rc.debug:
683 if IP_rc.debug:
686 logplay_quiet = 0
684 logplay_quiet = 0
687 else:
685 else:
688 logplay_quiet = 1
686 logplay_quiet = 1
689
687
690 msg.logplay.trap_all()
688 msg.logplay.trap_all()
691 IP.safe_execfile(load_logplay,IP.user_ns,
689 IP.safe_execfile(load_logplay,IP.user_ns,
692 islog = 1, quiet = logplay_quiet)
690 islog = 1, quiet = logplay_quiet)
693 msg.logplay.release_all()
691 msg.logplay.release_all()
694 if IP_rc.messages:
692 if IP_rc.messages:
695 msg.summary += msg.logplay.summary_all()
693 msg.summary += msg.logplay.summary_all()
696 except:
694 except:
697 warn('Problems replaying logfile %s.' % load_logplay)
695 warn('Problems replaying logfile %s.' % load_logplay)
698 IP.InteractiveTB()
696 IP.InteractiveTB()
699
697
700 # Load remaining files in command line
698 # Load remaining files in command line
701 msg.user_exec.trap_all()
699 msg.user_exec.trap_all()
702
700
703 # Do NOT execute files named in the command line as scripts to be loaded
701 # Do NOT execute files named in the command line as scripts to be loaded
704 # by embedded instances. Doing so has the potential for an infinite
702 # by embedded instances. Doing so has the potential for an infinite
705 # recursion if there are exceptions thrown in the process.
703 # recursion if there are exceptions thrown in the process.
706
704
707 # XXX FIXME: the execution of user files should be moved out to after
705 # XXX FIXME: the execution of user files should be moved out to after
708 # ipython is fully initialized, just as if they were run via %run at the
706 # ipython is fully initialized, just as if they were run via %run at the
709 # ipython prompt. This would also give them the benefit of ipython's
707 # ipython prompt. This would also give them the benefit of ipython's
710 # nice tracebacks.
708 # nice tracebacks.
711
709
712 if (not embedded and IP_rc.args and
710 if (not embedded and IP_rc.args and
713 not IP_rc.args[0].lower().endswith('.ipy')):
711 not IP_rc.args[0].lower().endswith('.ipy')):
714 name_save = IP.user_ns['__name__']
712 name_save = IP.user_ns['__name__']
715 IP.user_ns['__name__'] = '__main__'
713 IP.user_ns['__name__'] = '__main__'
716 # Set our own excepthook in case the user code tries to call it
714 # Set our own excepthook in case the user code tries to call it
717 # directly. This prevents triggering the IPython crash handler.
715 # directly. This prevents triggering the IPython crash handler.
718 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
716 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
719
717
720 save_argv = sys.argv[1:] # save it for later restoring
718 save_argv = sys.argv[1:] # save it for later restoring
721
719
722 sys.argv = args
720 sys.argv = args
723
721
724 try:
722 try:
725 IP.safe_execfile(args[0], IP.user_ns)
723 IP.safe_execfile(args[0], IP.user_ns)
726 finally:
724 finally:
727 # Reset our crash handler in place
725 # Reset our crash handler in place
728 sys.excepthook = old_excepthook
726 sys.excepthook = old_excepthook
729 sys.argv[:] = save_argv
727 sys.argv[:] = save_argv
730 IP.user_ns['__name__'] = name_save
728 IP.user_ns['__name__'] = name_save
731
729
732 msg.user_exec.release_all()
730 msg.user_exec.release_all()
733
731
734 if IP_rc.messages:
732 if IP_rc.messages:
735 msg.summary += msg.user_exec.summary_all()
733 msg.summary += msg.user_exec.summary_all()
736
734
737 # since we can't specify a null string on the cmd line, 0 is the equivalent:
735 # since we can't specify a null string on the cmd line, 0 is the equivalent:
738 if IP_rc.nosep:
736 if IP_rc.nosep:
739 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
737 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
740 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
738 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
741 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
739 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
742 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
740 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
743 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
741 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
744 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
742 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
745 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
743 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
746
744
747 # Determine how many lines at the bottom of the screen are needed for
745 # Determine how many lines at the bottom of the screen are needed for
748 # showing prompts, so we can know wheter long strings are to be printed or
746 # showing prompts, so we can know wheter long strings are to be printed or
749 # paged:
747 # paged:
750 num_lines_bot = IP_rc.separate_in.count('\n')+1
748 num_lines_bot = IP_rc.separate_in.count('\n')+1
751 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
749 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
752
750
753 # configure startup banner
751 # configure startup banner
754 if IP_rc.c: # regular python doesn't print the banner with -c
752 if IP_rc.c: # regular python doesn't print the banner with -c
755 IP_rc.banner = 0
753 IP_rc.banner = 0
756 if IP_rc.banner:
754 if IP_rc.banner:
757 BANN_P = IP.BANNER_PARTS
755 BANN_P = IP.BANNER_PARTS
758 else:
756 else:
759 BANN_P = []
757 BANN_P = []
760
758
761 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
759 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
762
760
763 # add message log (possibly empty)
761 # add message log (possibly empty)
764 if msg.summary: BANN_P.append(msg.summary)
762 if msg.summary: BANN_P.append(msg.summary)
765 # Final banner is a string
763 # Final banner is a string
766 IP.BANNER = '\n'.join(BANN_P)
764 IP.BANNER = '\n'.join(BANN_P)
767
765
768 # Finalize the IPython instance. This assumes the rc structure is fully
766 # Finalize the IPython instance. This assumes the rc structure is fully
769 # in place.
767 # in place.
770 IP.post_config_initialization()
768 IP.post_config_initialization()
771
769
772 return IP
770 return IP
773 #************************ end of file <ipmaker.py> **************************
771 #************************ end of file <ipmaker.py> **************************
@@ -1,300 +1,300 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Test Suite Runner.
2 """IPython Test Suite Runner.
3
3
4 This module provides a main entry point to a user script to test IPython
4 This module provides a main entry point to a user script to test IPython
5 itself from the command line. There are two ways of running this script:
5 itself from the command line. There are two ways of running this script:
6
6
7 1. With the syntax `iptest all`. This runs our entire test suite by
7 1. With the syntax `iptest all`. This runs our entire test suite by
8 calling this script (with different arguments) or trial recursively. This
8 calling this script (with different arguments) or trial recursively. This
9 causes modules and package to be tested in different processes, using nose
9 causes modules and package to be tested in different processes, using nose
10 or trial where appropriate.
10 or trial where appropriate.
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 the script simply calls nose, but with special command line flags and
12 the script simply calls nose, but with special command line flags and
13 plugins loaded.
13 plugins loaded.
14
14
15 For now, this script requires that both nose and twisted are installed. This
15 For now, this script requires that both nose and twisted are installed. This
16 will change in the future.
16 will change in the future.
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Module imports
20 # Module imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import os.path as path
24 import os.path as path
25 import sys
25 import sys
26 import subprocess
26 import subprocess
27 import time
27 import time
28 import warnings
28 import warnings
29
29
30 import nose.plugins.builtin
30 import nose.plugins.builtin
31 from nose.core import TestProgram
31 from nose.core import TestProgram
32
32
33 from IPython.platutils import find_cmd
33 from IPython.platutils import find_cmd
34 from IPython.testing.plugin.ipdoctest import IPythonDoctest
34 from IPython.testing.plugin.ipdoctest import IPythonDoctest
35
35
36 pjoin = path.join
36 pjoin = path.join
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Logic for skipping doctests
39 # Logic for skipping doctests
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 def test_for(mod):
42 def test_for(mod):
43 """Test to see if mod is importable."""
43 """Test to see if mod is importable."""
44 try:
44 try:
45 __import__(mod)
45 __import__(mod)
46 except ImportError:
46 except ImportError:
47 return False
47 return False
48 else:
48 else:
49 return True
49 return True
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_zi = test_for('zope.interface')
53 have_zi = test_for('zope.interface')
54 have_twisted = test_for('twisted')
54 have_twisted = test_for('twisted')
55 have_foolscap = test_for('foolscap')
55 have_foolscap = test_for('foolscap')
56 have_objc = test_for('objc')
56 have_objc = test_for('objc')
57 have_pexpect = test_for('pexpect')
57 have_pexpect = test_for('pexpect')
58
58
59 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
59 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
60 # testing problems. We should strive to minimize the number of skipped
60 # testing problems. We should strive to minimize the number of skipped
61 # modules, since this means untested code. As the testing machinery
61 # modules, since this means untested code. As the testing machinery
62 # solidifies, this list should eventually become empty.
62 # solidifies, this list should eventually become empty.
63 EXCLUDE = [pjoin('IPython', 'external'),
63 EXCLUDE = [pjoin('IPython', 'external'),
64 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
64 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
65 pjoin('IPython_doctest_plugin'),
65 pjoin('IPython_doctest_plugin'),
66 pjoin('IPython', 'Gnuplot'),
66 pjoin('IPython', 'Gnuplot'),
67 pjoin('IPython', 'Extensions', 'ipy_'),
67 pjoin('IPython', 'Extensions', 'ipy_'),
68 pjoin('IPython', 'Extensions', 'clearcmd'),
68 pjoin('IPython', 'Extensions', 'clearcmd'),
69 pjoin('IPython', 'Extensions', 'PhysicalQInteractive'),
69 pjoin('IPython', 'Extensions', 'PhysicalQInteractive'),
70 pjoin('IPython', 'Extensions', 'scitedirector'),
70 pjoin('IPython', 'Extensions', 'scitedirector'),
71 pjoin('IPython', 'Extensions', 'numeric_formats'),
71 pjoin('IPython', 'Extensions', 'numeric_formats'),
72 pjoin('IPython', 'testing', 'attic'),
72 pjoin('IPython', 'testing', 'attic'),
73 pjoin('IPython', 'testing', 'tutils'),
73 pjoin('IPython', 'testing', 'tutils'),
74 pjoin('IPython', 'testing', 'tools'),
74 pjoin('IPython', 'testing', 'tools'),
75 pjoin('IPython', 'testing', 'mkdoctests')
75 pjoin('IPython', 'testing', 'mkdoctests')
76 ]
76 ]
77
77
78 if not have_wx:
78 if not have_wx:
79 EXCLUDE.append(pjoin('IPython', 'Extensions', 'igrid'))
79 EXCLUDE.append(pjoin('IPython', 'Extensions', 'igrid'))
80 EXCLUDE.append(pjoin('IPython', 'gui'))
80 EXCLUDE.append(pjoin('IPython', 'gui'))
81 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
81 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
82
82
83 if not have_objc:
83 if not have_objc:
84 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
84 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
85
85
86 if not have_curses:
86 if not have_curses:
87 EXCLUDE.append(pjoin('IPython', 'Extensions', 'ibrowse'))
87 EXCLUDE.append(pjoin('IPython', 'Extensions', 'ibrowse'))
88
88
89 if not sys.platform == 'win32':
89 if not sys.platform == 'win32':
90 EXCLUDE.append(pjoin('IPython', 'platutils_win32'))
90 EXCLUDE.append(pjoin('IPython', 'platutils_win32'))
91
91
92 # These have to be skipped on win32 because the use echo, rm, cd, etc.
92 # These have to be skipped on win32 because the use echo, rm, cd, etc.
93 # See ticket https://bugs.launchpad.net/bugs/366982
93 # See ticket https://bugs.launchpad.net/bugs/366982
94 if sys.platform == 'win32':
94 if sys.platform == 'win32':
95 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'test_exampleip'))
95 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'test_exampleip'))
96 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'dtexample'))
96 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'dtexample'))
97
97
98 if not os.name == 'posix':
98 if not os.name == 'posix':
99 EXCLUDE.append(pjoin('IPython', 'platutils_posix'))
99 EXCLUDE.append(pjoin('IPython', 'platutils_posix'))
100
100
101 if not have_pexpect:
101 if not have_pexpect:
102 EXCLUDE.append(pjoin('IPython', 'irunner'))
102 EXCLUDE.append(pjoin('IPython', 'irunner'))
103
103
104 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
104 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
105 if sys.platform == 'win32':
105 if sys.platform == 'win32':
106 EXCLUDE = [s.replace('\\','\\\\') for s in EXCLUDE]
106 EXCLUDE = [s.replace('\\','\\\\') for s in EXCLUDE]
107
107
108
108
109 #-----------------------------------------------------------------------------
109 #-----------------------------------------------------------------------------
110 # Functions and classes
110 # Functions and classes
111 #-----------------------------------------------------------------------------
111 #-----------------------------------------------------------------------------
112
112
113 def run_iptest():
113 def run_iptest():
114 """Run the IPython test suite using nose.
114 """Run the IPython test suite using nose.
115
115
116 This function is called when this script is **not** called with the form
116 This function is called when this script is **not** called with the form
117 `iptest all`. It simply calls nose with appropriate command line flags
117 `iptest all`. It simply calls nose with appropriate command line flags
118 and accepts all of the standard nose arguments.
118 and accepts all of the standard nose arguments.
119 """
119 """
120
120
121 warnings.filterwarnings('ignore',
121 warnings.filterwarnings('ignore',
122 'This will be removed soon. Use IPython.testing.util instead')
122 'This will be removed soon. Use IPython.testing.util instead')
123
123
124 argv = sys.argv + [
124 argv = sys.argv + [
125 # Loading ipdoctest causes problems with Twisted.
125 # Loading ipdoctest causes problems with Twisted.
126 # I am removing this as a temporary fix to get the
126 # I am removing this as a temporary fix to get the
127 # test suite back into working shape. Our nose
127 # test suite back into working shape. Our nose
128 # plugin needs to be gone through with a fine
128 # plugin needs to be gone through with a fine
129 # toothed comb to find what is causing the problem.
129 # toothed comb to find what is causing the problem.
130 '--with-ipdoctest',
130 '--with-ipdoctest',
131 '--ipdoctest-tests','--ipdoctest-extension=txt',
131 '--ipdoctest-tests','--ipdoctest-extension=txt',
132 '--detailed-errors',
132 '--detailed-errors',
133
133
134 # We add --exe because of setuptools' imbecility (it
134 # We add --exe because of setuptools' imbecility (it
135 # blindly does chmod +x on ALL files). Nose does the
135 # blindly does chmod +x on ALL files). Nose does the
136 # right thing and it tries to avoid executables,
136 # right thing and it tries to avoid executables,
137 # setuptools unfortunately forces our hand here. This
137 # setuptools unfortunately forces our hand here. This
138 # has been discussed on the distutils list and the
138 # has been discussed on the distutils list and the
139 # setuptools devs refuse to fix this problem!
139 # setuptools devs refuse to fix this problem!
140 '--exe',
140 '--exe',
141 ]
141 ]
142
142
143 # Detect if any tests were required by explicitly calling an IPython
143 # Detect if any tests were required by explicitly calling an IPython
144 # submodule or giving a specific path
144 # submodule or giving a specific path
145 has_tests = False
145 has_tests = False
146 for arg in sys.argv:
146 for arg in sys.argv:
147 if 'IPython' in arg or arg.endswith('.py') or \
147 if 'IPython' in arg or arg.endswith('.py') or \
148 (':' in arg and '.py' in arg):
148 (':' in arg and '.py' in arg):
149 has_tests = True
149 has_tests = True
150 break
150 break
151
151
152 # If nothing was specifically requested, test full IPython
152 # If nothing was specifically requested, test full IPython
153 if not has_tests:
153 if not has_tests:
154 argv.append('IPython')
154 argv.append('IPython')
155
155
156 # Construct list of plugins, omitting the existing doctest plugin, which
156 # Construct list of plugins, omitting the existing doctest plugin, which
157 # ours replaces (and extends).
157 # ours replaces (and extends).
158 plugins = [IPythonDoctest(EXCLUDE)]
158 plugins = [IPythonDoctest(EXCLUDE)]
159 for p in nose.plugins.builtin.plugins:
159 for p in nose.plugins.builtin.plugins:
160 plug = p()
160 plug = p()
161 if plug.name == 'doctest':
161 if plug.name == 'doctest':
162 continue
162 continue
163
163
164 #print '*** adding plugin:',plug.name # dbg
164 #print '*** adding plugin:',plug.name # dbg
165 plugins.append(plug)
165 plugins.append(plug)
166
166
167 TestProgram(argv=argv,plugins=plugins)
167 TestProgram(argv=argv,plugins=plugins)
168
168
169
169
170 class IPTester(object):
170 class IPTester(object):
171 """Call that calls iptest or trial in a subprocess.
171 """Call that calls iptest or trial in a subprocess.
172 """
172 """
173 def __init__(self,runner='iptest',params=None):
173 def __init__(self,runner='iptest',params=None):
174 """ """
174 """ """
175 if runner == 'iptest':
175 if runner == 'iptest':
176 self.runner = ['iptest','-v']
176 self.runner = ['iptest','-v']
177 else:
177 else:
178 self.runner = [find_cmd('trial')]
178 self.runner = [find_cmd('trial')]
179 if params is None:
179 if params is None:
180 params = []
180 params = []
181 if isinstance(params,str):
181 if isinstance(params,str):
182 params = [params]
182 params = [params]
183 self.params = params
183 self.params = params
184
184
185 # Assemble call
185 # Assemble call
186 self.call_args = self.runner+self.params
186 self.call_args = self.runner+self.params
187
187
188 def run(self):
188 def run(self):
189 """Run the stored commands"""
189 """Run the stored commands"""
190 return subprocess.call(self.call_args)
190 return subprocess.call(self.call_args)
191
191
192
192
193 def make_runners():
193 def make_runners():
194 """Define the modules and packages that need to be tested.
194 """Define the modules and packages that need to be tested.
195 """
195 """
196
196
197 # This omits additional top-level modules that should not be doctested.
197 # This omits additional top-level modules that should not be doctested.
198 # XXX: Shell.py is also ommited because of a bug in the skip_doctest
198 # XXX: Shell.py is also ommited because of a bug in the skip_doctest
199 # decorator. See ticket https://bugs.launchpad.net/bugs/366209
199 # decorator. See ticket https://bugs.launchpad.net/bugs/366209
200 top_mod = \
200 top_mod = \
201 ['backgroundjobs.py', 'coloransi.py', 'completer.py', 'ConfigLoader.py',
201 ['backgroundjobs.py', 'coloransi.py', 'completer.py', 'configloader.py',
202 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py',
202 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py',
203 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py',
203 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py',
204 'generics.py', 'genutils.py', 'history.py', 'hooks.py', 'ipapi.py',
204 'generics.py', 'genutils.py', 'history.py', 'hooks.py', 'ipapi.py',
205 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'Itpl.py',
205 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'Itpl.py',
206 'Logger.py', 'macro.py', 'Magic.py', 'OInspect.py',
206 'Logger.py', 'macro.py', 'Magic.py', 'OInspect.py',
207 'OutputTrap.py', 'platutils.py', 'prefilter.py', 'Prompts.py',
207 'OutputTrap.py', 'platutils.py', 'prefilter.py', 'Prompts.py',
208 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py',
208 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py',
209 'shellglobals.py', 'strdispatch.py', 'twshell.py',
209 'shellglobals.py', 'strdispatch.py', 'twshell.py',
210 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py',
210 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py',
211 # See note above for why this is skipped
211 # See note above for why this is skipped
212 # 'Shell.py',
212 # 'Shell.py',
213 'winconsole.py']
213 'winconsole.py']
214
214
215 if have_pexpect:
215 if have_pexpect:
216 top_mod.append('irunner.py')
216 top_mod.append('irunner.py')
217
217
218 if sys.platform == 'win32':
218 if sys.platform == 'win32':
219 top_mod.append('platutils_win32.py')
219 top_mod.append('platutils_win32.py')
220 elif os.name == 'posix':
220 elif os.name == 'posix':
221 top_mod.append('platutils_posix.py')
221 top_mod.append('platutils_posix.py')
222 else:
222 else:
223 top_mod.append('platutils_dummy.py')
223 top_mod.append('platutils_dummy.py')
224
224
225 # These are tested by nose, so skip IPython.kernel
225 # These are tested by nose, so skip IPython.kernel
226 top_pack = ['config','Extensions','frontend',
226 top_pack = ['config','Extensions','frontend',
227 'testing','tests','tools','UserConfig']
227 'testing','tests','tools','UserConfig']
228
228
229 if have_wx:
229 if have_wx:
230 top_pack.append('gui')
230 top_pack.append('gui')
231
231
232 modules = ['IPython.%s' % m[:-3] for m in top_mod ]
232 modules = ['IPython.%s' % m[:-3] for m in top_mod ]
233 packages = ['IPython.%s' % m for m in top_pack ]
233 packages = ['IPython.%s' % m for m in top_pack ]
234
234
235 # Make runners
235 # Make runners
236 runners = dict(zip(top_pack, [IPTester(params=v) for v in packages]))
236 runners = dict(zip(top_pack, [IPTester(params=v) for v in packages]))
237
237
238 # Test IPython.kernel using trial if twisted is installed
238 # Test IPython.kernel using trial if twisted is installed
239 if have_zi and have_twisted and have_foolscap:
239 if have_zi and have_twisted and have_foolscap:
240 runners['trial'] = IPTester('trial',['IPython'])
240 runners['trial'] = IPTester('trial',['IPython'])
241
241
242 runners['modules'] = IPTester(params=modules)
242 runners['modules'] = IPTester(params=modules)
243
243
244 return runners
244 return runners
245
245
246
246
247 def run_iptestall():
247 def run_iptestall():
248 """Run the entire IPython test suite by calling nose and trial.
248 """Run the entire IPython test suite by calling nose and trial.
249
249
250 This function constructs :class:`IPTester` instances for all IPython
250 This function constructs :class:`IPTester` instances for all IPython
251 modules and package and then runs each of them. This causes the modules
251 modules and package and then runs each of them. This causes the modules
252 and packages of IPython to be tested each in their own subprocess using
252 and packages of IPython to be tested each in their own subprocess using
253 nose or twisted.trial appropriately.
253 nose or twisted.trial appropriately.
254 """
254 """
255 runners = make_runners()
255 runners = make_runners()
256 # Run all test runners, tracking execution time
256 # Run all test runners, tracking execution time
257 failed = {}
257 failed = {}
258 t_start = time.time()
258 t_start = time.time()
259 for name,runner in runners.iteritems():
259 for name,runner in runners.iteritems():
260 print '*'*77
260 print '*'*77
261 print 'IPython test set:',name
261 print 'IPython test set:',name
262 res = runner.run()
262 res = runner.run()
263 if res:
263 if res:
264 failed[name] = res
264 failed[name] = res
265 t_end = time.time()
265 t_end = time.time()
266 t_tests = t_end - t_start
266 t_tests = t_end - t_start
267 nrunners = len(runners)
267 nrunners = len(runners)
268 nfail = len(failed)
268 nfail = len(failed)
269 # summarize results
269 # summarize results
270 print
270 print
271 print '*'*77
271 print '*'*77
272 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
272 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
273 print
273 print
274 if not failed:
274 if not failed:
275 print 'OK'
275 print 'OK'
276 else:
276 else:
277 # If anything went wrong, point out what command to rerun manually to
277 # If anything went wrong, point out what command to rerun manually to
278 # see the actual errors and individual summary
278 # see the actual errors and individual summary
279 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
279 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
280 for name in failed:
280 for name in failed:
281 failed_runner = runners[name]
281 failed_runner = runners[name]
282 print '-'*40
282 print '-'*40
283 print 'Runner failed:',name
283 print 'Runner failed:',name
284 print 'You may wish to rerun this one individually, with:'
284 print 'You may wish to rerun this one individually, with:'
285 print ' '.join(failed_runner.call_args)
285 print ' '.join(failed_runner.call_args)
286 print
286 print
287
287
288
288
289 def main():
289 def main():
290 if len(sys.argv) == 1:
290 if len(sys.argv) == 1:
291 run_iptestall()
291 run_iptestall()
292 else:
292 else:
293 if sys.argv[1] == 'all':
293 if sys.argv[1] == 'all':
294 run_iptestall()
294 run_iptestall()
295 else:
295 else:
296 run_iptest()
296 run_iptest()
297
297
298
298
299 if __name__ == '__main__':
299 if __name__ == '__main__':
300 main() No newline at end of file
300 main()
General Comments 0
You need to be logged in to leave comments. Login now