##// END OF EJS Templates
Refactored the command line config system and other aspects of config....
Brian Granger -
Show More
@@ -299,7 +299,7 b' class CommandLineConfigLoader(ConfigLoader):'
299 299
300 300 class ArgParseConfigLoader(CommandLineConfigLoader):
301 301
302 def __init__(self, argv=None, arguments=(), *parser_args, **parser_kw):
302 def __init__(self, argv=None, *parser_args, **parser_kw):
303 303 """Create a config loader for use with argparse.
304 304
305 305 Parameters
@@ -309,11 +309,6 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
309 309 If given, used to read command-line arguments from, otherwise
310 310 sys.argv[1:] is used.
311 311
312 arguments : optional, tuple
313 A tuple of two element tuples each having the form (args, kwargs).
314 Each such pair is passed to parser.add_argument(*args, **kwargs)
315 in sequence to configure the parser.
316
317 312 parser_args : tuple
318 313 A tuple of positional arguments that will be passed to the
319 314 constructor of :class:`argparse.ArgumentParser`.
@@ -326,7 +321,6 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
326 321 if argv == None:
327 322 argv = sys.argv[1:]
328 323 self.argv = argv
329 self.arguments = arguments
330 324 self.parser_args = parser_args
331 325 kwargs = dict(argument_default=argparse.SUPPRESS)
332 326 kwargs.update(parser_kw)
@@ -359,19 +353,9 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
359 353 def _create_parser(self):
360 354 self.parser = ArgumentParser(*self.parser_args, **self.parser_kw)
361 355 self._add_arguments()
362 self._add_other_arguments()
363 356
364 357 def _add_arguments(self):
365 for argument in self.arguments:
366 # Remove any defaults in case people add them. We can't have
367 # command line default because all default are determined by
368 # traited class attributes.
369 argument[1].pop('default', None)
370 self.parser.add_argument(*argument[0], **argument[1])
371
372 def _add_other_arguments(self):
373 """Meant for subclasses to add their own arguments."""
374 pass
358 raise NotImplementedError("subclasses must implement _add_arguments")
375 359
376 360 def _parse_args(self, args):
377 361 """self.parser->self.parsed_data"""
@@ -61,18 +61,26 b' class TestPyFileCL(TestCase):'
61 61 self.assertEquals(config.Foo.Bam.value, range(10))
62 62 self.assertEquals(config.D.C.value, 'hi there')
63 63
64
65 arguments = (
66 (('-f','--foo'), dict(dest='Global.foo', type=str)),
67 (('-b',), dict(dest='MyClass.bar', type=int)),
68 (('-n',), dict(dest='n', action='store_true')),
69 (('Global.bam',), dict(type=str))
70 )
64 class MyLoader1(ArgParseConfigLoader):
65 def _add_arguments(self):
66 p = self.parser
67 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
68 p.add_argument('-b', dest='MyClass.bar', type=int)
69 p.add_argument('-n', dest='n', action='store_true')
70 p.add_argument('Global.bam', type=str)
71
72 class MyLoader2(ArgParseConfigLoader):
73 def _add_arguments(self):
74 subparsers = self.parser.add_subparsers(dest='subparser_name')
75 subparser1 = subparsers.add_parser('1')
76 subparser1.add_argument('-x',dest='Global.x')
77 subparser2 = subparsers.add_parser('2')
78 subparser2.add_argument('y')
71 79
72 80 class TestArgParseCL(TestCase):
73 81
74 82 def test_basic(self):
75 cl = ArgParseConfigLoader(arguments=arguments)
83 cl = MyLoader1()
76 84 config = cl.load_config('-f hi -b 10 -n wow'.split())
77 85 self.assertEquals(config.Global.foo, 'hi')
78 86 self.assertEquals(config.MyClass.bar, 10)
@@ -84,16 +92,7 b' class TestArgParseCL(TestCase):'
84 92 self.assertEquals(config.Global.bam, 'wow')
85 93
86 94 def test_add_arguments(self):
87
88 class MyLoader(ArgParseConfigLoader):
89 def _add_arguments(self):
90 subparsers = self.parser.add_subparsers(dest='subparser_name')
91 subparser1 = subparsers.add_parser('1')
92 subparser1.add_argument('-x',dest='Global.x')
93 subparser2 = subparsers.add_parser('2')
94 subparser2.add_argument('y')
95
96 cl = MyLoader()
95 cl = MyLoader2()
97 96 config = cl.load_config('2 frobble'.split())
98 97 self.assertEquals(config.subparser_name, '2')
99 98 self.assertEquals(config.y, 'frobble')
@@ -102,10 +101,7 b' class TestArgParseCL(TestCase):'
102 101 self.assertEquals(config.Global.x, 'frobble')
103 102
104 103 def test_argv(self):
105 cl = ArgParseConfigLoader(
106 argv='-f hi -b 10 -n wow'.split(),
107 arguments=arguments
108 )
104 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
109 105 config = cl.load_config()
110 106 self.assertEquals(config.Global.foo, 'hi')
111 107 self.assertEquals(config.MyClass.bar, 10)
@@ -48,94 +48,75 b' class ApplicationError(Exception):'
48 48 pass
49 49
50 50
51 app_cl_args = (
52 (('--ipython-dir', ), dict(
53 dest='Global.ipython_dir',type=unicode,
54 help=
55 """Set to override default location of the IPython directory
56 IPYTHON_DIR, stored as Global.ipython_dir. This can also be specified
57 through the environment variable IPYTHON_DIR.""",
58 metavar='Global.ipython_dir') ),
59 (('-p', '--profile',), dict(
60 dest='Global.profile',type=unicode,
61 help=
62 """The string name of the ipython profile to be used. Assume that your
63 config file is ipython_config-<name>.py (looks in current dir first,
64 then in IPYTHON_DIR). This is a quick way to keep and load multiple
65 config files for different tasks, especially if include your basic one
66 in your more specialized ones. You can keep a basic
67 IPYTHON_DIR/ipython_config.py file and then have other 'profiles' which
68 include this one and load extra things for particular tasks.""",
69 metavar='Global.profile') ),
70 (('--log-level',), dict(
71 dest="Global.log_level",type=int,
72 help='Set the log level (0,10,20,30,40,50). Default is 30.',
73 metavar='Global.log_level')),
74 (('--config-file',), dict(
75 dest='Global.config_file',type=unicode,
76 help=
77 """Set the config file name to override default. Normally IPython
78 loads ipython_config.py (from current directory) or
79 IPYTHON_DIR/ipython_config.py. If the loading of your config file
80 fails, IPython starts with a bare bones configuration (no modules
81 loaded at all).""",
82 metavar='Global.config_file')),
83 )
51 class BaseAppConfigLoader(ArgParseConfigLoader):
52 """Default command line options for IPython based applications."""
53
54 def _add_ipython_dir(self, parser):
55 """Add the --ipython-dir option to the parser."""
56 paa = parser.add_argument
57 paa('--ipython-dir',
58 dest='Global.ipython_dir',type=unicode,
59 help=
60 """Set to override default location of the IPython directory
61 IPYTHON_DIR, stored as Global.ipython_dir. This can also be
62 specified through the environment variable IPYTHON_DIR.""",
63 metavar='Global.ipython_dir')
64
65 def _add_log_level(self, parser):
66 """Add the --log-level option to the parser."""
67 paa = parser.add_argument
68 paa('--log-level',
69 dest="Global.log_level",type=int,
70 help='Set the log level (0,10,20,30,40,50). Default is 30.',
71 metavar='Global.log_level')
72
73 def _add_arguments(self):
74 self._add_ipython_dir(self.parser)
75 self._add_log_level(self.parser)
76
84 77
85 78 class Application(object):
86 79 """Load a config, construct components and set them running.
87 80
88 The configuration of an application can be done via four different Config
89 objects, which are loaded and ultimately merged into a single one used from
90 that point on by the app. These are:
81 The configuration of an application can be done via three different Config
82 objects, which are loaded and ultimately merged into a single one used
83 from that point on by the app. These are:
91 84
92 85 1. default_config: internal defaults, implemented in code.
93 86 2. file_config: read from the filesystem.
94 87 3. command_line_config: read from the system's command line flags.
95 4. constructor_config: passed parametrically to the constructor.
96 88
97 89 During initialization, 3 is actually read before 2, since at the
98 90 command-line one may override the location of the file to be read. But the
99 91 above is the order in which the merge is made.
100
101 There is a final config object can be created and passed to the
102 constructor: override_config. If it exists, this completely overrides the
103 configs 2-4 above (the default is still used to ensure that all needed
104 fields at least are created). This makes it easier to create
105 parametrically (e.g. in testing or sphinx plugins) objects with a known
106 configuration, that are unaffected by whatever arguments may be present in
107 sys.argv or files in the user's various directories.
108 92 """
109 93
110 94 name = u'ipython'
111 95 description = 'IPython: an enhanced interactive Python shell.'
112 #: usage message printed by argparse. If None, auto-generate
96 #: Usage message printed by argparse. If None, auto-generate
113 97 usage = None
98 #: The command line config loader. Subclass of ArgParseConfigLoader.
99 command_line_loader = BaseAppConfigLoader
100 #: The name of the config file to load.
114 101 config_file_name = u'ipython_config.py'
115 #: Track the default and actual separately because some messages are
116 #: only printed if we aren't using the default.
102 #: The name of the default config file. Track separately from the actual
103 #: name because some logic happens only if we aren't using the default.
117 104 default_config_file_name = config_file_name
118 105 default_log_level = logging.WARN
119 106 #: Set by --profile option
120 107 profile_name = None
121 108 #: User's ipython directory, typically ~/.ipython/
122 109 ipython_dir = None
123 #: internal defaults, implemented in code.
110 #: Internal defaults, implemented in code.
124 111 default_config = None
125 #: read from the filesystem
112 #: Read from the filesystem.
126 113 file_config = None
127 #: read from the system's command line flags
114 #: Read from the system's command line flags.
128 115 command_line_config = None
129 #: passed parametrically to the constructor.
130 constructor_config = None
131 #: final override, if given supercedes file/command/constructor configs
132 override_config = None
116 #: The final config that will be passed to the component.
117 master_config = None
133 118 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
134 119 argv = None
135 #: Default command line arguments. Subclasses should create a new tuple
136 #: that *includes* these.
137 cl_arguments = app_cl_args
138
139 120 #: extra arguments computed by the command-line loader
140 121 extra_args = None
141 122
@@ -146,10 +127,8 b' class Application(object):'
146 127 # Class choices for things that will be instantiated at runtime.
147 128 _CrashHandler = crashhandler.CrashHandler
148 129
149 def __init__(self, argv=None, constructor_config=None, override_config=None):
130 def __init__(self, argv=None):
150 131 self.argv = sys.argv[1:] if argv is None else argv
151 self.constructor_config = constructor_config
152 self.override_config = override_config
153 132 self.init_logger()
154 133
155 134 def init_logger(self):
@@ -194,13 +173,12 b' class Application(object):'
194 173 self.log_default_config()
195 174 self.set_default_config_log_level()
196 175
197 if self.override_config is None:
198 # Command-line config
199 self.pre_load_command_line_config()
200 self.load_command_line_config()
201 self.set_command_line_config_log_level()
202 self.post_load_command_line_config()
203 self.log_command_line_config()
176 # Command-line config
177 self.pre_load_command_line_config()
178 self.load_command_line_config()
179 self.set_command_line_config_log_level()
180 self.post_load_command_line_config()
181 self.log_command_line_config()
204 182
205 183 # Find resources needed for filesystem access, using information from
206 184 # the above two
@@ -209,13 +187,12 b' class Application(object):'
209 187 self.find_config_file_name()
210 188 self.find_config_file_paths()
211 189
212 if self.override_config is None:
213 # File-based config
214 self.pre_load_file_config()
215 self.load_file_config()
216 self.set_file_config_log_level()
217 self.post_load_file_config()
218 self.log_file_config()
190 # File-based config
191 self.pre_load_file_config()
192 self.load_file_config()
193 self.set_file_config_log_level()
194 self.post_load_file_config()
195 self.log_file_config()
219 196
220 197 # Merge all config objects into a single one the app can then use
221 198 self.merge_configs()
@@ -270,11 +247,12 b' class Application(object):'
270 247
271 248 def create_command_line_config(self):
272 249 """Create and return a command line config loader."""
273 return ArgParseConfigLoader(self.argv, self.cl_arguments,
274 description=self.description,
275 version=release.version,
276 usage=self.usage,
277 )
250 return self.command_line_loader(
251 self.argv,
252 description=self.description,
253 version=release.version,
254 usage=self.usage
255 )
278 256
279 257 def pre_load_command_line_config(self):
280 258 """Do actions just before loading the command line config."""
@@ -418,13 +396,9 b' class Application(object):'
418 396 """Merge the default, command line and file config objects."""
419 397 config = Config()
420 398 config._merge(self.default_config)
421 if self.override_config is None:
422 config._merge(self.file_config)
423 config._merge(self.command_line_config)
424 if self.constructor_config is not None:
425 config._merge(self.constructor_config)
426 else:
427 config._merge(self.override_config)
399 config._merge(self.file_config)
400 config._merge(self.command_line_config)
401
428 402 # XXX fperez - propose to Brian we rename master_config to simply
429 403 # config, I think this is going to be heavily used in examples and
430 404 # application code and the name is shorter/easier to find/remember.
@@ -221,3 +221,4 b' class IPythonCrashHandler(CrashHandler):'
221 221 pass
222 222
223 223 return ''.join(report)
224
This diff has been collapsed as it changes many lines, (608 lines changed) Show them Hide them
@@ -28,7 +28,7 b' import os'
28 28 import sys
29 29
30 30 from IPython.core import crashhandler
31 from IPython.core.application import Application
31 from IPython.core.application import Application, BaseAppConfigLoader
32 32 from IPython.core.iplib import InteractiveShell
33 33 from IPython.config.loader import (
34 34 Config,
@@ -42,305 +42,279 b' from . import usage'
42 42 # Globals, utilities and helpers
43 43 #-----------------------------------------------------------------------------
44 44
45 #: The default config file name for this application.
45 46 default_config_file_name = u'ipython_config.py'
46 47
47 cl_args = (
48 (('--autocall',), dict(
49 type=int, dest='InteractiveShell.autocall',
50 help=
51 """Make IPython automatically call any callable object even if you
52 didn't type explicit parentheses. For example, 'str 43' becomes
53 'str(43)' automatically. The value can be '0' to disable the feature,
54 '1' for 'smart' autocall, where it is not applied if there are no more
55 arguments on the line, and '2' for 'full' autocall, where all callable
56 objects are automatically called (even if no arguments are present).
57 The default is '1'.""",
58 metavar='InteractiveShell.autocall')
59 ),
60 (('--autoindent',), dict(
61 action='store_true', dest='InteractiveShell.autoindent',
62 help='Turn on autoindenting.')
63 ),
64 (('--no-autoindent',), dict(
65 action='store_false', dest='InteractiveShell.autoindent',
66 help='Turn off autoindenting.')
67 ),
68 (('--automagic',), dict(
69 action='store_true', dest='InteractiveShell.automagic',
70 help='Turn on the auto calling of magic commands.'
71 'Type %%magic at the IPython prompt for more information.')
72 ),
73 (('--no-automagic',), dict(
74 action='store_false', dest='InteractiveShell.automagic',
75 help='Turn off the auto calling of magic commands.')
76 ),
77 (('--autoedit-syntax',), dict(
78 action='store_true', dest='InteractiveShell.autoedit_syntax',
79 help='Turn on auto editing of files with syntax errors.')
80 ),
81 (('--no-autoedit-syntax',), dict(
82 action='store_false', dest='InteractiveShell.autoedit_syntax',
83 help='Turn off auto editing of files with syntax errors.')
84 ),
85 (('--banner',), dict(
86 action='store_true', dest='Global.display_banner',
87 help='Display a banner upon starting IPython.')
88 ),
89 (('--no-banner',), dict(
90 action='store_false', dest='Global.display_banner',
91 help="Don't display a banner upon starting IPython.")
92 ),
93 (('--cache-size',), dict(
94 type=int, dest='InteractiveShell.cache_size',
95 help=
96 """Set the size of the output cache. The default is 1000, you can
97 change it permanently in your config file. Setting it to 0 completely
98 disables the caching system, and the minimum value accepted is 20 (if
99 you provide a value less than 20, it is reset to 0 and a warning is
100 issued). This limit is defined because otherwise you'll spend more
101 time re-flushing a too small cache than working.
102 """,
103 metavar='InteractiveShell.cache_size')
104 ),
105 (('--classic',), dict(
106 action='store_true', dest='Global.classic',
107 help="Gives IPython a similar feel to the classic Python prompt.")
108 ),
109 (('--colors',), dict(
110 type=str, dest='InteractiveShell.colors',
111 help="Set the color scheme (NoColor, Linux, and LightBG).",
112 metavar='InteractiveShell.colors')
113 ),
114 (('--color-info',), dict(
115 action='store_true', dest='InteractiveShell.color_info',
116 help=
117 """IPython can display information about objects via a set of func-
118 tions, and optionally can use colors for this, syntax highlighting
119 source code and various other elements. However, because this
120 information is passed through a pager (like 'less') and many pagers get
121 confused with color codes, this option is off by default. You can test
122 it and turn it on permanently in your ipython_config.py file if it
123 works for you. Test it and turn it on permanently if it works with
124 your system. The magic function %%color_info allows you to toggle this
125 inter- actively for testing."""
126 )
127 ),
128 (('--no-color-info',), dict(
129 action='store_false', dest='InteractiveShell.color_info',
130 help="Disable using colors for info related things.")
131 ),
132 (('--confirm-exit',), dict(
133 action='store_true', dest='InteractiveShell.confirm_exit',
134 help=
135 """Set to confirm when you try to exit IPython with an EOF (Control-D
136 in Unix, Control-Z/Enter in Windows). By typing 'exit', 'quit' or
137 '%%Exit', you can force a direct exit without any confirmation.
138 """
139 )
140 ),
141 (('--no-confirm-exit',), dict(
142 action='store_false', dest='InteractiveShell.confirm_exit',
143 help="Don't prompt the user when exiting.")
144 ),
145 (('--deep-reload',), dict(
146 action='store_true', dest='InteractiveShell.deep_reload',
147 help=
148 """Enable deep (recursive) reloading by default. IPython can use the
149 deep_reload module which reloads changes in modules recursively (it
150 replaces the reload() function, so you don't need to change anything to
151 use it). deep_reload() forces a full reload of modules whose code may
152 have changed, which the default reload() function does not. When
153 deep_reload is off, IPython will use the normal reload(), but
154 deep_reload will still be available as dreload(). This fea- ture is off
155 by default [which means that you have both normal reload() and
156 dreload()].""")
157 ),
158 (('--no-deep-reload',), dict(
159 action='store_false', dest='InteractiveShell.deep_reload',
160 help="Disable deep (recursive) reloading by default.")
161 ),
162 (('--editor',), dict(
163 type=str, dest='InteractiveShell.editor',
164 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
165 metavar='InteractiveShell.editor')
166 ),
167 (('--log','-l'), dict(
168 action='store_true', dest='InteractiveShell.logstart',
169 help="Start logging to the default log file (./ipython_log.py).")
170 ),
171 (('--logfile','-lf'), dict(
172 type=unicode, dest='InteractiveShell.logfile',
173 help="Start logging to logfile with this name.",
174 metavar='InteractiveShell.logfile')
175 ),
176 (('--log-append','-la'), dict(
177 type=unicode, dest='InteractiveShell.logappend',
178 help="Start logging to the given file in append mode.",
179 metavar='InteractiveShell.logfile')
180 ),
181 (('--pdb',), dict(
182 action='store_true', dest='InteractiveShell.pdb',
183 help="Enable auto calling the pdb debugger after every exception.")
184 ),
185 (('--no-pdb',), dict(
186 action='store_false', dest='InteractiveShell.pdb',
187 help="Disable auto calling the pdb debugger after every exception.")
188 ),
189 (('--pprint',), dict(
190 action='store_true', dest='InteractiveShell.pprint',
191 help="Enable auto pretty printing of results.")
192 ),
193 (('--no-pprint',), dict(
194 action='store_false', dest='InteractiveShell.pprint',
195 help="Disable auto auto pretty printing of results.")
196 ),
197 (('--prompt-in1','-pi1'), dict(
198 type=str, dest='InteractiveShell.prompt_in1',
199 help=
200 """Set the main input prompt ('In [\#]: '). Note that if you are using
201 numbered prompts, the number is represented with a '\#' in the string.
202 Don't forget to quote strings with spaces embedded in them. Most
203 bash-like escapes can be used to customize IPython's prompts, as well
204 as a few additional ones which are IPython-spe- cific. All valid
205 prompt escapes are described in detail in the Customization section of
206 the IPython manual.""",
207 metavar='InteractiveShell.prompt_in1')
208 ),
209 (('--prompt-in2','-pi2'), dict(
210 type=str, dest='InteractiveShell.prompt_in2',
211 help=
212 """Set the secondary input prompt (' .\D.: '). Similar to the previous
213 option, but used for the continuation prompts. The special sequence
214 '\D' is similar to '\#', but with all digits replaced by dots (so you
215 can have your continuation prompt aligned with your input prompt).
216 Default: ' .\D.: ' (note three spaces at the start for alignment with
217 'In [\#]')""",
218 metavar='InteractiveShell.prompt_in2')
219 ),
220 (('--prompt-out','-po'), dict(
221 type=str, dest='InteractiveShell.prompt_out',
222 help="Set the output prompt ('Out[\#]:')",
223 metavar='InteractiveShell.prompt_out')
224 ),
225 (('--quick',), dict(
226 action='store_true', dest='Global.quick',
227 help="Enable quick startup with no config files.")
228 ),
229 (('--readline',), dict(
230 action='store_true', dest='InteractiveShell.readline_use',
231 help="Enable readline for command line usage.")
232 ),
233 (('--no-readline',), dict(
234 action='store_false', dest='InteractiveShell.readline_use',
235 help="Disable readline for command line usage.")
236 ),
237 (('--screen-length','-sl'), dict(
238 type=int, dest='InteractiveShell.screen_length',
239 help=
240 """Number of lines of your screen, used to control printing of very
241 long strings. Strings longer than this number of lines will be sent
242 through a pager instead of directly printed. The default value for
243 this is 0, which means IPython will auto-detect your screen size every
244 time it needs to print certain potentially long strings (this doesn't
245 change the behavior of the 'print' keyword, it's only triggered
246 internally). If for some reason this isn't working well (it needs
247 curses support), specify it yourself. Otherwise don't change the
248 default.""",
249 metavar='InteractiveShell.screen_length')
250 ),
251 (('--separate-in','-si'), dict(
252 type=str, dest='InteractiveShell.separate_in',
253 help="Separator before input prompts. Default '\\n'.",
254 metavar='InteractiveShell.separate_in')
255 ),
256 (('--separate-out','-so'), dict(
257 type=str, dest='InteractiveShell.separate_out',
258 help="Separator before output prompts. Default 0 (nothing).",
259 metavar='InteractiveShell.separate_out')
260 ),
261 (('--separate-out2','-so2'), dict(
262 type=str, dest='InteractiveShell.separate_out2',
263 help="Separator after output prompts. Default 0 (nonight).",
264 metavar='InteractiveShell.separate_out2')
265 ),
266 (('-no-sep',), dict(
267 action='store_true', dest='Global.nosep',
268 help="Eliminate all spacing between prompts.")
269 ),
270 (('--term-title',), dict(
271 action='store_true', dest='InteractiveShell.term_title',
272 help="Enable auto setting the terminal title.")
273 ),
274 (('--no-term-title',), dict(
275 action='store_false', dest='InteractiveShell.term_title',
276 help="Disable auto setting the terminal title.")
277 ),
278 (('--xmode',), dict(
279 type=str, dest='InteractiveShell.xmode',
280 help=
281 """Exception reporting mode ('Plain','Context','Verbose'). Plain:
282 similar to python's normal traceback printing. Context: prints 5 lines
283 of context source code around each line in the traceback. Verbose:
284 similar to Context, but additionally prints the variables currently
285 visible where the exception happened (shortening their strings if too
286 long). This can potentially be very slow, if you happen to have a huge
287 data structure whose string representation is complex to compute.
288 Your computer may appear to freeze for a while with cpu usage at 100%%.
289 If this occurs, you can cancel the traceback with Ctrl-C (maybe hitting
290 it more than once).
291 """,
292 metavar='InteractiveShell.xmode')
293 ),
294 (('--ext',), dict(
295 type=str, dest='Global.extra_extension',
296 help="The dotted module name of an IPython extension to load.",
297 metavar='Global.extra_extension')
298 ),
299 (('-c',), dict(
300 type=str, dest='Global.code_to_run',
301 help="Execute the given command string.",
302 metavar='Global.code_to_run')
303 ),
304 (('-i',), dict(
305 action='store_true', dest='Global.force_interact',
306 help=
307 "If running code from the command line, become interactive afterwards."
308 )
309 ),
310
311 # Options to start with GUI control enabled from the beginning
312 (('--gui',), dict(
313 type=str, dest='Global.gui',
314 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
315 metavar='gui-mode')
316 ),
317
318 (('--pylab','-pylab'), dict(
319 type=str, dest='Global.pylab',
320 nargs='?', const='auto', metavar='gui-mode',
321 help="Pre-load matplotlib and numpy for interactive use. "+
322 "If no value is given, the gui backend is matplotlib's, else use "+
323 "one of: ['tk', 'qt', 'wx', 'gtk'].")
324 ),
325
326 # Legacy GUI options. Leave them in for backwards compatibility, but the
327 # 'thread' names are really a misnomer now.
328 (('--wthread','-wthread'), dict(
329 action='store_true', dest='Global.wthread',
330 help="Enable wxPython event loop integration "+
331 "(DEPRECATED, use --gui wx)")
332 ),
333 (('--q4thread','--qthread','-q4thread','-qthread'), dict(
334 action='store_true', dest='Global.q4thread',
335 help="Enable Qt4 event loop integration. Qt3 is no longer supported. "+
336 "(DEPRECATED, use --gui qt)")
337 ),
338 (('--gthread','-gthread'), dict(
339 action='store_true', dest='Global.gthread',
340 help="Enable GTK event loop integration. "+
341 "(DEPRECATED, use --gui gtk)")
342 ),
343 )
48
49 class IPAppConfigLoader(BaseAppConfigLoader):
50
51 def _add_arguments(self):
52 super(IPAppConfigLoader, self)._add_arguments()
53 paa = self.parser.add_argument
54 paa('-p',
55 '--profile', dest='Global.profile', type=unicode,
56 help=
57 """The string name of the ipython profile to be used. Assume that your
58 config file is ipython_config-<name>.py (looks in current dir first,
59 then in IPYTHON_DIR). This is a quick way to keep and load multiple
60 config files for different tasks, especially if include your basic one
61 in your more specialized ones. You can keep a basic
62 IPYTHON_DIR/ipython_config.py file and then have other 'profiles' which
63 include this one and load extra things for particular tasks.""",
64 metavar='Global.profile')
65 paa('--config-file',
66 dest='Global.config_file', type=unicode,
67 help=
68 """Set the config file name to override default. Normally IPython
69 loads ipython_config.py (from current directory) or
70 IPYTHON_DIR/ipython_config.py. If the loading of your config file
71 fails, IPython starts with a bare bones configuration (no modules
72 loaded at all).""",
73 metavar='Global.config_file')
74 paa('--autocall',
75 dest='InteractiveShell.autocall', type=int,
76 help=
77 """Make IPython automatically call any callable object even if you
78 didn't type explicit parentheses. For example, 'str 43' becomes
79 'str(43)' automatically. The value can be '0' to disable the feature,
80 '1' for 'smart' autocall, where it is not applied if there are no more
81 arguments on the line, and '2' for 'full' autocall, where all callable
82 objects are automatically called (even if no arguments are present).
83 The default is '1'.""",
84 metavar='InteractiveShell.autocall')
85 paa('--autoindent',
86 action='store_true', dest='InteractiveShell.autoindent',
87 help='Turn on autoindenting.')
88 paa('--no-autoindent',
89 action='store_false', dest='InteractiveShell.autoindent',
90 help='Turn off autoindenting.')
91 paa('--automagic',
92 action='store_true', dest='InteractiveShell.automagic',
93 help=
94 """Turn on the auto calling of magic commands. Type %%magic at the
95 IPython prompt for more information.""")
96 paa('--no-automagic',
97 action='store_false', dest='InteractiveShell.automagic',
98 help='Turn off the auto calling of magic commands.')
99 paa('--autoedit-syntax',
100 action='store_true', dest='InteractiveShell.autoedit_syntax',
101 help='Turn on auto editing of files with syntax errors.')
102 paa('--no-autoedit-syntax',
103 action='store_false', dest='InteractiveShell.autoedit_syntax',
104 help='Turn off auto editing of files with syntax errors.')
105 paa('--banner',
106 action='store_true', dest='Global.display_banner',
107 help='Display a banner upon starting IPython.')
108 paa('--no-banner',
109 action='store_false', dest='Global.display_banner',
110 help="Don't display a banner upon starting IPython.")
111 paa('--cache-size',
112 type=int, dest='InteractiveShell.cache_size',
113 help=
114 """Set the size of the output cache. The default is 1000, you can
115 change it permanently in your config file. Setting it to 0 completely
116 disables the caching system, and the minimum value accepted is 20 (if
117 you provide a value less than 20, it is reset to 0 and a warning is
118 issued). This limit is defined because otherwise you'll spend more
119 time re-flushing a too small cache than working""",
120 metavar='InteractiveShell.cache_size')
121 paa('--classic',
122 action='store_true', dest='Global.classic',
123 help="Gives IPython a similar feel to the classic Python prompt.")
124 paa('--colors',
125 type=str, dest='InteractiveShell.colors',
126 help="Set the color scheme (NoColor, Linux, and LightBG).",
127 metavar='InteractiveShell.colors')
128 paa('--color-info',
129 action='store_true', dest='InteractiveShell.color_info',
130 help=
131 """IPython can display information about objects via a set of func-
132 tions, and optionally can use colors for this, syntax highlighting
133 source code and various other elements. However, because this
134 information is passed through a pager (like 'less') and many pagers get
135 confused with color codes, this option is off by default. You can test
136 it and turn it on permanently in your ipython_config.py file if it
137 works for you. Test it and turn it on permanently if it works with
138 your system. The magic function %%color_info allows you to toggle this
139 inter- actively for testing.""")
140 paa('--no-color-info',
141 action='store_false', dest='InteractiveShell.color_info',
142 help="Disable using colors for info related things.")
143 paa('--confirm-exit',
144 action='store_true', dest='InteractiveShell.confirm_exit',
145 help=
146 """Set to confirm when you try to exit IPython with an EOF (Control-D
147 in Unix, Control-Z/Enter in Windows). By typing 'exit', 'quit' or
148 '%%Exit', you can force a direct exit without any confirmation.""")
149 paa('--no-confirm-exit',
150 action='store_false', dest='InteractiveShell.confirm_exit',
151 help="Don't prompt the user when exiting.")
152 paa('--deep-reload',
153 action='store_true', dest='InteractiveShell.deep_reload',
154 help=
155 """Enable deep (recursive) reloading by default. IPython can use the
156 deep_reload module which reloads changes in modules recursively (it
157 replaces the reload() function, so you don't need to change anything to
158 use it). deep_reload() forces a full reload of modules whose code may
159 have changed, which the default reload() function does not. When
160 deep_reload is off, IPython will use the normal reload(), but
161 deep_reload will still be available as dreload(). This fea- ture is off
162 by default [which means that you have both normal reload() and
163 dreload()].""")
164 paa('--no-deep-reload',
165 action='store_false', dest='InteractiveShell.deep_reload',
166 help="Disable deep (recursive) reloading by default.")
167 paa('--editor',
168 type=str, dest='InteractiveShell.editor',
169 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
170 metavar='InteractiveShell.editor')
171 paa('--log','-l',
172 action='store_true', dest='InteractiveShell.logstart',
173 help="Start logging to the default log file (./ipython_log.py).")
174 paa('--logfile','-lf',
175 type=unicode, dest='InteractiveShell.logfile',
176 help="Start logging to logfile with this name.",
177 metavar='InteractiveShell.logfile')
178 paa('--log-append','-la',
179 type=unicode, dest='InteractiveShell.logappend',
180 help="Start logging to the given file in append mode.",
181 metavar='InteractiveShell.logfile')
182 paa('--pdb',
183 action='store_true', dest='InteractiveShell.pdb',
184 help="Enable auto calling the pdb debugger after every exception.")
185 paa('--no-pdb',
186 action='store_false', dest='InteractiveShell.pdb',
187 help="Disable auto calling the pdb debugger after every exception.")
188 paa('--pprint',
189 action='store_true', dest='InteractiveShell.pprint',
190 help="Enable auto pretty printing of results.")
191 paa('--no-pprint',
192 action='store_false', dest='InteractiveShell.pprint',
193 help="Disable auto auto pretty printing of results.")
194 paa('--prompt-in1','-pi1',
195 type=str, dest='InteractiveShell.prompt_in1',
196 help=
197 """Set the main input prompt ('In [\#]: '). Note that if you are using
198 numbered prompts, the number is represented with a '\#' in the string.
199 Don't forget to quote strings with spaces embedded in them. Most
200 bash-like escapes can be used to customize IPython's prompts, as well
201 as a few additional ones which are IPython-spe- cific. All valid
202 prompt escapes are described in detail in the Customization section of
203 the IPython manual.""",
204 metavar='InteractiveShell.prompt_in1')
205 paa('--prompt-in2','-pi2',
206 type=str, dest='InteractiveShell.prompt_in2',
207 help=
208 """Set the secondary input prompt (' .\D.: '). Similar to the previous
209 option, but used for the continuation prompts. The special sequence
210 '\D' is similar to '\#', but with all digits replaced by dots (so you
211 can have your continuation prompt aligned with your input prompt).
212 Default: ' .\D.: ' (note three spaces at the start for alignment with
213 'In [\#]')""",
214 metavar='InteractiveShell.prompt_in2')
215 paa('--prompt-out','-po',
216 type=str, dest='InteractiveShell.prompt_out',
217 help="Set the output prompt ('Out[\#]:')",
218 metavar='InteractiveShell.prompt_out')
219 paa('--quick',
220 action='store_true', dest='Global.quick',
221 help="Enable quick startup with no config files.")
222 paa('--readline',
223 action='store_true', dest='InteractiveShell.readline_use',
224 help="Enable readline for command line usage.")
225 paa('--no-readline',
226 action='store_false', dest='InteractiveShell.readline_use',
227 help="Disable readline for command line usage.")
228 paa('--screen-length','-sl',
229 type=int, dest='InteractiveShell.screen_length',
230 help=
231 """Number of lines of your screen, used to control printing of very
232 long strings. Strings longer than this number of lines will be sent
233 through a pager instead of directly printed. The default value for
234 this is 0, which means IPython will auto-detect your screen size every
235 time it needs to print certain potentially long strings (this doesn't
236 change the behavior of the 'print' keyword, it's only triggered
237 internally). If for some reason this isn't working well (it needs
238 curses support), specify it yourself. Otherwise don't change the
239 default.""",
240 metavar='InteractiveShell.screen_length')
241 paa('--separate-in','-si',
242 type=str, dest='InteractiveShell.separate_in',
243 help="Separator before input prompts. Default '\\n'.",
244 metavar='InteractiveShell.separate_in')
245 paa('--separate-out','-so',
246 type=str, dest='InteractiveShell.separate_out',
247 help="Separator before output prompts. Default 0 (nothing).",
248 metavar='InteractiveShell.separate_out')
249 paa('--separate-out2','-so2',
250 type=str, dest='InteractiveShell.separate_out2',
251 help="Separator after output prompts. Default 0 (nonight).",
252 metavar='InteractiveShell.separate_out2')
253 paa('-no-sep',
254 action='store_true', dest='Global.nosep',
255 help="Eliminate all spacing between prompts.")
256 paa('--term-title',
257 action='store_true', dest='InteractiveShell.term_title',
258 help="Enable auto setting the terminal title.")
259 paa('--no-term-title',
260 action='store_false', dest='InteractiveShell.term_title',
261 help="Disable auto setting the terminal title.")
262 paa('--xmode',
263 type=str, dest='InteractiveShell.xmode',
264 help=
265 """Exception reporting mode ('Plain','Context','Verbose'). Plain:
266 similar to python's normal traceback printing. Context: prints 5 lines
267 of context source code around each line in the traceback. Verbose:
268 similar to Context, but additionally prints the variables currently
269 visible where the exception happened (shortening their strings if too
270 long). This can potentially be very slow, if you happen to have a huge
271 data structure whose string representation is complex to compute.
272 Your computer may appear to freeze for a while with cpu usage at 100%%.
273 If this occurs, you can cancel the traceback with Ctrl-C (maybe hitting
274 it more than once).
275 """,
276 metavar='InteractiveShell.xmode')
277 paa('--ext',
278 type=str, dest='Global.extra_extension',
279 help="The dotted module name of an IPython extension to load.",
280 metavar='Global.extra_extension')
281 paa('-c',
282 type=str, dest='Global.code_to_run',
283 help="Execute the given command string.",
284 metavar='Global.code_to_run')
285 paa('-i',
286 action='store_true', dest='Global.force_interact',
287 help=
288 "If running code from the command line, become interactive afterwards.")
289
290 # Options to start with GUI control enabled from the beginning
291 paa('--gui',
292 type=str, dest='Global.gui',
293 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
294 metavar='gui-mode')
295 paa('--pylab','-pylab',
296 type=str, dest='Global.pylab',
297 nargs='?', const='auto', metavar='gui-mode',
298 help="Pre-load matplotlib and numpy for interactive use. "+
299 "If no value is given, the gui backend is matplotlib's, else use "+
300 "one of: ['tk', 'qt', 'wx', 'gtk'].")
301
302 # Legacy GUI options. Leave them in for backwards compatibility, but the
303 # 'thread' names are really a misnomer now.
304 paa('--wthread', '-wthread',
305 action='store_true', dest='Global.wthread',
306 help=
307 """Enable wxPython event loop integration. (DEPRECATED, use --gui wx)""")
308 paa('--q4thread', '--qthread', '-q4thread', '-qthread',
309 action='store_true', dest='Global.q4thread',
310 help=
311 """Enable Qt4 event loop integration. Qt3 is no longer supported.
312 (DEPRECATED, use --gui qt)""")
313 paa('--gthread', '-gthread',
314 action='store_true', dest='Global.gthread',
315 help=
316 """Enable GTK event loop integration. (DEPRECATED, use --gui gtk)""")
317
344 318
345 319 #-----------------------------------------------------------------------------
346 320 # Main classes and functions
@@ -350,44 +324,12 b' class IPythonApp(Application):'
350 324 name = u'ipython'
351 325 #: argparse formats better the 'usage' than the 'description' field
352 326 description = None
353 #: usage message printed by argparse. If None, auto-generate
354 327 usage = usage.cl_usage
355
328 command_line_loader = IPAppConfigLoader
356 329 config_file_name = default_config_file_name
357 330
358 cl_arguments = Application.cl_arguments + cl_args
359
360 331 # Private and configuration attributes
361 332 _CrashHandler = crashhandler.IPythonCrashHandler
362
363 def __init__(self, argv=None,
364 constructor_config=None, override_config=None,
365 **shell_params):
366 """Create a new IPythonApp.
367
368 See the parent class for details on how configuration is handled.
369
370 Parameters
371 ----------
372 argv : optional, list
373 If given, used as the command-line argv environment to read arguments
374 from.
375
376 constructor_config : optional, Config
377 If given, additional config that is merged last, after internal
378 defaults, command-line and file-based configs.
379
380 override_config : optional, Config
381 If given, config that overrides all others unconditionally (except
382 for internal defaults, which ensure that all parameters exist).
383
384 shell_params : optional, dict
385 All other keywords are passed to the :class:`iplib.InteractiveShell`
386 constructor.
387 """
388 super(IPythonApp, self).__init__(argv, constructor_config,
389 override_config)
390 self.shell_params = shell_params
391 333
392 334 def create_default_config(self):
393 335 super(IPythonApp, self).create_default_config()
@@ -473,8 +415,7 b' class IPythonApp(Application):'
473 415 sys.path.insert(0, '')
474 416
475 417 # Create an InteractiveShell instance
476 self.shell = InteractiveShell(None, self.master_config,
477 **self.shell_params )
418 self.shell = InteractiveShell(None, self.master_config)
478 419
479 420 def post_construct(self):
480 421 """Do actions after construct, but before starting the app."""
@@ -646,3 +587,4 b' def launch_new_instance():'
646 587 """Create and run a full blown IPython instance"""
647 588 app = IPythonApp()
648 589 app.start()
590
@@ -25,7 +25,7 b' import warnings'
25 25 from twisted.python import log
26 26
27 27 from IPython.config.loader import PyFileConfigLoader
28 from IPython.core.application import Application
28 from IPython.core.application import Application, BaseAppConfigLoader
29 29 from IPython.core.component import Component
30 30 from IPython.utils.path import (
31 31 get_ipython_package_dir,
@@ -46,7 +46,7 b" warnings.filterwarnings('ignore', 'the sha module is deprecated',"
46 46 DeprecationWarning)
47 47
48 48 #-----------------------------------------------------------------------------
49 # Classes and functions
49 # Module errors
50 50 #-----------------------------------------------------------------------------
51 51
52 52 class ClusterDirError(Exception):
@@ -57,6 +57,10 b' class PIDFileError(Exception):'
57 57 pass
58 58
59 59
60 #-----------------------------------------------------------------------------
61 # Class for managing cluster directories
62 #-----------------------------------------------------------------------------
63
60 64 class ClusterDir(Component):
61 65 """An object to manage the cluster directory and its resources.
62 66
@@ -232,38 +236,63 b' class ClusterDir(Component):'
232 236 return ClusterDir(cluster_dir)
233 237
234 238
235 # Default command line options for IPython cluster applications.
236 cl_args = (
237 (('--ipython-dir',), dict(
238 dest='Global.ipython_dir',type=unicode,
239 help='Set to override default location of Global.ipython_dir.',
240 metavar='Global.ipython_dir') ),
241 (('-p', '--profile',), dict(
242 dest='Global.profile',type=unicode,
243 help=
244 """The string name of the profile to be used. This determines the name
245 of the cluster dir as: cluster_<profile>. The default profile is named
246 'default'. The cluster directory is resolve this way if the
247 --cluster-dir option is not used.""",
248 metavar='Global.profile') ),
249 (('--cluster-dir',), dict(
250 dest='Global.cluster_dir',type=unicode,
251 help="""Set the cluster dir. This overrides the logic used by the
252 --profile option.""",
253 metavar='Global.cluster_dir') ),
254 (('--work-dir',), dict(
255 dest='Global.work_dir',type=unicode,
256 help='Set the working dir for the process.',
257 metavar='Global.work_dir') ),
258 (('--clean-logs',), dict(
259 dest='Global.clean_logs', action='store_true',
260 help='Delete old log flies before starting.') ),
261 (('--no-clean-logs',), dict(
262 dest='Global.clean_logs', action='store_false',
263 help="Don't Delete old log flies before starting.") ),
264 )
239 #-----------------------------------------------------------------------------
240 # Command line options
241 #-----------------------------------------------------------------------------
242
243 class ClusterDirConfigLoader(BaseAppConfigLoader):
244
245 def _add_cluster_profile(self, parser):
246 paa = parser.add_argument
247 paa('-p', '--profile',
248 dest='Global.profile',type=unicode,
249 help=
250 """The string name of the profile to be used. This determines the name
251 of the cluster dir as: cluster_<profile>. The default profile is named
252 'default'. The cluster directory is resolve this way if the
253 --cluster-dir option is not used.""",
254 metavar='Global.profile')
255
256 def _add_cluster_dir(self, parser):
257 paa = parser.add_argument
258 paa('--cluster-dir',
259 dest='Global.cluster_dir',type=unicode,
260 help="""Set the cluster dir. This overrides the logic used by the
261 --profile option.""",
262 metavar='Global.cluster_dir')
263
264 def _add_work_dir(self, parser):
265 paa = parser.add_argument
266 paa('--work-dir',
267 dest='Global.work_dir',type=unicode,
268 help='Set the working dir for the process.',
269 metavar='Global.work_dir')
270
271 def _add_clean_logs(self, parser):
272 paa = parser.add_argument
273 paa('--clean-logs',
274 dest='Global.clean_logs', action='store_true',
275 help='Delete old log flies before starting.')
276
277 def _add_no_clean_logs(self, parser):
278 paa = parser.add_argument
279 paa('--no-clean-logs',
280 dest='Global.clean_logs', action='store_false',
281 help="Don't Delete old log flies before starting.")
282
283 def _add_arguments(self):
284 super(ClusterDirConfigLoader, self)._add_arguments()
285 self._add_cluster_profile(self.parser)
286 self._add_cluster_dir(self.parser)
287 self._add_work_dir(self.parser)
288 self._add_clean_logs(self.parser)
289 self._add_no_clean_logs(self.parser)
265 290
266 291
292 #-----------------------------------------------------------------------------
293 # Main application
294 #-----------------------------------------------------------------------------
295
267 296 class ApplicationWithClusterDir(Application):
268 297 """An application that puts everything into a cluster directory.
269 298
@@ -283,10 +312,9 b' class ApplicationWithClusterDir(Application):'
283 312 dir and named the value of the ``config_file_name`` class attribute.
284 313 """
285 314
315 command_line_loader = ClusterDirConfigLoader
286 316 auto_create_cluster_dir = True
287 317
288 cl_arguments = Application.cl_arguments + cl_args
289
290 318 def create_default_config(self):
291 319 super(ApplicationWithClusterDir, self).create_default_config()
292 320 self.default_config.Global.profile = u'default'
@@ -462,3 +490,4 b' class ApplicationWithClusterDir(Application):'
462 490 return pid
463 491 else:
464 492 raise PIDFileError('pid file not found: %s' % pid_file)
493
@@ -22,159 +22,162 b' import signal'
22 22 if os.name=='posix':
23 23 from twisted.scripts._twistd_unix import daemonize
24 24
25 from IPython.core import release
25 from twisted.internet import reactor, defer
26 from twisted.python import log, failure
27
28
26 29 from IPython.external.argparse import ArgumentParser, SUPPRESS
27 from IPython.config.loader import ArgParseConfigLoader
28 30 from IPython.utils.importstring import import_item
29
30 31 from IPython.kernel.clusterdir import (
31 ApplicationWithClusterDir, ClusterDirError, PIDFileError
32 ApplicationWithClusterDir, ClusterDirConfigLoader,
33 ClusterDirError, PIDFileError
32 34 )
33 35
34 from twisted.internet import reactor, defer
35 from twisted.python import log, failure
36
37 36
38 37 #-----------------------------------------------------------------------------
39 # The ipcluster application
38 # Module level variables
40 39 #-----------------------------------------------------------------------------
41 40
42 41
42 default_config_file_name = u'ipcluster_config.py'
43
44
45 _description = """\
46 Start an IPython cluster for parallel computing.\n\n
47
48 An IPython cluster consists of 1 controller and 1 or more engines.
49 This command automates the startup of these processes using a wide
50 range of startup methods (SSH, local processes, PBS, mpiexec,
51 Windows HPC Server 2008). To start a cluster with 4 engines on your
52 local host simply do "ipcluster start -n 4". For more complex usage
53 you will typically do "ipcluster create -p mycluster", then edit
54 configuration files, followed by "ipcluster start -p mycluster -n 4".
55 """
56
57
43 58 # Exit codes for ipcluster
44 59
45 60 # This will be the exit code if the ipcluster appears to be running because
46 61 # a .pid file exists
47 62 ALREADY_STARTED = 10
48 63
64
49 65 # This will be the exit code if ipcluster stop is run, but there is not .pid
50 66 # file to be found.
51 67 ALREADY_STOPPED = 11
52 68
53 69
54 class IPClusterCLLoader(ArgParseConfigLoader):
70 #-----------------------------------------------------------------------------
71 # Command line options
72 #-----------------------------------------------------------------------------
73
55 74
56 def _add_other_arguments(self):
75 class IPClusterAppConfigLoader(ClusterDirConfigLoader):
76
77 def _add_arguments(self):
78 # Don't call ClusterDirConfigLoader._add_arguments as we don't want
79 # its defaults on self.parser. Instead, we will put those on
80 # default options on our subparsers.
81
57 82 # This has all the common options that all subcommands use
58 parent_parser1 = ArgumentParser(add_help=False,
59 argument_default=SUPPRESS)
60 parent_parser1.add_argument('--ipython-dir',
61 dest='Global.ipython_dir',type=unicode,
62 help='Set to override default location of Global.ipython_dir.',
63 metavar='Global.ipython_dir')
64 parent_parser1.add_argument('--log-level',
65 dest="Global.log_level",type=int,
66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
67 metavar='Global.log_level')
83 parent_parser1 = ArgumentParser(
84 add_help=False,
85 argument_default=SUPPRESS
86 )
87 self._add_ipython_dir(parent_parser1)
88 self._add_log_level(parent_parser1)
68 89
69 90 # This has all the common options that other subcommands use
70 parent_parser2 = ArgumentParser(add_help=False,
71 argument_default=SUPPRESS)
72 parent_parser2.add_argument('-p','--profile',
73 dest='Global.profile',type=unicode,
74 help='The string name of the profile to be used. This determines '
75 'the name of the cluster dir as: cluster_<profile>. The default profile '
76 'is named "default". The cluster directory is resolve this way '
77 'if the --cluster-dir option is not used.',
78 metavar='Global.profile')
79 parent_parser2.add_argument('--cluster-dir',
80 dest='Global.cluster_dir',type=unicode,
81 help='Set the cluster dir. This overrides the logic used by the '
82 '--profile option.',
83 metavar='Global.cluster_dir'),
84 parent_parser2.add_argument('--work-dir',
85 dest='Global.work_dir',type=unicode,
86 help='Set the working dir for the process.',
87 metavar='Global.work_dir')
88 parent_parser2.add_argument('--log-to-file',
89 action='store_true', dest='Global.log_to_file',
90 help='Log to a file in the log directory (default is stdout)'
91 parent_parser2 = ArgumentParser(
92 add_help=False,
93 argument_default=SUPPRESS
91 94 )
95 self._add_cluster_profile(parent_parser2)
96 self._add_cluster_dir(parent_parser2)
97 self._add_work_dir(parent_parser2)
98 paa = parent_parser2.add_argument
99 paa('--log-to-file',
100 action='store_true', dest='Global.log_to_file',
101 help='Log to a file in the log directory (default is stdout)')
92 102
103 # Create the object used to create the subparsers.
93 104 subparsers = self.parser.add_subparsers(
94 105 dest='Global.subcommand',
95 106 title='ipcluster subcommands',
96 description='ipcluster has a variety of subcommands. '
97 'The general way of running ipcluster is "ipcluster <cmd> '
98 ' [options]""',
99 help='For more help, type "ipcluster <cmd> -h"')
107 description=
108 """ipcluster has a variety of subcommands. The general way of
109 running ipcluster is 'ipcluster <cmd> [options]'""",
110 help="For more help, type 'ipcluster <cmd> -h'"
111 )
100 112
113 # The "list" subcommand parser
101 114 parser_list = subparsers.add_parser(
102 115 'list',
103 116 help='List all clusters in cwd and ipython_dir.',
104 117 parents=[parent_parser1]
105 118 )
106 119
120 # The "create" subcommand parser
107 121 parser_create = subparsers.add_parser(
108 122 'create',
109 123 help='Create a new cluster directory.',
110 124 parents=[parent_parser1, parent_parser2]
111 125 )
112 parser_create.add_argument(
113 '--reset-config',
126 paa = parser_create.add_argument
127 paa('--reset-config',
114 128 dest='Global.reset_config', action='store_true',
115 help='Recopy the default config files to the cluster directory. '
116 'You will loose any modifications you have made to these files.'
117 )
129 help=
130 """Recopy the default config files to the cluster directory.
131 You will loose any modifications you have made to these files.""")
118 132
133 # The "start" subcommand parser
119 134 parser_start = subparsers.add_parser(
120 135 'start',
121 136 help='Start a cluster.',
122 137 parents=[parent_parser1, parent_parser2]
123 138 )
124 parser_start.add_argument(
125 '-n', '--number',
139 paa = parser_start.add_argument
140 paa('-n', '--number',
126 141 type=int, dest='Global.n',
127 142 help='The number of engines to start.',
128 metavar='Global.n'
129 )
130 parser_start.add_argument('--clean-logs',
143 metavar='Global.n')
144 paa('--clean-logs',
131 145 dest='Global.clean_logs', action='store_true',
132 help='Delete old log flies before starting.',
133 )
134 parser_start.add_argument('--no-clean-logs',
146 help='Delete old log flies before starting.')
147 paa('--no-clean-logs',
135 148 dest='Global.clean_logs', action='store_false',
136 help="Don't delete old log flies before starting.",
137 )
138 parser_start.add_argument('--daemon',
149 help="Don't delete old log flies before starting.")
150 paa('--daemon',
139 151 dest='Global.daemonize', action='store_true',
140 help='Daemonize the ipcluster program. This implies --log-to-file',
141 )
142 parser_start.add_argument('--no-daemon',
152 help='Daemonize the ipcluster program. This implies --log-to-file')
153 paa('--no-daemon',
143 154 dest='Global.daemonize', action='store_false',
144 help="Dont't daemonize the ipcluster program.",
145 )
155 help="Dont't daemonize the ipcluster program.")
146 156
147 parser_start = subparsers.add_parser(
157 # The "stop" subcommand parser
158 parser_stop = subparsers.add_parser(
148 159 'stop',
149 160 help='Stop a cluster.',
150 161 parents=[parent_parser1, parent_parser2]
151 162 )
152 parser_start.add_argument('--signal',
163 paa = parser_stop.add_argument
164 paa('--signal',
153 165 dest='Global.signal', type=int,
154 166 help="The signal number to use in stopping the cluster (default=2).",
155 metavar="Global.signal",
156 )
157
158
159 default_config_file_name = u'ipcluster_config.py'
167 metavar="Global.signal")
160 168
161 169
162 _description = """Start an IPython cluster for parallel computing.\n\n
163
164 An IPython cluster consists of 1 controller and 1 or more engines.
165 This command automates the startup of these processes using a wide
166 range of startup methods (SSH, local processes, PBS, mpiexec,
167 Windows HPC Server 2008). To start a cluster with 4 engines on your
168 local host simply do "ipcluster start -n 4". For more complex usage
169 you will typically do "ipcluster create -p mycluster", then edit
170 configuration files, followed by "ipcluster start -p mycluster -n 4".
171 """
170 #-----------------------------------------------------------------------------
171 # Main application
172 #-----------------------------------------------------------------------------
172 173
173 174
174 175 class IPClusterApp(ApplicationWithClusterDir):
175 176
176 177 name = u'ipcluster'
177 178 description = _description
179 usage = None
180 command_line_loader = IPClusterAppConfigLoader
178 181 config_file_name = default_config_file_name
179 182 default_log_level = logging.INFO
180 183 auto_create_cluster_dir = False
@@ -191,13 +194,6 b' class IPClusterApp(ApplicationWithClusterDir):'
191 194 self.default_config.Global.signal = 2
192 195 self.default_config.Global.daemonize = False
193 196
194 def create_command_line_config(self):
195 """Create and return a command line config loader."""
196 return IPClusterCLLoader(
197 description=self.description,
198 version=release.version
199 )
200
201 197 def find_resources(self):
202 198 subcommand = self.command_line_config.Global.subcommand
203 199 if subcommand=='list':
@@ -451,6 +447,7 b' class IPClusterApp(ApplicationWithClusterDir):'
451 447 # old .pid files.
452 448 self.remove_pid_file()
453 449
450
454 451 def launch_new_instance():
455 452 """Create and run the IPython cluster."""
456 453 app = IPClusterApp()
@@ -25,12 +25,34 b' from twisted.internet import reactor'
25 25 from twisted.python import log
26 26
27 27 from IPython.config.loader import Config
28 from IPython.core.application import Application
29 28 from IPython.kernel import controllerservice
30 from IPython.kernel.clusterdir import ApplicationWithClusterDir
29 from IPython.kernel.clusterdir import (
30 ApplicationWithClusterDir,
31 ClusterDirConfigLoader
32 )
31 33 from IPython.kernel.fcutil import FCServiceFactory
32 34 from IPython.utils.traitlets import Instance, Unicode
33 35
36
37 #-----------------------------------------------------------------------------
38 # Module level variables
39 #-----------------------------------------------------------------------------
40
41
42 #: The default config file name for this application
43 default_config_file_name = u'ipcontroller_config.py'
44
45
46 _description = """Start the IPython controller for parallel computing.
47
48 The IPython controller provides a gateway between the IPython engines and
49 clients. The controller needs to be started before the engines and can be
50 configured using command line options or using a cluster directory. Cluster
51 directories contain config, log and security files and are usually located in
52 your .ipython directory and named as "cluster_<profile>". See the --profile
53 and --cluster-dir options for details.
54 """
55
34 56 #-----------------------------------------------------------------------------
35 57 # Default interfaces
36 58 #-----------------------------------------------------------------------------
@@ -90,97 +112,82 b' class FCEngineServiceFactory(FCServiceFactory):'
90 112
91 113
92 114 #-----------------------------------------------------------------------------
93 # The main application
115 # Command line options
94 116 #-----------------------------------------------------------------------------
95 117
96 118
97 cl_args = (
98 # Client config
99 (('--client-ip',), dict(
100 type=str, dest='FCClientServiceFactory.ip',
101 help='The IP address or hostname the controller will listen on for '
102 'client connections.',
103 metavar='FCClientServiceFactory.ip')
104 ),
105 (('--client-port',), dict(
106 type=int, dest='FCClientServiceFactory.port',
107 help='The port the controller will listen on for client connections. '
108 'The default is to use 0, which will autoselect an open port.',
109 metavar='FCClientServiceFactory.port')
110 ),
111 (('--client-location',), dict(
112 type=str, dest='FCClientServiceFactory.location',
113 help='The hostname or IP that clients should connect to. This does '
114 'not control which interface the controller listens on. Instead, this '
115 'determines the hostname/IP that is listed in the FURL, which is how '
116 'clients know where to connect. Useful if the controller is listening '
117 'on multiple interfaces.',
118 metavar='FCClientServiceFactory.location')
119 ),
120 # Engine config
121 (('--engine-ip',), dict(
122 type=str, dest='FCEngineServiceFactory.ip',
123 help='The IP address or hostname the controller will listen on for '
124 'engine connections.',
125 metavar='FCEngineServiceFactory.ip')
126 ),
127 (('--engine-port',), dict(
128 type=int, dest='FCEngineServiceFactory.port',
129 help='The port the controller will listen on for engine connections. '
130 'The default is to use 0, which will autoselect an open port.',
131 metavar='FCEngineServiceFactory.port')
132 ),
133 (('--engine-location',), dict(
134 type=str, dest='FCEngineServiceFactory.location',
135 help='The hostname or IP that engines should connect to. This does '
136 'not control which interface the controller listens on. Instead, this '
137 'determines the hostname/IP that is listed in the FURL, which is how '
138 'engines know where to connect. Useful if the controller is listening '
139 'on multiple interfaces.',
140 metavar='FCEngineServiceFactory.location')
141 ),
142 # Global config
143 (('--log-to-file',), dict(
144 action='store_true', dest='Global.log_to_file',
145 help='Log to a file in the log directory (default is stdout)')
146 ),
147 (('-r','--reuse-furls'), dict(
148 action='store_true', dest='Global.reuse_furls',
149 help='Try to reuse all FURL files. If this is not set all FURL files '
150 'are deleted before the controller starts. This must be set if '
151 'specific ports are specified by --engine-port or --client-port.')
152 ),
153 (('--no-secure',), dict(
154 action='store_false', dest='Global.secure',
155 help='Turn off SSL encryption for all connections.')
156 ),
157 (('--secure',), dict(
158 action='store_true', dest='Global.secure',
159 help='Turn off SSL encryption for all connections.')
160 )
161 )
119 class IPControllerAppConfigLoader(ClusterDirConfigLoader):
120
121 def _add_arguments(self):
122 super(IPControllerAppConfigLoader, self)._add_arguments()
123 paa = self.parser.add_argument
124 # Client config
125 paa('--client-ip',
126 type=str, dest='FCClientServiceFactory.ip',
127 help='The IP address or hostname the controller will listen on for '
128 'client connections.',
129 metavar='FCClientServiceFactory.ip')
130 paa('--client-port',
131 type=int, dest='FCClientServiceFactory.port',
132 help='The port the controller will listen on for client connections. '
133 'The default is to use 0, which will autoselect an open port.',
134 metavar='FCClientServiceFactory.port')
135 paa('--client-location',), dict(
136 type=str, dest='FCClientServiceFactory.location',
137 help='The hostname or IP that clients should connect to. This does '
138 'not control which interface the controller listens on. Instead, this '
139 'determines the hostname/IP that is listed in the FURL, which is how '
140 'clients know where to connect. Useful if the controller is listening '
141 'on multiple interfaces.',
142 metavar='FCClientServiceFactory.location')
143 # Engine config
144 paa('--engine-ip',
145 type=str, dest='FCEngineServiceFactory.ip',
146 help='The IP address or hostname the controller will listen on for '
147 'engine connections.',
148 metavar='FCEngineServiceFactory.ip')
149 paa('--engine-port',
150 type=int, dest='FCEngineServiceFactory.port',
151 help='The port the controller will listen on for engine connections. '
152 'The default is to use 0, which will autoselect an open port.',
153 metavar='FCEngineServiceFactory.port')
154 paa('--engine-location',
155 type=str, dest='FCEngineServiceFactory.location',
156 help='The hostname or IP that engines should connect to. This does '
157 'not control which interface the controller listens on. Instead, this '
158 'determines the hostname/IP that is listed in the FURL, which is how '
159 'engines know where to connect. Useful if the controller is listening '
160 'on multiple interfaces.',
161 metavar='FCEngineServiceFactory.location')
162 # Global config
163 paa('--log-to-file',
164 action='store_true', dest='Global.log_to_file',
165 help='Log to a file in the log directory (default is stdout)')
166 paa('-r','--reuse-furls',
167 action='store_true', dest='Global.reuse_furls',
168 help='Try to reuse all FURL files. If this is not set all FURL files '
169 'are deleted before the controller starts. This must be set if '
170 'specific ports are specified by --engine-port or --client-port.')
171 paa('--no-secure',
172 action='store_false', dest='Global.secure',
173 help='Turn off SSL encryption for all connections.')
174 paa('--secure',
175 action='store_true', dest='Global.secure',
176 help='Turn off SSL encryption for all connections.')
162 177
163 178
164 _description = """Start the IPython controller for parallel computing.
165
166 The IPython controller provides a gateway between the IPython engines and
167 clients. The controller needs to be started before the engines and can be
168 configured using command line options or using a cluster directory. Cluster
169 directories contain config, log and security files and are usually located in
170 your .ipython directory and named as "cluster_<profile>". See the --profile
171 and --cluster-dir options for details.
172 """
173
174 default_config_file_name = u'ipcontroller_config.py'
179 #-----------------------------------------------------------------------------
180 # The main application
181 #-----------------------------------------------------------------------------
175 182
176 183
177 184 class IPControllerApp(ApplicationWithClusterDir):
178 185
179 186 name = u'ipcontroller'
180 187 description = _description
188 command_line_loader = IPControllerAppConfigLoader
181 189 config_file_name = default_config_file_name
182 190 auto_create_cluster_dir = True
183 cl_arguments = Application.cl_arguments + cl_args
184 191
185 192 def create_default_config(self):
186 193 super(IPControllerApp, self).create_default_config()
@@ -22,39 +22,21 b' from twisted.application import service'
22 22 from twisted.internet import reactor
23 23 from twisted.python import log
24 24
25 from IPython.core.application import Application
26 from IPython.kernel.clusterdir import ApplicationWithClusterDir
25 from IPython.kernel.clusterdir import (
26 ApplicationWithClusterDir,
27 ClusterDirConfigLoader
28 )
27 29 from IPython.kernel.engineconnector import EngineConnector
28 30 from IPython.kernel.engineservice import EngineService
29 31 from IPython.kernel.fcutil import Tub
30 32 from IPython.utils.importstring import import_item
31 33
32 34 #-----------------------------------------------------------------------------
33 # The main application
35 # Module level variables
34 36 #-----------------------------------------------------------------------------
35 37
36 cl_args = (
37 # Controller config
38 (('--furl-file',), dict(
39 type=unicode, dest='Global.furl_file',
40 help='The full location of the file containing the FURL of the '
41 'controller. If this is not given, the FURL file must be in the '
42 'security directory of the cluster directory. This location is '
43 'resolved using the --profile and --app-dir options.',
44 metavar='Global.furl_file')
45 ),
46 # MPI
47 (('--mpi',), dict(
48 type=str, dest='MPI.use',
49 help='How to enable MPI (mpi4py, pytrilinos, or empty string to disable).',
50 metavar='MPI.use')
51 ),
52 # Global config
53 (('--log-to-file',), dict(
54 action='store_true', dest='Global.log_to_file',
55 help='Log to a file in the log directory (default is stdout)')
56 )
57 )
38 #: The default config file name for this application
39 default_config_file_name = u'ipengine_config.py'
58 40
59 41
60 42 mpi4py_init = """from mpi4py import MPI as mpi
@@ -62,6 +44,7 b' mpi.size = mpi.COMM_WORLD.Get_size()'
62 44 mpi.rank = mpi.COMM_WORLD.Get_rank()
63 45 """
64 46
47
65 48 pytrilinos_init = """from PyTrilinos import Epetra
66 49 class SimpleStruct:
67 50 pass
@@ -71,9 +54,6 b' mpi.size = 0'
71 54 """
72 55
73 56
74 default_config_file_name = u'ipengine_config.py'
75
76
77 57 _description = """Start an IPython engine for parallel computing.\n\n
78 58
79 59 IPython engines run in parallel and perform computations on behalf of a client
@@ -84,14 +64,47 b' usually located in your .ipython directory and named as "cluster_<profile>".'
84 64 See the --profile and --cluster-dir options for details.
85 65 """
86 66
67 #-----------------------------------------------------------------------------
68 # Command line options
69 #-----------------------------------------------------------------------------
70
71
72 class IPEngineAppConfigLoader(ClusterDirConfigLoader):
73
74 def _add_arguments(self):
75 super(IPEngineAppConfigLoader, self)._add_arguments()
76 paa = self.parser.add_argument
77 # Controller config
78 paa('--furl-file',
79 type=unicode, dest='Global.furl_file',
80 help='The full location of the file containing the FURL of the '
81 'controller. If this is not given, the FURL file must be in the '
82 'security directory of the cluster directory. This location is '
83 'resolved using the --profile and --app-dir options.',
84 metavar='Global.furl_file')
85 # MPI
86 paa('--mpi',
87 type=str, dest='MPI.use',
88 help='How to enable MPI (mpi4py, pytrilinos, or empty string to disable).',
89 metavar='MPI.use')
90 # Global config
91 paa('--log-to-file',
92 action='store_true', dest='Global.log_to_file',
93 help='Log to a file in the log directory (default is stdout)')
94
95
96 #-----------------------------------------------------------------------------
97 # Main application
98 #-----------------------------------------------------------------------------
99
87 100
88 101 class IPEngineApp(ApplicationWithClusterDir):
89 102
90 103 name = u'ipengine'
91 104 description = _description
105 command_line_loader = IPEngineAppConfigLoader
92 106 config_file_name = default_config_file_name
93 107 auto_create_cluster_dir = True
94 cl_arguments = Application.cl_arguments + cl_args
95 108
96 109 def create_default_config(self):
97 110 super(IPEngineApp, self).create_default_config()
General Comments 0
You need to be logged in to leave comments. Login now