##// END OF EJS Templates
Minor changes to a few files to reflect design discussion.
Brian Granger -
Show More
@@ -1,198 +1,198 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """A factory for creating configuration objects.
3 """A factory for creating configuration objects.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18 import sys
18 import sys
19
19
20 from IPython.external import argparse
20 from IPython.external import argparse
21 from IPython.utils.ipstruct import Struct
21 from IPython.utils.ipstruct import Struct
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Code
24 # Code
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27
27
28 class ConfigLoaderError(Exception):
28 class ConfigLoaderError(Exception):
29 pass
29 pass
30
30
31
31
32 class ConfigLoader(object):
32 class ConfigLoader(object):
33 """A object for loading configurations from just about anywhere.
33 """A object for loading configurations from just about anywhere.
34
34
35 The resulting configuration is packaged as a :class:`Struct`.
35 The resulting configuration is packaged as a :class:`Struct`.
36
36
37 Notes
37 Notes
38 -----
38 -----
39 A :class:`ConfigLoader` does one thing: load a config from a source
39 A :class:`ConfigLoader` does one thing: load a config from a source
40 (file, command line arguments) and returns the data as a :class:`Struct`.
40 (file, command line arguments) and returns the data as a :class:`Struct`.
41 There are lots of things that :class:`ConfigLoader` does not do. It does
41 There are lots of things that :class:`ConfigLoader` does not do. It does
42 not implement complex logic for finding config files. It does not handle
42 not implement complex logic for finding config files. It does not handle
43 default values or merge multiple configs. These things need to be
43 default values or merge multiple configs. These things need to be
44 handled elsewhere.
44 handled elsewhere.
45 """
45 """
46
46
47 def __init__(self):
47 def __init__(self):
48 """A base class for config loaders.
48 """A base class for config loaders.
49
49
50 Examples
50 Examples
51 --------
51 --------
52
52
53 >>> cl = ConfigLoader()
53 >>> cl = ConfigLoader()
54 >>> config = cl.load_config()
54 >>> config = cl.load_config()
55 >>> config
55 >>> config
56 {}
56 {}
57 """
57 """
58 self.clear()
58 self.clear()
59
59
60 def clear(self):
60 def clear(self):
61 self.config = Struct()
61 self.config = Struct()
62
62
63 def load_config(self):
63 def load_config(self):
64 """Load a config from somewhere, return a Struct.
64 """Load a config from somewhere, return a Struct.
65
65
66 Usually, this will cause self.config to be set and then returned.
66 Usually, this will cause self.config to be set and then returned.
67 """
67 """
68 return self.config
68 return self.config
69
69
70
70
71 class FileConfigLoader(ConfigLoader):
71 class FileConfigLoader(ConfigLoader):
72 """A base class for file based configurations.
72 """A base class for file based configurations.
73
73
74 As we add more file based config loaders, the common logic should go
74 As we add more file based config loaders, the common logic should go
75 here.
75 here.
76 """
76 """
77 pass
77 pass
78
78
79
79
80 class PyFileConfigLoader(FileConfigLoader):
80 class PyFileConfigLoader(FileConfigLoader):
81 """A config loader for pure python files.
81 """A config loader for pure python files.
82
82
83 This calls execfile on a plain python file and looks for attributes
83 This calls execfile on a plain python file and looks for attributes
84 that are all caps. These attribute are added to the config Struct.
84 that are all caps. These attribute are added to the config Struct.
85 """
85 """
86
86
87 def __init__(self, filename, path='.'):
87 def __init__(self, filename, path='.'):
88 """Build a config loader for a filename and path.
88 """Build a config loader for a filename and path.
89
89
90 Parameters
90 Parameters
91 ----------
91 ----------
92 filename : str
92 filename : str
93 The file name of the config file.
93 The file name of the config file.
94 path : str, list, tuple
94 path : str, list, tuple
95 The path to search for the config file on, or a sequence of
95 The path to search for the config file on, or a sequence of
96 paths to try in order.
96 paths to try in order.
97 """
97 """
98 super(PyFileConfigLoader, self).__init__()
98 super(PyFileConfigLoader, self).__init__()
99 self.filename = filename
99 self.filename = filename
100 self.path = path
100 self.path = path
101 self.full_filename = ''
101 self.full_filename = ''
102 self.data = None
102 self.data = None
103
103
104 def load_config(self):
104 def load_config(self):
105 """Load the config from a file and return it as a Struct."""
105 """Load the config from a file and return it as a Struct."""
106 self._find_file()
106 self._find_file()
107 self._read_file_as_dict()
107 self._read_file_as_dict()
108 self._convert_to_struct()
108 self._convert_to_struct()
109 return self.config
109 return self.config
110
110
111 def _find_file(self):
111 def _find_file(self):
112 """Try to find the file by searching the paths."""
112 """Try to find the file by searching the paths."""
113 if os.path.isfile(os.path.expanduser(self.filename)):
113 if os.path.isfile(os.path.expanduser(self.filename)):
114 self.full_filename = os.path.expanduser(self.filename)
114 self.full_filename = os.path.expanduser(self.filename)
115 return
115 return
116 if self.path == '.':
116 if self.path == '.':
117 self.path = [os.getcwd()]
117 self.path = [os.getcwd()]
118 if not isinstance(path, (list, tuple)):
118 if not isinstance(path, (list, tuple)):
119 raise TypeError("path must be a list or tuple, got: %r" % self.path)
119 raise TypeError("path must be a list or tuple, got: %r" % self.path)
120 for p in self.path:
120 for p in self.path:
121 if p == '.': p = os.getcwd()
121 if p == '.': p = os.getcwd()
122 full_filename = os.path.expanduser(os.path.join(p, self.filename))
122 full_filename = os.path.expanduser(os.path.join(p, self.filename))
123 if os.path.isfile(full_filename):
123 if os.path.isfile(full_filename):
124 self.full_filename = full_filename
124 self.full_filename = full_filename
125 return
125 return
126 raise IOError("Config file does not exist in any "
126 raise IOError("Config file does not exist in any "
127 "of the search paths: %r, %r" % \
127 "of the search paths: %r, %r" % \
128 (self.filename, self.path))
128 (self.filename, self.path))
129
129
130 def _read_file_as_dict(self):
130 def _read_file_as_dict(self):
131 self.data = {}
131 self.data = {}
132 execfile(self.full_filename, self.data)
132 execfile(self.full_filename, self.data)
133
133
134 def _convert_to_struct(self):
134 def _convert_to_struct(self):
135 if self.data is None:
135 if self.data is None:
136 ConfigLoaderError('self.data does not exist')
136 ConfigLoaderError('self.data does not exist')
137 for k, v in self.data.iteritems():
137 for k, v in self.data.iteritems():
138 if k == k.upper():
138 if k == k.upper():
139 self.config[k] = v
139 self.config[k] = v
140
140
141
141
142 class CommandLineConfigLoader(ConfigLoader):
142 class CommandLineConfigLoader(ConfigLoader):
143 """A config loader for command line arguments.
143 """A config loader for command line arguments.
144
144
145 As we add more command line based loaders, the common logic should go
145 As we add more command line based loaders, the common logic should go
146 here.
146 here.
147 """
147 """
148
148
149
149
150 class NoDefault(object): pass
150 class NoDefault(object): pass
151 NoDefault = NoDefault()
151 NoDefault = NoDefault()
152
152
153 class ArgParseConfigLoader(CommandLineConfigLoader):
153 class ArgParseConfigLoader(CommandLineConfigLoader):
154
154
155 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
155 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
156 arguments = []
156 arguments = ()
157
157
158 def __init__(self, *args, **kw):
158 def __init__(self, *args, **kw):
159 """Create a config loader for use with argparse.
159 """Create a config loader for use with argparse.
160
160
161 The args and kwargs arguments here are passed onto the constructor
161 The args and kwargs arguments here are passed onto the constructor
162 of :class:`argparse.ArgumentParser`.
162 of :class:`argparse.ArgumentParser`.
163 """
163 """
164 super(CommandLineConfigLoader, self).__init__()
164 super(CommandLineConfigLoader, self).__init__()
165 self.args = args
165 self.args = args
166 self.kw = kw
166 self.kw = kw
167
167
168 def load_config(self, args=None):
168 def load_config(self, args=None):
169 """Parse command line arguments and return as a Struct."""
169 """Parse command line arguments and return as a Struct."""
170 self._create_parser()
170 self._create_parser()
171 self._parse_args(args)
171 self._parse_args(args)
172 self._convert_to_struct()
172 self._convert_to_struct()
173 return self.config
173 return self.config
174
174
175 def _create_parser(self):
175 def _create_parser(self):
176 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
176 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
177 self._add_arguments()
177 self._add_arguments()
178
178
179 def _add_arguments(self):
179 def _add_arguments(self):
180 for argument in self.arguments:
180 for argument in self.arguments:
181 if not argument[1].has_key('default'):
181 if not argument[1].has_key('default'):
182 argument[1]['default'] = NoDefault
182 argument[1]['default'] = NoDefault
183 self.parser.add_argument(*argument[0],**argument[1])
183 self.parser.add_argument(*argument[0],**argument[1])
184
184
185 def _parse_args(self, args=None):
185 def _parse_args(self, args=None):
186 """self.parser->self.parsed_data"""
186 """self.parser->self.parsed_data"""
187 if args is None:
187 if args is None:
188 self.parsed_data = self.parser.parse_args()
188 self.parsed_data = self.parser.parse_args()
189 else:
189 else:
190 self.parsed_data = self.parser.parse_args(args)
190 self.parsed_data = self.parser.parse_args(args)
191
191
192 def _convert_to_struct(self):
192 def _convert_to_struct(self):
193 """self.parsed_data->self.config"""
193 """self.parsed_data->self.config"""
194 self.config = Struct()
194 self.config = Struct()
195 for k, v in vars(self.parsed_data).items():
195 for k, v in vars(self.parsed_data).items():
196 if v is not NoDefault:
196 if v is not NoDefault:
197 setattr(self.config, k, v)
197 setattr(self.config, k, v)
198
198
@@ -1,92 +1,93 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.config.loader
4 Tests for IPython.config.loader
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.config.loader import PyFileConfigLoader, ArgParseConfigLoader
27 from IPython.config.loader import PyFileConfigLoader, ArgParseConfigLoader
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Actual tests
30 # Actual tests
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33
33
34 pyfile = """
34 pyfile = """
35 A = 10
35 A = 10
36 B = range(10)
36 B = range(10)
37 C = True
37 C = True
38 D = 'hi there'
38 D = 'hi there'
39 """
39 """
40
40
41 class TestPyFileCL(TestCase):
41 class TestPyFileCL(TestCase):
42
42
43 def test_basic(self):
43 def test_basic(self):
44 fd, fname = mkstemp()
44 fd, fname = mkstemp()
45 f = os.fdopen(fd, 'w')
45 f = os.fdopen(fd, 'w')
46 f.write(pyfile)
46 f.write(pyfile)
47 f.close()
47 f.close()
48 # Unlink the file
48 cl = PyFileConfigLoader(fname)
49 cl = PyFileConfigLoader(fname)
49 config = cl.load_config()
50 config = cl.load_config()
50 self.assertEquals(config.A, 10)
51 self.assertEquals(config.A, 10)
51 self.assertEquals(config.B, range(10))
52 self.assertEquals(config.B, range(10))
52 self.assertEquals(config.C, True)
53 self.assertEquals(config.C, True)
53 self.assertEquals(config.D, 'hi there')
54 self.assertEquals(config.D, 'hi there')
54
55
55
56
56 class TestArgParseCL(TestCase):
57 class TestArgParseCL(TestCase):
57
58
58 def test_basic(self):
59 def test_basic(self):
59
60
60 class MyLoader(ArgParseConfigLoader):
61 class MyLoader(ArgParseConfigLoader):
61 arguments = [
62 arguments = (
62 (('-f','--foo'), dict(dest='FOO', type=str)),
63 (('-f','--foo'), dict(dest='FOO', type=str)),
63 (('-b',), dict(dest='BAR', type=int)),
64 (('-b',), dict(dest='BAR', type=int)),
64 (('-n',), dict(dest='N', action='store_true')),
65 (('-n',), dict(dest='N', action='store_true')),
65 (('BAM',), dict(type=str))
66 (('BAM',), dict(type=str))
66 ]
67 )
67
68
68 cl = MyLoader()
69 cl = MyLoader()
69 config = cl.load_config('-f hi -b 10 -n wow'.split())
70 config = cl.load_config('-f hi -b 10 -n wow'.split())
70 self.assertEquals(config.FOO, 'hi')
71 self.assertEquals(config.FOO, 'hi')
71 self.assertEquals(config.BAR, 10)
72 self.assertEquals(config.BAR, 10)
72 self.assertEquals(config.N, True)
73 self.assertEquals(config.N, True)
73 self.assertEquals(config.BAM, 'wow')
74 self.assertEquals(config.BAM, 'wow')
74
75
75 def test_add_arguments(self):
76 def test_add_arguments(self):
76
77
77 class MyLoader(ArgParseConfigLoader):
78 class MyLoader(ArgParseConfigLoader):
78 def _add_arguments(self):
79 def _add_arguments(self):
79 subparsers = self.parser.add_subparsers(dest='subparser_name')
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
80 subparser1 = subparsers.add_parser('1')
81 subparser1 = subparsers.add_parser('1')
81 subparser1.add_argument('-x')
82 subparser1.add_argument('-x')
82 subparser2 = subparsers.add_parser('2')
83 subparser2 = subparsers.add_parser('2')
83 subparser2.add_argument('y')
84 subparser2.add_argument('y')
84
85
85 cl = MyLoader()
86 cl = MyLoader()
86 config = cl.load_config('2 frobble'.split())
87 config = cl.load_config('2 frobble'.split())
87 self.assertEquals(config.subparser_name, '2')
88 self.assertEquals(config.subparser_name, '2')
88 self.assertEquals(config.y, 'frobble')
89 self.assertEquals(config.y, 'frobble')
89 config = cl.load_config('1 -x frobble'.split())
90 config = cl.load_config('1 -x frobble'.split())
90 self.assertEquals(config.subparser_name, '1')
91 self.assertEquals(config.subparser_name, '1')
91 self.assertEquals(config.x, 'frobble')
92 self.assertEquals(config.x, 'frobble')
92
93
@@ -1,159 +1,161 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 An application for IPython
4 An application for IPython
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10
10
11 Notes
11 Notes
12 -----
12 -----
13
13
14 The following directories are relevant in the startup of an app:
14 The following directories are relevant in the startup of an app:
15
15
16 * The ipythondir. This has a default, but can be set by IPYTHONDIR or at
16 * The ipythondir. This has a default, but can be set by IPYTHONDIR or at
17 the command line.
17 the command line.
18 * The current working directory.
18 * The current working directory.
19 * Another runtime directory. With some applications (engine, controller) we
19 * Another runtime directory. With some applications (engine, controller) we
20 need the ability to have different cluster configs. Each of these needs
20 need the ability to have different cluster configs. Each of these needs
21 to have its own config, security dir and log dir. We could simply treat
21 to have its own config, security dir and log dir. We could simply treat
22 these as regular ipython dirs.
22 these as regular ipython dirs.
23
23
24 There are number of ways in which these directories are used:
24 There are number of ways in which these directories are used:
25
25
26 * For config files.
26 * For config files.
27 * For other assets and resources needed to run. These include
27 * For other assets and resources needed to run. These include
28 plugins, magics, furls files.
28 plugins, magics, furls files.
29 * For writing various things created at runtime like logs, furl files, etc.
29 * For writing various things created at runtime like logs, furl files, etc.
30
30
31 Questions:
31 Questions:
32
32
33
33
34 * Can we limit ourselves to 1 config file or do we want to have a sequence
34 * Can we limit ourselves to 1 config file or do we want to have a sequence
35 of them like IPYTHONDIR->RUNTIMEDIR->CWD?
35 of them like IPYTHONDIR->RUNTIMEDIR->CWD? [1]
36 * Do we need a debug mode that has custom exception handling and can drop
36 * Do we need a debug mode that has custom exception handling and can drop
37 into pdb upno startup?
37 into pdb upno startup? N
38 * Do we need to use an OutputTrap to capture output and then present it
38 * Do we need to use an OutputTrap to capture output and then present it
39 to a user if startup fails?
39 to a user if startup fails? N
40 * Do we want the location of the config file(s) to be independent of the
40 * Do we want the location of the config file(s) to be independent of the
41 ipython/runtime dir or coupled to it. In other words, can the user select
41 ipython/runtime dir or coupled to it. In other words, can the user select
42 a config file that is outside their runtime/ipython dir. One model is
42 a config file that is outside their runtime/ipython dir. One model is
43 that we could have a very strict model of IPYTHONDIR=runtimed dir=
43 that we could have a very strict model of IPYTHONDIR=runtimed dir=
44 dir used for all config.
44 dir used for all config.
45 * Do we install default config files or not?
45 * Do we install default config files or not? N
46
47 * attempt needs to either clash or to die
46 """
48 """
47
49
48 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
49 # Copyright (C) 2008-2009 The IPython Development Team
51 # Copyright (C) 2008-2009 The IPython Development Team
50 #
52 #
51 # Distributed under the terms of the BSD License. The full license is in
53 # Distributed under the terms of the BSD License. The full license is in
52 # the file COPYING, distributed as part of this software.
54 # the file COPYING, distributed as part of this software.
53 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
54
56
55 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
56 # Imports
58 # Imports
57 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
58
60
59 import sys
61 import sys
60 from copy import deepcopy
62 from copy import deepcopy
61 from IPython.utils.ipstruct import Struct
63 from IPython.utils.ipstruct import Struct
62
64
63 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
64 # Classes and functions
66 # Classes and functions
65 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
66
68
67
69
68 class ApplicationError(Exception):
70 class ApplicationError(Exception):
69 pass
71 pass
70
72
71
73
72 class Application(object):
74 class Application(object):
73
75
74 runtime_dirs = []
76 runtime_dirs = []
75 default_config = Struct()
77 default_config = Struct()
76 runtime_dir = ''
78 runtime_dir = ''
77 config_file = ''
79 config_file = ''
78 name = ''
80 name = ''
79
81
80 def __init__(self):
82 def __init__(self):
81 pass
83 pass
82
84
83 def start(self):
85 def start(self):
84 """Start the application."""
86 """Start the application."""
85 self.attempt(self.create_command_line_config)
87 self.attempt(self.create_command_line_config)
86 self.attempt(self.find_runtime_dirs)
88 self.attempt(self.find_runtime_dirs)
87 self.attempt(self.create_runtime_dirs)
89 self.attempt(self.create_runtime_dirs)
88 self.attempt(self.find_config_files)
90 self.attempt(self.find_config_files)
89 self.attempt(self.create_file_configs)
91 self.attempt(self.create_file_configs)
90 self.attempt(self.merge_configs)
92 self.attempt(self.merge_configs)
91 self.attempt(self.construct)
93 self.attempt(self.construct)
92 self.attempt(self.start_logging)
94 self.attempt(self.start_logging)
93 self.attempt(self.start_app)
95 self.attempt(self.start_app)
94
96
95 #-------------------------------------------------------------------------
97 #-------------------------------------------------------------------------
96 # Various stages of Application creation
98 # Various stages of Application creation
97 #-------------------------------------------------------------------------
99 #-------------------------------------------------------------------------
98
100
99 def create_command_line_config(self):
101 def create_command_line_config(self):
100 """Read the command line args and return its config object."""
102 """Read the command line args and return its config object."""
101 self.command_line_config = Struct()
103 self.command_line_config = Struct()
102
104
103 def find_runtime_dirs(self):
105 def find_runtime_dirs(self):
104 """Find the runtime directory for this application.
106 """Find the runtime directory for this application.
105
107
106 This should set self.runtime_dir.
108 This should set self.runtime_dir.
107 """
109 """
108 pass
110 pass
109
111
110 def create_runtime_dirs(self):
112 def create_runtime_dirs(self):
111 """Create the runtime dirs if they don't exist."""
113 """Create the runtime dirs if they don't exist."""
112 pass
114 pass
113
115
114 def find_config_files(self):
116 def find_config_files(self):
115 """Find the config file for this application."""
117 """Find the config file for this application."""
116 pass
118 pass
117
119
118 def create_file_configs(self):
120 def create_file_configs(self):
119 self.file_configs = [Struct()]
121 self.file_configs = [Struct()]
120
122
121 def merge_configs(self):
123 def merge_configs(self):
122 config = Struct()
124 config = Struct()
123 all_configs = self.file_configs + self.command_line_config
125 all_configs = self.file_configs + self.command_line_config
124 for c in all_configs:
126 for c in all_configs:
125 config.update(c)
127 config.update(c)
126 self.master_config = config
128 self.master_config = config
127
129
128 def construct(self, config):
130 def construct(self, config):
129 """Construct the main components that make up this app."""
131 """Construct the main components that make up this app."""
130 pass
132 pass
131
133
132 def start_logging(self):
134 def start_logging(self):
133 """Start logging, if needed, at the last possible moment."""
135 """Start logging, if needed, at the last possible moment."""
134 pass
136 pass
135
137
136 def start_app(self):
138 def start_app(self):
137 """Actually start the app."""
139 """Actually start the app."""
138 pass
140 pass
139
141
140 #-------------------------------------------------------------------------
142 #-------------------------------------------------------------------------
141 # Utility methods
143 # Utility methods
142 #-------------------------------------------------------------------------
144 #-------------------------------------------------------------------------
143
145
144 def abort(self):
146 def abort(self):
145 """Abort the starting of the application."""
147 """Abort the starting of the application."""
146 print "Aborting application: ", self.name
148 print "Aborting application: ", self.name
147 sys.exit(1)
149 sys.exit(1)
148
150
149 def attempt(self, func):
151 def attempt(self, func):
150 try:
152 try:
151 func()
153 func()
152 except:
154 except:
153 self.handle_error()
155 self.handle_error()
154 self.abort()
156 self.abort()
155
157
156 def handle_error(self):
158 def handle_error(self):
157 print "I am dying!"
159 print "I am dying!"
158
160
159 No newline at end of file
161
General Comments 0
You need to be logged in to leave comments. Login now