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