##// END OF EJS Templates
Changed how config files are loaded....
Brian Granger -
Show More
@@ -1,146 +1,148 b''
1 # Get the config being loaded so we can set attributes on it
2 c = get_config()
3
1 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
2 # Global options
5 # Global options
3 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
4
7
5 # Global.display_banner = True
8 # c.Global.display_banner = True
6
9
7 # Global.classic = False
10 # c.Global.classic = False
8
11
9 # Global.nosep = True
12 # c.Global.nosep = True
10
13
11 # Set this to determine the detail of what is logged at startup.
14 # Set this to determine the detail of what is logged at startup.
12 # The default is 30 and possible values are 0,10,20,30,40,50.
15 # The default is 30 and possible values are 0,10,20,30,40,50.
13 # Global.log_level = 30
16 c.Global.log_level = 20
14
17
15 # This should be a list of importable Python modules that have an
18 # This should be a list of importable Python modules that have an
16 # load_in_ipython(ip) method. This method gets called when the extension
19 # load_in_ipython(ip) method. This method gets called when the extension
17 # is loaded. You can put your extensions anywhere they can be imported
20 # is loaded. You can put your extensions anywhere they can be imported
18 # but we add the extensions subdir of the ipython directory to sys.path
21 # but we add the extensions subdir of the ipython directory to sys.path
19 # during extension loading, so you can put them there as well.
22 # during extension loading, so you can put them there as well.
20 # Global.extensions = [
23 # c.Global.extensions = [
21 # 'myextension'
24 # 'myextension'
22 # ]
25 # ]
23
26
24 # These lines are run in IPython in the user's namespace after extensions
27 # These lines are run in IPython in the user's namespace after extensions
25 # are loaded. They can contain full IPython syntax with magics etc.
28 # are loaded. They can contain full IPython syntax with magics etc.
26 # Global.exec_lines = [
29 # c.Global.exec_lines = [
27 # 'import numpy',
30 # 'import numpy',
28 # 'a = 10; b = 20',
31 # 'a = 10; b = 20',
29 # '1/0'
32 # '1/0'
30 # ]
33 # ]
31
34
32 # These files are run in IPython in the user's namespace. Files with a .py
35 # These files are run in IPython in the user's namespace. Files with a .py
33 # extension need to be pure Python. Files with a .ipy extension can have
36 # extension need to be pure Python. Files with a .ipy extension can have
34 # custom IPython syntax (like magics, etc.).
37 # custom IPython syntax (like magics, etc.).
35 # These files need to be in the cwd, the ipythondir or be absolute paths.
38 # These files need to be in the cwd, the ipythondir or be absolute paths.
36 # Global.exec_files = [
39 # c.Global.exec_files = [
37 # 'mycode.py',
40 # 'mycode.py',
38 # 'fancy.ipy'
41 # 'fancy.ipy'
39 # ]
42 # ]
40
43
41 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
42 # InteractiveShell options
45 # InteractiveShell options
43 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
44
47
48 # c.InteractiveShell.autocall = 1
45
49
46 # InteractiveShell.autocall = 1
50 # c.InteractiveShell.autoedit_syntax = False
47
48 # InteractiveShell.autoedit_syntax = False
49
51
50 # InteractiveShell.autoindent = True
52 # c.InteractiveShell.autoindent = True
51
53
52 # InteractiveShell.automagic = False
54 # c.InteractiveShell.automagic = False
53
55
54 # InteractiveShell.banner1 = 'This if for overriding the default IPython banner'
56 # c.InteractiveShell.banner1 = 'This if for overriding the default IPython banner'
55
57
56 # InteractiveShell.banner2 = "This is for extra banner text"
58 # c.InteractiveShell.banner2 = "This is for extra banner text"
57
59
58 # InteractiveShell.cache_size = 1000
60 # c.InteractiveShell.cache_size = 1000
59
61
60 # InteractiveShell.colors = 'LightBG'
62 # c.InteractiveShell.colors = 'LightBG'
61
63
62 # InteractiveShell.color_info = True
64 # c.InteractiveShell.color_info = True
63
65
64 # InteractiveShell.confirm_exit = True
66 # c.InteractiveShell.confirm_exit = True
65
67
66 # InteractiveShell.deep_reload = False
68 # c.InteractiveShell.deep_reload = False
67
69
68 # InteractiveShell.editor = 'nano'
70 # c.InteractiveShell.editor = 'nano'
69
71
70 # InteractiveShell.logstart = True
72 # c.InteractiveShell.logstart = True
71
73
72 # InteractiveShell.logfile = 'ipython_log.py'
74 # c.InteractiveShell.logfile = 'ipython_log.py'
73
75
74 # InteractiveShell.logplay = 'mylog.py'
76 # c.InteractiveShell.logplay = 'mylog.py'
75
77
76 # InteractiveShell.object_info_string_level = 0
78 # c.InteractiveShell.object_info_string_level = 0
77
79
78 # InteractiveShell.pager = 'less'
80 # c.InteractiveShell.pager = 'less'
79
81
80 # InteractiveShell.pdb = False
82 # c.InteractiveShell.pdb = False
81
83
82 # InteractiveShell.pprint = True
84 # c.InteractiveShell.pprint = True
83
85
84 # InteractiveShell.prompt_in1 = 'In [\#]: '
86 # c.InteractiveShell.prompt_in1 = 'In [\#]: '
85 # InteractiveShell.prompt_in2 = ' .\D.: '
87 # c.InteractiveShell.prompt_in2 = ' .\D.: '
86 # InteractiveShell.prompt_out = 'Out[\#]: '
88 # c.InteractiveShell.prompt_out = 'Out[\#]: '
87 # InteractiveShell.prompts_pad_left = True
89 # c.InteractiveShell.prompts_pad_left = True
88
90
89 # InteractiveShell.quiet = False
91 # c.InteractiveShell.quiet = False
90
92
91 # Readline
93 # Readline
92 # InteractiveShell.readline_use = True
94 # c.InteractiveShell.readline_use = True
93
95
94 # InteractiveShell.readline_parse_and_bind = [
96 # c.InteractiveShell.readline_parse_and_bind = [
95 # 'tab: complete',
97 # 'tab: complete',
96 # '"\C-l": possible-completions',
98 # '"\C-l": possible-completions',
97 # 'set show-all-if-ambiguous on',
99 # 'set show-all-if-ambiguous on',
98 # '"\C-o": tab-insert',
100 # '"\C-o": tab-insert',
99 # '"\M-i": " "',
101 # '"\M-i": " "',
100 # '"\M-o": "\d\d\d\d"',
102 # '"\M-o": "\d\d\d\d"',
101 # '"\M-I": "\d\d\d\d"',
103 # '"\M-I": "\d\d\d\d"',
102 # '"\C-r": reverse-search-history',
104 # '"\C-r": reverse-search-history',
103 # '"\C-s": forward-search-history',
105 # '"\C-s": forward-search-history',
104 # '"\C-p": history-search-backward',
106 # '"\C-p": history-search-backward',
105 # '"\C-n": history-search-forward',
107 # '"\C-n": history-search-forward',
106 # '"\e[A": history-search-backward',
108 # '"\e[A": history-search-backward',
107 # '"\e[B": history-search-forward',
109 # '"\e[B": history-search-forward',
108 # '"\C-k": kill-line',
110 # '"\C-k": kill-line',
109 # '"\C-u": unix-line-discard',
111 # '"\C-u": unix-line-discard',
110 # ]
112 # ]
111 # InteractiveShell.readline_remove_delims = '-/~'
113 # c.InteractiveShell.readline_remove_delims = '-/~'
112 # InteractiveShell.readline_merge_completions = True
114 # c.InteractiveShell.readline_merge_completions = True
113 # InteractiveShell.readline_omit_names = 0
115 # c.InteractiveShell.readline_omit_names = 0
114
116
115 # InteractiveShell.screen_length = 0
117 # c.InteractiveShell.screen_length = 0
116
118
117 # InteractiveShell.separate_in = '\n'
119 # c.InteractiveShell.separate_in = '\n'
118 # InteractiveShell.separate_out = ''
120 # c.InteractiveShell.separate_out = ''
119 # InteractiveShell.separate_out2 = ''
121 # c.InteractiveShell.separate_out2 = ''
120
122
121 # InteractiveShell.system_header = "IPython system call: "
123 # c.InteractiveShell.system_header = "IPython system call: "
122
124
123 # InteractiveShell.system_verbose = True
125 # c.InteractiveShell.system_verbose = True
124
126
125 # InteractiveShell.term_title = False
127 # c.InteractiveShell.term_title = False
126
128
127 # InteractiveShell.wildcards_case_sensitive = True
129 # c.InteractiveShell.wildcards_case_sensitive = True
128
130
129 # InteractiveShell.xmode = 'Context'
131 # c.InteractiveShell.xmode = 'Context'
130
132
131 #-----------------------------------------------------------------------------
133 #-----------------------------------------------------------------------------
132 # PrefilterManager options
134 # PrefilterManager options
133 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
134
136
135 # PrefilterManager.multi_line_specials = True
137 # c.PrefilterManager.multi_line_specials = True
136
138
137 #-----------------------------------------------------------------------------
139 #-----------------------------------------------------------------------------
138 # AliasManager options
140 # AliasManager options
139 #-----------------------------------------------------------------------------
141 #-----------------------------------------------------------------------------
140
142
141 # Do this to enable all defaults
143 # Do this to enable all defaults
142 # AliasManager.default_aliases = []
144 # c.AliasManager.default_aliases = []
143
145
144 # AliasManager.user_aliases = [
146 # c.AliasManager.user_aliases = [
145 # ('foo', 'echo Hi')
147 # ('foo', 'echo Hi')
146 # ] No newline at end of file
148 # ]
@@ -1,328 +1,329 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """A simple configuration system.
3 """A simple configuration system.
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 import __builtin__
21 import __builtin__
22 import os
22 import os
23 import sys
23 import sys
24
24
25 from IPython.external import argparse
25 from IPython.external import argparse
26 from IPython.utils.genutils import filefind
26 from IPython.utils.genutils import filefind
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Exceptions
29 # Exceptions
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32
32
33 class ConfigError(Exception):
33 class ConfigError(Exception):
34 pass
34 pass
35
35
36
36
37 class ConfigLoaderError(ConfigError):
37 class ConfigLoaderError(ConfigError):
38 pass
38 pass
39
39
40
40
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 # Config class for holding config information
42 # Config class for holding config information
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44
44
45
45
46 class Config(dict):
46 class Config(dict):
47 """An attribute based dict that can do smart merges."""
47 """An attribute based dict that can do smart merges."""
48
48
49 def __init__(self, *args, **kwds):
49 def __init__(self, *args, **kwds):
50 dict.__init__(self, *args, **kwds)
50 dict.__init__(self, *args, **kwds)
51 # This sets self.__dict__ = self, but it has to be done this way
51 # This sets self.__dict__ = self, but it has to be done this way
52 # because we are also overriding __setattr__.
52 # because we are also overriding __setattr__.
53 dict.__setattr__(self, '__dict__', self)
53 dict.__setattr__(self, '__dict__', self)
54
54
55 def _merge(self, other):
55 def _merge(self, other):
56 to_update = {}
56 to_update = {}
57 for k, v in other.items():
57 for k, v in other.items():
58 if not self.has_key(k):
58 if not self.has_key(k):
59 to_update[k] = v
59 to_update[k] = v
60 else: # I have this key
60 else: # I have this key
61 if isinstance(v, Config):
61 if isinstance(v, Config):
62 # Recursively merge common sub Configs
62 # Recursively merge common sub Configs
63 self[k]._merge(v)
63 self[k]._merge(v)
64 else:
64 else:
65 # Plain updates for non-Configs
65 # Plain updates for non-Configs
66 to_update[k] = v
66 to_update[k] = v
67
67
68 self.update(to_update)
68 self.update(to_update)
69
69
70 def _is_section_key(self, key):
70 def _is_section_key(self, key):
71 if key[0].upper()==key[0] and not key.startswith('_'):
71 if key[0].upper()==key[0] and not key.startswith('_'):
72 return True
72 return True
73 else:
73 else:
74 return False
74 return False
75
75
76 def has_key(self, key):
76 def has_key(self, key):
77 if self._is_section_key(key):
77 if self._is_section_key(key):
78 return True
78 return True
79 else:
79 else:
80 return dict.has_key(self, key)
80 return dict.has_key(self, key)
81
81
82 def _has_section(self, key):
82 def _has_section(self, key):
83 if self._is_section_key(key):
83 if self._is_section_key(key):
84 if dict.has_key(self, key):
84 if dict.has_key(self, key):
85 return True
85 return True
86 return False
86 return False
87
87
88 def copy(self):
88 def copy(self):
89 return type(self)(dict.copy(self))
89 return type(self)(dict.copy(self))
90
90
91 def __copy__(self):
91 def __copy__(self):
92 return self.copy()
92 return self.copy()
93
93
94 def __deepcopy__(self, memo):
94 def __deepcopy__(self, memo):
95 import copy
95 import copy
96 return type(self)(copy.deepcopy(self.items()))
96 return type(self)(copy.deepcopy(self.items()))
97
97
98 def __getitem__(self, key):
98 def __getitem__(self, key):
99 # Because we use this for an exec namespace, we need to delegate
99 # Because we use this for an exec namespace, we need to delegate
100 # the lookup of names in __builtin__ to itself. This means
100 # the lookup of names in __builtin__ to itself. This means
101 # that you can't have section or attribute names that are
101 # that you can't have section or attribute names that are
102 # builtins.
102 # builtins.
103 try:
103 try:
104 return getattr(__builtin__, key)
104 return getattr(__builtin__, key)
105 except AttributeError:
105 except AttributeError:
106 pass
106 pass
107 if self._is_section_key(key):
107 if self._is_section_key(key):
108 try:
108 try:
109 return dict.__getitem__(self, key)
109 return dict.__getitem__(self, key)
110 except KeyError:
110 except KeyError:
111 c = Config()
111 c = Config()
112 dict.__setitem__(self, key, c)
112 dict.__setitem__(self, key, c)
113 return c
113 return c
114 else:
114 else:
115 return dict.__getitem__(self, key)
115 return dict.__getitem__(self, key)
116
116
117 def __setitem__(self, key, value):
117 def __setitem__(self, key, value):
118 # Don't allow names in __builtin__ to be modified.
118 # Don't allow names in __builtin__ to be modified.
119 if hasattr(__builtin__, key):
119 if hasattr(__builtin__, key):
120 raise ConfigError('Config variable names cannot have the same name '
120 raise ConfigError('Config variable names cannot have the same name '
121 'as a Python builtin: %s' % key)
121 'as a Python builtin: %s' % key)
122 if self._is_section_key(key):
122 if self._is_section_key(key):
123 if not isinstance(value, Config):
123 if not isinstance(value, Config):
124 raise ValueError('values whose keys begin with an uppercase '
124 raise ValueError('values whose keys begin with an uppercase '
125 'char must be Config instances: %r, %r' % (key, value))
125 'char must be Config instances: %r, %r' % (key, value))
126 else:
126 else:
127 dict.__setitem__(self, key, value)
127 dict.__setitem__(self, key, value)
128
128
129 def __getattr__(self, key):
129 def __getattr__(self, key):
130 try:
130 try:
131 return self.__getitem__(key)
131 return self.__getitem__(key)
132 except KeyError, e:
132 except KeyError, e:
133 raise AttributeError(e)
133 raise AttributeError(e)
134
134
135 def __setattr__(self, key, value):
135 def __setattr__(self, key, value):
136 try:
136 try:
137 self.__setitem__(key, value)
137 self.__setitem__(key, value)
138 except KeyError, e:
138 except KeyError, e:
139 raise AttributeError(e)
139 raise AttributeError(e)
140
140
141 def __delattr__(self, key):
141 def __delattr__(self, key):
142 try:
142 try:
143 dict.__delitem__(self, key)
143 dict.__delitem__(self, key)
144 except KeyError, e:
144 except KeyError, e:
145 raise AttributeError(e)
145 raise AttributeError(e)
146
146
147
147
148 #-----------------------------------------------------------------------------
148 #-----------------------------------------------------------------------------
149 # Config loading classes
149 # Config loading classes
150 #-----------------------------------------------------------------------------
150 #-----------------------------------------------------------------------------
151
151
152
152
153 class ConfigLoader(object):
153 class ConfigLoader(object):
154 """A object for loading configurations from just about anywhere.
154 """A object for loading configurations from just about anywhere.
155
155
156 The resulting configuration is packaged as a :class:`Struct`.
156 The resulting configuration is packaged as a :class:`Struct`.
157
157
158 Notes
158 Notes
159 -----
159 -----
160 A :class:`ConfigLoader` does one thing: load a config from a source
160 A :class:`ConfigLoader` does one thing: load a config from a source
161 (file, command line arguments) and returns the data as a :class:`Struct`.
161 (file, command line arguments) and returns the data as a :class:`Struct`.
162 There are lots of things that :class:`ConfigLoader` does not do. It does
162 There are lots of things that :class:`ConfigLoader` does not do. It does
163 not implement complex logic for finding config files. It does not handle
163 not implement complex logic for finding config files. It does not handle
164 default values or merge multiple configs. These things need to be
164 default values or merge multiple configs. These things need to be
165 handled elsewhere.
165 handled elsewhere.
166 """
166 """
167
167
168 def __init__(self):
168 def __init__(self):
169 """A base class for config loaders.
169 """A base class for config loaders.
170
170
171 Examples
171 Examples
172 --------
172 --------
173
173
174 >>> cl = ConfigLoader()
174 >>> cl = ConfigLoader()
175 >>> config = cl.load_config()
175 >>> config = cl.load_config()
176 >>> config
176 >>> config
177 {}
177 {}
178 """
178 """
179 self.clear()
179 self.clear()
180
180
181 def clear(self):
181 def clear(self):
182 self.config = Config()
182 self.config = Config()
183
183
184 def load_config(self):
184 def load_config(self):
185 """Load a config from somewhere, return a Struct.
185 """Load a config from somewhere, return a Struct.
186
186
187 Usually, this will cause self.config to be set and then returned.
187 Usually, this will cause self.config to be set and then returned.
188 """
188 """
189 return self.config
189 return self.config
190
190
191
191
192 class FileConfigLoader(ConfigLoader):
192 class FileConfigLoader(ConfigLoader):
193 """A base class for file based configurations.
193 """A base class for file based configurations.
194
194
195 As we add more file based config loaders, the common logic should go
195 As we add more file based config loaders, the common logic should go
196 here.
196 here.
197 """
197 """
198 pass
198 pass
199
199
200
200
201 class PyFileConfigLoader(FileConfigLoader):
201 class PyFileConfigLoader(FileConfigLoader):
202 """A config loader for pure python files.
202 """A config loader for pure python files.
203
203
204 This calls execfile on a plain python file and looks for attributes
204 This calls execfile on a plain python file and looks for attributes
205 that are all caps. These attribute are added to the config Struct.
205 that are all caps. These attribute are added to the config Struct.
206 """
206 """
207
207
208 def __init__(self, filename, path=None):
208 def __init__(self, filename, path=None):
209 """Build a config loader for a filename and path.
209 """Build a config loader for a filename and path.
210
210
211 Parameters
211 Parameters
212 ----------
212 ----------
213 filename : str
213 filename : str
214 The file name of the config file.
214 The file name of the config file.
215 path : str, list, tuple
215 path : str, list, tuple
216 The path to search for the config file on, or a sequence of
216 The path to search for the config file on, or a sequence of
217 paths to try in order.
217 paths to try in order.
218 """
218 """
219 super(PyFileConfigLoader, self).__init__()
219 super(PyFileConfigLoader, self).__init__()
220 self.filename = filename
220 self.filename = filename
221 self.path = path
221 self.path = path
222 self.full_filename = ''
222 self.full_filename = ''
223 self.data = None
223 self.data = None
224
224
225 def load_config(self):
225 def load_config(self):
226 """Load the config from a file and return it as a Struct."""
226 """Load the config from a file and return it as a Struct."""
227 self._find_file()
227 self._find_file()
228 self._read_file_as_dict()
228 self._read_file_as_dict()
229 self._convert_to_config()
229 self._convert_to_config()
230 return self.config
230 return self.config
231
231
232 def _find_file(self):
232 def _find_file(self):
233 """Try to find the file by searching the paths."""
233 """Try to find the file by searching the paths."""
234 self.full_filename = filefind(self.filename, self.path)
234 self.full_filename = filefind(self.filename, self.path)
235
235
236 def _read_file_as_dict(self):
236 def _read_file_as_dict(self):
237 """Load the config file into self.config, with recursive loading."""
237 """Load the config file into self.config, with recursive loading."""
238 # This closure is made available in the namespace that is used
238 # This closure is made available in the namespace that is used
239 # to exec the config file. This allows users to call
239 # to exec the config file. This allows users to call
240 # load_subconfig('myconfig.py') to load config files recursively.
240 # load_subconfig('myconfig.py') to load config files recursively.
241 # It needs to be a closure because it has references to self.path
241 # It needs to be a closure because it has references to self.path
242 # and self.config. The sub-config is loaded with the same path
242 # and self.config. The sub-config is loaded with the same path
243 # as the parent, but it uses an empty config which is then merged
243 # as the parent, but it uses an empty config which is then merged
244 # with the parents.
244 # with the parents.
245 def load_subconfig(fname):
245 def load_subconfig(fname):
246 loader = PyFileConfigLoader(fname, self.path)
246 loader = PyFileConfigLoader(fname, self.path)
247 sub_config = loader.load_config()
247 sub_config = loader.load_config()
248 self.config._merge(sub_config)
248 self.config._merge(sub_config)
249
249
250 self.config.load_subconfig = load_subconfig
250 # Again, this needs to be a closure and should be used in config
251 try:
251 # files to get the config being loaded.
252 execfile(self.full_filename, self.config)
252 def get_config():
253 finally:
253 return self.config
254 del self.config.load_subconfig
254
255 del self.config['__builtins__']
255 namespace = dict(load_subconfig=load_subconfig, get_config=get_config)
256 execfile(self.full_filename, namespace)
256
257
257 def _convert_to_config(self):
258 def _convert_to_config(self):
258 if self.data is None:
259 if self.data is None:
259 ConfigLoaderError('self.data does not exist')
260 ConfigLoaderError('self.data does not exist')
260
261
261
262
262 class CommandLineConfigLoader(ConfigLoader):
263 class CommandLineConfigLoader(ConfigLoader):
263 """A config loader for command line arguments.
264 """A config loader for command line arguments.
264
265
265 As we add more command line based loaders, the common logic should go
266 As we add more command line based loaders, the common logic should go
266 here.
267 here.
267 """
268 """
268
269
269
270
270 class NoConfigDefault(object): pass
271 class NoConfigDefault(object): pass
271 NoConfigDefault = NoConfigDefault()
272 NoConfigDefault = NoConfigDefault()
272
273
273 class ArgParseConfigLoader(CommandLineConfigLoader):
274 class ArgParseConfigLoader(CommandLineConfigLoader):
274
275
275 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
276 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
276 arguments = ()
277 arguments = ()
277
278
278 def __init__(self, *args, **kw):
279 def __init__(self, *args, **kw):
279 """Create a config loader for use with argparse.
280 """Create a config loader for use with argparse.
280
281
281 The args and kwargs arguments here are passed onto the constructor
282 The args and kwargs arguments here are passed onto the constructor
282 of :class:`argparse.ArgumentParser`.
283 of :class:`argparse.ArgumentParser`.
283 """
284 """
284 super(CommandLineConfigLoader, self).__init__()
285 super(CommandLineConfigLoader, self).__init__()
285 self.args = args
286 self.args = args
286 self.kw = kw
287 self.kw = kw
287
288
288 def load_config(self, args=None):
289 def load_config(self, args=None):
289 """Parse command line arguments and return as a Struct."""
290 """Parse command line arguments and return as a Struct."""
290 self._create_parser()
291 self._create_parser()
291 self._parse_args(args)
292 self._parse_args(args)
292 self._convert_to_config()
293 self._convert_to_config()
293 return self.config
294 return self.config
294
295
295 def get_extra_args(self):
296 def get_extra_args(self):
296 if hasattr(self, 'extra_args'):
297 if hasattr(self, 'extra_args'):
297 return self.extra_args
298 return self.extra_args
298 else:
299 else:
299 return []
300 return []
300
301
301 def _create_parser(self):
302 def _create_parser(self):
302 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
303 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
303 self._add_arguments()
304 self._add_arguments()
304 self._add_other_arguments()
305 self._add_other_arguments()
305
306
306 def _add_other_arguments(self):
307 def _add_other_arguments(self):
307 pass
308 pass
308
309
309 def _add_arguments(self):
310 def _add_arguments(self):
310 for argument in self.arguments:
311 for argument in self.arguments:
311 if not argument[1].has_key('default'):
312 if not argument[1].has_key('default'):
312 argument[1]['default'] = NoConfigDefault
313 argument[1]['default'] = NoConfigDefault
313 self.parser.add_argument(*argument[0],**argument[1])
314 self.parser.add_argument(*argument[0],**argument[1])
314
315
315 def _parse_args(self, args=None):
316 def _parse_args(self, args=None):
316 """self.parser->self.parsed_data"""
317 """self.parser->self.parsed_data"""
317 if args is None:
318 if args is None:
318 self.parsed_data, self.extra_args = self.parser.parse_known_args()
319 self.parsed_data, self.extra_args = self.parser.parse_known_args()
319 else:
320 else:
320 self.parsed_data, self.extra_args = self.parser.parse_known_args(args)
321 self.parsed_data, self.extra_args = self.parser.parse_known_args(args)
321
322
322 def _convert_to_config(self):
323 def _convert_to_config(self):
323 """self.parsed_data->self.config"""
324 """self.parsed_data->self.config"""
324 for k, v in vars(self.parsed_data).items():
325 for k, v in vars(self.parsed_data).items():
325 if v is not NoConfigDefault:
326 if v is not NoConfigDefault:
326 exec_str = 'self.config.' + k + '= v'
327 exec_str = 'self.config.' + k + '= v'
327 exec exec_str in locals(), globals()
328 exec exec_str in locals(), globals()
328
329
@@ -1,17 +1,19 b''
1 c = get_config()
2
1 # This can be used at any point in a config file to load a sub config
3 # This can be used at any point in a config file to load a sub config
2 # and merge it into the current one.
4 # and merge it into the current one.
3 load_subconfig('ipython_config.py')
5 load_subconfig('ipython_config.py')
4
6
5 lines = """
7 lines = """
6 import cmath
8 import cmath
7 from math import *
9 from math import *
8 """
10 """
9
11
10 # You have to make sure that attributes that are containers already
12 # You have to make sure that attributes that are containers already
11 # exist before using them. Simple assigning a new list will override
13 # exist before using them. Simple assigning a new list will override
12 # all previous values.
14 # all previous values.
13 if hasattr(Global, 'exec_lines'):
15 if hasattr(c.Global, 'exec_lines'):
14 Global.exec_lines.append(lines)
16 c.Global.exec_lines.append(lines)
15 else:
17 else:
16 Global.exec_lines = [lines]
18 c.Global.exec_lines = [lines]
17
19
@@ -1,18 +1,20 b''
1 c = get_config()
2
1 # This can be used at any point in a config file to load a sub config
3 # This can be used at any point in a config file to load a sub config
2 # and merge it into the current one.
4 # and merge it into the current one.
3 load_subconfig('ipython_config.py')
5 load_subconfig('ipython_config.py')
4
6
5 lines = """
7 lines = """
6 import numpy
8 import numpy
7 import scipy
9 import scipy
8 import numpy as np
10 import numpy as np
9 import scipy as sp
11 import scipy as sp
10 """
12 """
11
13
12 # You have to make sure that attributes that are containers already
14 # You have to make sure that attributes that are containers already
13 # exist before using them. Simple assigning a new list will override
15 # exist before using them. Simple assigning a new list will override
14 # all previous values.
16 # all previous values.
15 if hasattr(Global, 'exec_lines'):
17 if hasattr(c.Global, 'exec_lines'):
16 Global.exec_lines.append(lines)
18 c.Global.exec_lines.append(lines)
17 else:
19 else:
18 Global.exec_lines = [lines] No newline at end of file
20 c.Global.exec_lines = [lines] No newline at end of file
@@ -1,20 +1,22 b''
1 c = get_config()
2
1 # This can be used at any point in a config file to load a sub config
3 # This can be used at any point in a config file to load a sub config
2 # and merge it into the current one.
4 # and merge it into the current one.
3 load_subconfig('ipython_config.py')
5 load_subconfig('ipython_config.py')
4
6
5 lines = """
7 lines = """
6 import matplotlib
8 import matplotlib
7 %gui -a wx
9 %gui -a wx
8 matplotlib.use('wxagg')
10 matplotlib.use('wxagg')
9 matplotlib.interactive(True)
11 matplotlib.interactive(True)
10 from matplotlib import pyplot as plt
12 from matplotlib import pyplot as plt
11 from matplotlib.pyplot import *
13 from matplotlib.pyplot import *
12 """
14 """
13
15
14 # You have to make sure that attributes that are containers already
16 # You have to make sure that attributes that are containers already
15 # exist before using them. Simple assigning a new list will override
17 # exist before using them. Simple assigning a new list will override
16 # all previous values.
18 # all previous values.
17 if hasattr(Global, 'exec_lines'):
19 if hasattr(c.Global, 'exec_lines'):
18 Global.exec_lines.append(lines)
20 c.Global.exec_lines.append(lines)
19 else:
21 else:
20 Global.exec_lines = [lines] No newline at end of file
22 c.Global.exec_lines = [lines] No newline at end of file
@@ -1,27 +1,29 b''
1 c = get_config()
2
1 # This can be used at any point in a config file to load a sub config
3 # This can be used at any point in a config file to load a sub config
2 # and merge it into the current one.
4 # and merge it into the current one.
3 load_subconfig('ipython_config.py')
5 load_subconfig('ipython_config.py')
4
6
5 InteractiveShell.prompt_in1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
7 c.InteractiveShell.prompt_in1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
6 InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
8 c.InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
7 InteractiveShell.prompt_out = '<\#> '
9 c.InteractiveShell.prompt_out = '<\#> '
8
10
9 InteractiveShell.prompts_pad_left = True
11 c.InteractiveShell.prompts_pad_left = True
10
12
11 InteractiveShell.separate_in = ''
13 c.InteractiveShell.separate_in = ''
12 InteractiveShell.separate_out = ''
14 c.InteractiveShell.separate_out = ''
13 InteractiveShell.separate_out2 = ''
15 c.InteractiveShell.separate_out2 = ''
14
16
15 PrefilterManager.multi_line_specials = True
17 c.PrefilterManager.multi_line_specials = True
16
18
17 lines = """
19 lines = """
18 %rehashx
20 %rehashx
19 """
21 """
20
22
21 # You have to make sure that attributes that are containers already
23 # You have to make sure that attributes that are containers already
22 # exist before using them. Simple assigning a new list will override
24 # exist before using them. Simple assigning a new list will override
23 # all previous values.
25 # all previous values.
24 if hasattr(Global, 'exec_lines'):
26 if hasattr(c.Global, 'exec_lines'):
25 Global.exec_lines.append(lines)
27 c.Global.exec_lines.append(lines)
26 else:
28 else:
27 Global.exec_lines = [lines] No newline at end of file
29 c.Global.exec_lines = [lines] No newline at end of file
@@ -1,19 +1,21 b''
1 c = get_config()
2
1 # This can be used at any point in a config file to load a sub config
3 # This can be used at any point in a config file to load a sub config
2 # and merge it into the current one.
4 # and merge it into the current one.
3 load_subconfig('ipython_config.py')
5 load_subconfig('ipython_config.py')
4
6
5 lines = """
7 lines = """
6 from __future__ import division
8 from __future__ import division
7 from sympy import *
9 from sympy import *
8 x, y, z = symbols('xyz')
10 x, y, z = symbols('xyz')
9 k, m, n = symbols('kmn', integer=True)
11 k, m, n = symbols('kmn', integer=True)
10 f, g, h = map(Function, 'fgh')
12 f, g, h = map(Function, 'fgh')
11 """
13 """
12
14
13 # You have to make sure that attributes that are containers already
15 # You have to make sure that attributes that are containers already
14 # exist before using them. Simple assigning a new list will override
16 # exist before using them. Simple assigning a new list will override
15 # all previous values.
17 # all previous values.
16 if hasattr(Global, 'exec_lines'):
18 if hasattr(c.Global, 'exec_lines'):
17 Global.exec_lines.append(lines)
19 c.Global.exec_lines.append(lines)
18 else:
20 else:
19 Global.exec_lines = [lines]
21 c.Global.exec_lines = [lines]
General Comments 0
You need to be logged in to leave comments. Login now