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