Show More
@@ -1,81 +1,66 b'' | |||
|
1 | 1 | #----------------------------------------------------------------------------- |
|
2 | # IPython Shell Configuration Defaults | |
|
2 | # Global options | |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | |
|
5 | Global.classic = False | |
|
6 | Global.nosep = False | |
|
7 | ||
|
5 | 8 | #----------------------------------------------------------------------------- |
|
6 | # Startup | |
|
9 | # InteractiveShell options | |
|
7 | 10 | #----------------------------------------------------------------------------- |
|
8 | 11 | |
|
9 | AUTOCALL = True | |
|
10 | ||
|
11 | AUTOEDIT_SYNTAX = False | |
|
12 | ||
|
13 | AUTOINDENT = True | |
|
14 | ||
|
15 | AUTOMAGIC = True | |
|
16 | ||
|
17 | CACHE_SIZE = 1000 | |
|
18 | 12 | |
|
19 | CLASSIC = False | |
|
13 | InteractiveShell.autocall = 1 | |
|
20 | 14 | |
|
21 | COLORS = 'Linux' | |
|
15 | InteractiveShell.autoedit_syntax = False | |
|
22 | 16 | |
|
23 | COLOR_INFO = True | |
|
17 | InteractiveShell.autoindent = True | |
|
24 | 18 | |
|
25 | CONFIRM_EXIT = True | |
|
19 | InteractiveShell.automagic = False | |
|
26 | 20 | |
|
27 | DEEP_RELOAD = False | |
|
21 | InteractiveShell.banner1 = 'This if for overriding the default IPython banner' | |
|
28 | 22 | |
|
29 | EDITOR = 0 | |
|
23 | InteractiveShell.banner2 = "This is for extra banner text" | |
|
30 | 24 | |
|
31 | LOG = True | |
|
25 | InteractiveShell.cache_size = 1000 | |
|
32 | 26 | |
|
33 | LOGFILE = '' | |
|
27 | InteractiveShell.colors = 'LightBG' | |
|
34 | 28 | |
|
35 | BANNER = True | |
|
29 | InteractiveShell.color_info = True | |
|
36 | 30 | |
|
37 | MESSAGES = True | |
|
31 | InteractiveShell.confirm_exit = True | |
|
38 | 32 | |
|
39 | PDB = False | |
|
33 | InteractiveShell.deep_reload = False | |
|
40 | 34 | |
|
41 | PPRINT = True | |
|
35 | InteractiveShell.display_banner = True | |
|
42 | 36 | |
|
43 | PROMPT_IN1 = 'In [\#]: ' | |
|
37 | InteractiveShell.editor = 'nano' | |
|
44 | 38 | |
|
45 | PROMPT_IN2 = ' .\D.: ' | |
|
39 | InteractiveShell.logstart = True | |
|
46 | 40 | |
|
47 | PROMPT_OUT = 'Out[\#]: ' | |
|
41 | InteractiveShell.logfile = 'ipython_log.py' | |
|
48 | 42 | |
|
49 | PROMPTS_PAD_LEFT = True | |
|
43 | InteractiveShell.logplay = 'mylog.py' | |
|
50 | 44 | |
|
51 | QUICK = False | |
|
45 | InteractiveShell.object_info_string_level = 0 | |
|
52 | 46 | |
|
53 | SCREEN_LENGTH = 0 | |
|
47 | InteractiveShell.pager = 'less' | |
|
54 | 48 | |
|
55 | SEPARATE_IN = '\n' | |
|
56 | SEPARATE_OUT = '' | |
|
57 | SEPARATE_OUT2 = '' | |
|
58 | NOSEP = False | |
|
49 | InteractiveShell.pdb = False | |
|
59 | 50 | |
|
60 | WILDCARDS_CASE_SENSITIVE = True | |
|
51 | InteractiveShell.pprint = True | |
|
61 | 52 | |
|
62 | OBJECT_INFO_STRING_LEVEL = 0 | |
|
53 | InteractiveShell.prompt_in1 = 'In [\#]: ' | |
|
54 | InteractiveShell.prompt_in2 = ' .\D.: ' | |
|
55 | InteractiveShell.prompt_out = 'Out[\#]: ' | |
|
56 | InteractiveShell.prompts_pad_left = True | |
|
63 | 57 | |
|
64 | XMODE = 'Context' | |
|
58 | InteractiveShell.quiet = False | |
|
65 | 59 | |
|
66 | MULTI_LINE_SPECIALS = True | |
|
67 | ||
|
68 | SYSTEM_HEADER = "IPython system call: " | |
|
69 | ||
|
70 | SYSTEM_VERBOSE = True | |
|
71 | ||
|
72 | #----------------------------------------------------------------------------- | |
|
73 | 60 | # Readline |
|
74 | #----------------------------------------------------------------------------- | |
|
75 | ||
|
76 | READLINE = True | |
|
61 | InteractiveShell.readline_use = False | |
|
77 | 62 | |
|
78 | READLINE_PARSE_AND_BIND = [ | |
|
63 | InteractiveShell.readline_parse_and_bind = [ | |
|
79 | 64 | 'tab: complete', |
|
80 | 65 | '"\C-l": possible-completions', |
|
81 | 66 | 'set show-all-if-ambiguous on', |
@@ -92,29 +77,39 b' READLINE_PARSE_AND_BIND = [' | |||
|
92 | 77 | '"\C-k": kill-line', |
|
93 | 78 | '"\C-u": unix-line-discard', |
|
94 | 79 | ] |
|
80 | InteractiveShell.readline_remove_delims = '-/~' | |
|
81 | InteractiveShell.readline_merge_completions = True | |
|
82 | InteractiveShell.readline_omit_names = 0 | |
|
83 | ||
|
84 | InteractiveShell.screen_length = 0 | |
|
85 | ||
|
86 | InteractiveShell.separate_in = '\n' | |
|
87 | InteractiveShell.separate_out = '' | |
|
88 | InteractiveShell.separate_out2 = '' | |
|
89 | ||
|
90 | InteractiveShell.system_header = "IPython system call: " | |
|
95 | 91 | |
|
96 | READLINE_REMOVE_DELIMS = '-/~' | |
|
92 | InteractiveShell.system_verbose = True | |
|
97 | 93 | |
|
98 | READLINE_MERGE_COMPLETIONS = True | |
|
94 | InteractiveShell.term_title = False | |
|
99 | 95 | |
|
100 | READLINE_OMIT_NAMES = 0 | |
|
96 | InteractiveShell.wildcards_case_sensitive = True | |
|
97 | ||
|
98 | InteractiveShell.xmode = 'Context' | |
|
101 | 99 | |
|
102 | 100 | #----------------------------------------------------------------------------- |
|
103 | # Code to execute | |
|
101 | # PrefilterManager options | |
|
104 | 102 | #----------------------------------------------------------------------------- |
|
105 | 103 | |
|
106 | EXECUTE = [ | |
|
107 | 'import numpy as np', | |
|
108 | 'import sympy', | |
|
109 | 'a = 10' | |
|
110 | ] | |
|
111 | ||
|
112 | EXECFILE = [] | |
|
104 | PrefilterManager.multi_line_specials = True | |
|
113 | 105 | |
|
114 | 106 | #----------------------------------------------------------------------------- |
|
115 | # Alias | |
|
107 | # AliasManager options | |
|
116 | 108 | #----------------------------------------------------------------------------- |
|
117 | 109 | |
|
118 | ALIAS = [ | |
|
119 | ('myls', 'ls -la') | |
|
110 | # Do this to enable all defaults | |
|
111 | # AliasManager.default_aliases = [] | |
|
112 | ||
|
113 | AliasManger.user_aliases = [ | |
|
114 | ('foo', 'echo Hi') | |
|
120 | 115 | ] No newline at end of file |
@@ -1,6 +1,10 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # encoding: utf-8 |
|
3 | """A factory for creating configuration objects. | |
|
3 | """A simple configuration system. | |
|
4 | ||
|
5 | Authors: | |
|
6 | ||
|
7 | * Brian Granger | |
|
4 | 8 | """ |
|
5 | 9 | |
|
6 | 10 | #----------------------------------------------------------------------------- |
@@ -14,22 +18,138 b'' | |||
|
14 | 18 | # Imports |
|
15 | 19 | #----------------------------------------------------------------------------- |
|
16 | 20 | |
|
21 | import __builtin__ | |
|
17 | 22 | import os |
|
18 | 23 | import sys |
|
19 | 24 | |
|
20 | 25 | from IPython.external import argparse |
|
21 | from IPython.utils.ipstruct import Struct | |
|
22 | 26 | from IPython.utils.genutils import filefind |
|
23 | 27 | |
|
24 | 28 | #----------------------------------------------------------------------------- |
|
25 | # Code | |
|
29 | # Exceptions | |
|
26 | 30 | #----------------------------------------------------------------------------- |
|
27 | 31 | |
|
28 | 32 | |
|
29 |
class Config |
|
|
33 | class ConfigError(Exception): | |
|
34 | pass | |
|
35 | ||
|
36 | ||
|
37 | class ConfigLoaderError(ConfigError): | |
|
30 | 38 | pass |
|
31 | 39 | |
|
32 | 40 | |
|
41 | #----------------------------------------------------------------------------- | |
|
42 | # Config class for holding config information | |
|
43 | #----------------------------------------------------------------------------- | |
|
44 | ||
|
45 | ||
|
46 | class Config(dict): | |
|
47 | """An attribute based dict that can do smart merges.""" | |
|
48 | ||
|
49 | def __init__(self, *args, **kwds): | |
|
50 | dict.__init__(self, *args, **kwds) | |
|
51 | # This sets self.__dict__ = self, but it has to be done this way | |
|
52 | # because we are also overriding __setattr__. | |
|
53 | dict.__setattr__(self, '__dict__', self) | |
|
54 | ||
|
55 | def _merge(self, other): | |
|
56 | to_update = {} | |
|
57 | for k, v in other.items(): | |
|
58 | if not self.has_key(k): | |
|
59 | to_update[k] = v | |
|
60 | else: # I have this key | |
|
61 | if isinstance(v, Config): | |
|
62 | # Recursively merge common sub Configs | |
|
63 | self[k]._merge(v) | |
|
64 | else: | |
|
65 | # Plain updates for non-Configs | |
|
66 | to_update[k] = v | |
|
67 | ||
|
68 | self.update(to_update) | |
|
69 | ||
|
70 | def _is_section_key(self, key): | |
|
71 | if key[0].upper()==key[0] and not key.startswith('_'): | |
|
72 | return True | |
|
73 | else: | |
|
74 | return False | |
|
75 | ||
|
76 | def has_key(self, key): | |
|
77 | if self._is_section_key(key): | |
|
78 | return True | |
|
79 | else: | |
|
80 | return dict.has_key(self, key) | |
|
81 | ||
|
82 | def _has_section(self, key): | |
|
83 | if self._is_section_key(key): | |
|
84 | if dict.has_key(self, key): | |
|
85 | return True | |
|
86 | return False | |
|
87 | ||
|
88 | def copy(self): | |
|
89 | return type(self)(dict.copy(self)) | |
|
90 | ||
|
91 | def __copy__(self): | |
|
92 | return self.copy() | |
|
93 | ||
|
94 | def __deepcopy__(self, memo): | |
|
95 | import copy | |
|
96 | return type(self)(copy.deepcopy(self.items())) | |
|
97 | ||
|
98 | def __getitem__(self, key): | |
|
99 | # Because we use this for an exec namespace, we need to delegate | |
|
100 | # the lookup of names in __builtin__ to itself. This means | |
|
101 | # that you can't have section or attribute names that are | |
|
102 | # builtins. | |
|
103 | try: | |
|
104 | return getattr(__builtin__, key) | |
|
105 | except AttributeError: | |
|
106 | pass | |
|
107 | if self._is_section_key(key): | |
|
108 | try: | |
|
109 | return dict.__getitem__(self, key) | |
|
110 | except KeyError: | |
|
111 | c = Config() | |
|
112 | dict.__setitem__(self, key, c) | |
|
113 | return c | |
|
114 | else: | |
|
115 | return dict.__getitem__(self, key) | |
|
116 | ||
|
117 | def __setitem__(self, key, value): | |
|
118 | # Don't allow names in __builtin__ to be modified. | |
|
119 | if hasattr(__builtin__, key): | |
|
120 | raise ConfigError('Config variable names cannot have the same name ' | |
|
121 | 'as a Python builtin: %s' % key) | |
|
122 | if self._is_section_key(key): | |
|
123 | if not isinstance(value, Config): | |
|
124 | raise ValueError('values whose keys begin with an uppercase ' | |
|
125 | 'char must be Config instances: %r, %r' % (key, value)) | |
|
126 | else: | |
|
127 | dict.__setitem__(self, key, value) | |
|
128 | ||
|
129 | def __getattr__(self, key): | |
|
130 | try: | |
|
131 | return self.__getitem__(key) | |
|
132 | except KeyError, e: | |
|
133 | raise AttributeError(e) | |
|
134 | ||
|
135 | def __setattr__(self, key, value): | |
|
136 | try: | |
|
137 | self.__setitem__(key, value) | |
|
138 | except KeyError, e: | |
|
139 | raise AttributeError(e) | |
|
140 | ||
|
141 | def __delattr__(self, key): | |
|
142 | try: | |
|
143 | dict.__delitem__(self, key) | |
|
144 | except KeyError, e: | |
|
145 | raise AttributeError(e) | |
|
146 | ||
|
147 | ||
|
148 | #----------------------------------------------------------------------------- | |
|
149 | # Config loading classes | |
|
150 | #----------------------------------------------------------------------------- | |
|
151 | ||
|
152 | ||
|
33 | 153 | class ConfigLoader(object): |
|
34 | 154 | """A object for loading configurations from just about anywhere. |
|
35 | 155 | |
@@ -59,7 +179,7 b' class ConfigLoader(object):' | |||
|
59 | 179 | self.clear() |
|
60 | 180 | |
|
61 | 181 | def clear(self): |
|
62 |
self.config = |
|
|
182 | self.config = Config() | |
|
63 | 183 | |
|
64 | 184 | def load_config(self): |
|
65 | 185 | """Load a config from somewhere, return a Struct. |
@@ -106,7 +226,7 b' class PyFileConfigLoader(FileConfigLoader):' | |||
|
106 | 226 | """Load the config from a file and return it as a Struct.""" |
|
107 | 227 | self._find_file() |
|
108 | 228 | self._read_file_as_dict() |
|
109 |
self._convert_to_ |
|
|
229 | self._convert_to_config() | |
|
110 | 230 | return self.config |
|
111 | 231 | |
|
112 | 232 | def _find_file(self): |
@@ -114,15 +234,12 b' class PyFileConfigLoader(FileConfigLoader):' | |||
|
114 | 234 | self.full_filename = filefind(self.filename, self.path) |
|
115 | 235 | |
|
116 | 236 | def _read_file_as_dict(self): |
|
117 | self.data = {} | |
|
118 | execfile(self.full_filename, self.data) | |
|
237 | execfile(self.full_filename, self.config) | |
|
119 | 238 | |
|
120 |
def _convert_to_ |
|
|
239 | def _convert_to_config(self): | |
|
121 | 240 | if self.data is None: |
|
122 | 241 | ConfigLoaderError('self.data does not exist') |
|
123 | for k, v in self.data.iteritems(): | |
|
124 | if k == k.upper(): | |
|
125 | self.config[k] = v | |
|
242 | del self.config['__builtins__'] | |
|
126 | 243 | |
|
127 | 244 | |
|
128 | 245 | class CommandLineConfigLoader(ConfigLoader): |
@@ -133,8 +250,8 b' class CommandLineConfigLoader(ConfigLoader):' | |||
|
133 | 250 | """ |
|
134 | 251 | |
|
135 | 252 | |
|
136 | class NoDefault(object): pass | |
|
137 | NoDefault = NoDefault() | |
|
253 | class NoConfigDefault(object): pass | |
|
254 | NoConfigDefault = NoConfigDefault() | |
|
138 | 255 | |
|
139 | 256 | class ArgParseConfigLoader(CommandLineConfigLoader): |
|
140 | 257 | |
@@ -155,7 +272,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):' | |||
|
155 | 272 | """Parse command line arguments and return as a Struct.""" |
|
156 | 273 | self._create_parser() |
|
157 | 274 | self._parse_args(args) |
|
158 |
self._convert_to_ |
|
|
275 | self._convert_to_config() | |
|
159 | 276 | return self.config |
|
160 | 277 | |
|
161 | 278 | def _create_parser(self): |
@@ -169,7 +286,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):' | |||
|
169 | 286 | def _add_arguments(self): |
|
170 | 287 | for argument in self.arguments: |
|
171 | 288 | if not argument[1].has_key('default'): |
|
172 | argument[1]['default'] = NoDefault | |
|
289 | argument[1]['default'] = NoConfigDefault | |
|
173 | 290 | self.parser.add_argument(*argument[0],**argument[1]) |
|
174 | 291 | |
|
175 | 292 | def _parse_args(self, args=None): |
@@ -179,25 +296,10 b' class ArgParseConfigLoader(CommandLineConfigLoader):' | |||
|
179 | 296 | else: |
|
180 | 297 | self.parsed_data = self.parser.parse_args(args) |
|
181 | 298 | |
|
182 |
def _convert_to_ |
|
|
299 | def _convert_to_config(self): | |
|
183 | 300 | """self.parsed_data->self.config""" |
|
184 | self.config = Struct() | |
|
185 | 301 | for k, v in vars(self.parsed_data).items(): |
|
186 | if v is not NoDefault: | |
|
187 |
|
|
|
188 | ||
|
189 | class IPythonArgParseConfigLoader(ArgParseConfigLoader): | |
|
302 | if v is not NoConfigDefault: | |
|
303 | exec_str = 'self.config.' + k + '= v' | |
|
304 | exec exec_str in locals(), globals() | |
|
190 | 305 | |
|
191 | def _add_other_arguments(self): | |
|
192 | self.parser.add_argument('-ipythondir',dest='IPYTHONDIR',type=str, | |
|
193 | help='Set to override default location of IPYTHONDIR.', | |
|
194 | default=NoDefault) | |
|
195 | self.parser.add_argument('-p','-profile',dest='PROFILE',type=str, | |
|
196 | help='The string name of the ipython profile to be used.', | |
|
197 | default=NoDefault) | |
|
198 | self.parser.add_argument('-debug',dest="DEBUG",action='store_true', | |
|
199 | help='Debug the application startup process.', | |
|
200 | default=NoDefault) | |
|
201 | self.parser.add_argument('-config_file',dest='CONFIG_FILE',type=str, | |
|
202 | help='Set the config file name to override default.', | |
|
203 | default=NoDefault) |
@@ -24,7 +24,12 b' import os' | |||
|
24 | 24 | from tempfile import mkstemp |
|
25 | 25 | from unittest import TestCase |
|
26 | 26 | |
|
27 |
from IPython.config.loader import |
|
|
27 | from IPython.config.loader import ( | |
|
28 | Config, | |
|
29 | PyFileConfigLoader, | |
|
30 | ArgParseConfigLoader, | |
|
31 | ConfigError | |
|
32 | ) | |
|
28 | 33 | |
|
29 | 34 | #----------------------------------------------------------------------------- |
|
30 | 35 | # Actual tests |
@@ -32,10 +37,11 b' from IPython.config.loader import PyFileConfigLoader, ArgParseConfigLoader' | |||
|
32 | 37 | |
|
33 | 38 | |
|
34 | 39 | pyfile = """ |
|
35 |
|
|
|
36 | B = range(10) | |
|
37 | C = True | |
|
38 | D = 'hi there' | |
|
40 | a = 10 | |
|
41 | b = 20 | |
|
42 | Foo.Bar.value = 10 | |
|
43 | Foo.Bam.value = range(10) | |
|
44 | D.C.value = 'hi there' | |
|
39 | 45 | """ |
|
40 | 46 | |
|
41 | 47 | class TestPyFileCL(TestCase): |
@@ -48,10 +54,11 b' class TestPyFileCL(TestCase):' | |||
|
48 | 54 | # Unlink the file |
|
49 | 55 | cl = PyFileConfigLoader(fname) |
|
50 | 56 | config = cl.load_config() |
|
51 |
self.assertEquals(config. |
|
|
52 |
self.assertEquals(config. |
|
|
53 |
self.assertEquals(config. |
|
|
54 |
self.assertEquals(config. |
|
|
57 | self.assertEquals(config.a, 10) | |
|
58 | self.assertEquals(config.b, 20) | |
|
59 | self.assertEquals(config.Foo.Bar.value, 10) | |
|
60 | self.assertEquals(config.Foo.Bam.value, range(10)) | |
|
61 | self.assertEquals(config.D.C.value, 'hi there') | |
|
55 | 62 | |
|
56 | 63 | |
|
57 | 64 | class TestArgParseCL(TestCase): |
@@ -60,18 +67,18 b' class TestArgParseCL(TestCase):' | |||
|
60 | 67 | |
|
61 | 68 | class MyLoader(ArgParseConfigLoader): |
|
62 | 69 | arguments = ( |
|
63 |
(('-f','--foo'), dict(dest=' |
|
|
64 |
(('-b',), dict(dest=' |
|
|
65 |
(('-n',), dict(dest=' |
|
|
66 |
((' |
|
|
70 | (('-f','--foo'), dict(dest='Global.foo', type=str)), | |
|
71 | (('-b',), dict(dest='MyClass.bar', type=int)), | |
|
72 | (('-n',), dict(dest='n', action='store_true')), | |
|
73 | (('Global.bam',), dict(type=str)) | |
|
67 | 74 | ) |
|
68 | 75 | |
|
69 | 76 | cl = MyLoader() |
|
70 | 77 | config = cl.load_config('-f hi -b 10 -n wow'.split()) |
|
71 |
self.assertEquals(config. |
|
|
72 |
self.assertEquals(config. |
|
|
73 |
self.assertEquals(config. |
|
|
74 |
self.assertEquals(config. |
|
|
78 | self.assertEquals(config.Global.foo, 'hi') | |
|
79 | self.assertEquals(config.MyClass.bar, 10) | |
|
80 | self.assertEquals(config.n, True) | |
|
81 | self.assertEquals(config.Global.bam, 'wow') | |
|
75 | 82 | |
|
76 | 83 | def test_add_arguments(self): |
|
77 | 84 | |
@@ -79,7 +86,7 b' class TestArgParseCL(TestCase):' | |||
|
79 | 86 | def _add_arguments(self): |
|
80 | 87 | subparsers = self.parser.add_subparsers(dest='subparser_name') |
|
81 | 88 | subparser1 = subparsers.add_parser('1') |
|
82 | subparser1.add_argument('-x') | |
|
89 | subparser1.add_argument('-x',dest='Global.x') | |
|
83 | 90 | subparser2 = subparsers.add_parser('2') |
|
84 | 91 | subparser2.add_argument('y') |
|
85 | 92 | |
@@ -89,5 +96,68 b' class TestArgParseCL(TestCase):' | |||
|
89 | 96 | self.assertEquals(config.y, 'frobble') |
|
90 | 97 | config = cl.load_config('1 -x frobble'.split()) |
|
91 | 98 | self.assertEquals(config.subparser_name, '1') |
|
92 | self.assertEquals(config.x, 'frobble') | |
|
93 | ||
|
99 | self.assertEquals(config.Global.x, 'frobble') | |
|
100 | ||
|
101 | class TestConfig(TestCase): | |
|
102 | ||
|
103 | def test_setget(self): | |
|
104 | c = Config() | |
|
105 | c.a = 10 | |
|
106 | self.assertEquals(c.a, 10) | |
|
107 | self.assertEquals(c.has_key('b'), False) | |
|
108 | ||
|
109 | def test_auto_section(self): | |
|
110 | c = Config() | |
|
111 | self.assertEquals(c.has_key('A'), True) | |
|
112 | self.assertEquals(c._has_section('A'), False) | |
|
113 | A = c.A | |
|
114 | A.foo = 'hi there' | |
|
115 | self.assertEquals(c._has_section('A'), True) | |
|
116 | self.assertEquals(c.A.foo, 'hi there') | |
|
117 | del c.A | |
|
118 | self.assertEquals(len(c.A.keys()),0) | |
|
119 | ||
|
120 | def test_merge_doesnt_exist(self): | |
|
121 | c1 = Config() | |
|
122 | c2 = Config() | |
|
123 | c2.bar = 10 | |
|
124 | c2.Foo.bar = 10 | |
|
125 | c1._merge(c2) | |
|
126 | self.assertEquals(c1.Foo.bar, 10) | |
|
127 | self.assertEquals(c1.bar, 10) | |
|
128 | c2.Bar.bar = 10 | |
|
129 | c1._merge(c2) | |
|
130 | self.assertEquals(c1.Bar.bar, 10) | |
|
131 | ||
|
132 | def test_merge_exists(self): | |
|
133 | c1 = Config() | |
|
134 | c2 = Config() | |
|
135 | c1.Foo.bar = 10 | |
|
136 | c1.Foo.bam = 30 | |
|
137 | c2.Foo.bar = 20 | |
|
138 | c2.Foo.wow = 40 | |
|
139 | c1._merge(c2) | |
|
140 | self.assertEquals(c1.Foo.bam, 30) | |
|
141 | self.assertEquals(c1.Foo.bar, 20) | |
|
142 | self.assertEquals(c1.Foo.wow, 40) | |
|
143 | c2.Foo.Bam.bam = 10 | |
|
144 | c1._merge(c2) | |
|
145 | self.assertEquals(c1.Foo.Bam.bam, 10) | |
|
146 | ||
|
147 | def test_deepcopy(self): | |
|
148 | c1 = Config() | |
|
149 | c1.Foo.bar = 10 | |
|
150 | c1.Foo.bam = 30 | |
|
151 | c1.a = 'asdf' | |
|
152 | c1.b = range(10) | |
|
153 | import copy | |
|
154 | c2 = copy.deepcopy(c1) | |
|
155 | self.assertEquals(c1, c2) | |
|
156 | self.assert_(c1 is not c2) | |
|
157 | self.assert_(c1.Foo is not c2.Foo) | |
|
158 | ||
|
159 | def test_builtin(self): | |
|
160 | c1 = Config() | |
|
161 | exec 'foo = True' in c1 | |
|
162 | self.assertEquals(c1.foo, True) | |
|
163 | self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10) |
@@ -43,7 +43,7 b' def default_aliases():' | |||
|
43 | 43 | # Make some aliases automatically |
|
44 | 44 | # Prepare list of shell aliases to auto-define |
|
45 | 45 | if os.name == 'posix': |
|
46 |
aut |
|
|
46 | default_aliases = ('mkdir mkdir', 'rmdir rmdir', | |
|
47 | 47 | 'mv mv -i','rm rm -i','cp cp -i', |
|
48 | 48 | 'cat cat','less less','clear clear', |
|
49 | 49 | # a better ls |
@@ -75,15 +75,15 b' def default_aliases():' | |||
|
75 | 75 | # things which are executable |
|
76 | 76 | 'lx ls -lF | grep ^-..x', |
|
77 | 77 | ) |
|
78 |
aut |
|
|
78 | default_aliases = default_aliases + ls_extra | |
|
79 | 79 | elif os.name in ['nt','dos']: |
|
80 |
aut |
|
|
80 | default_aliases = ('ls dir /on', | |
|
81 | 81 | 'ddir dir /ad /on', 'ldir dir /ad /on', |
|
82 | 82 | 'mkdir mkdir','rmdir rmdir','echo echo', |
|
83 | 83 | 'ren ren','cls cls','copy copy') |
|
84 | 84 | else: |
|
85 |
aut |
|
|
86 |
return [s.split(None,1) for s in aut |
|
|
85 | default_aliases = () | |
|
86 | return [s.split(None,1) for s in default_aliases] | |
|
87 | 87 | |
|
88 | 88 | |
|
89 | 89 | class AliasError(Exception): |
@@ -101,8 +101,8 b' class InvalidAliasError(AliasError):' | |||
|
101 | 101 | |
|
102 | 102 | class AliasManager(Component): |
|
103 | 103 | |
|
104 |
aut |
|
|
105 |
user_alias = List(default_value=[], config |
|
|
104 | default_aliases = List(default_aliases(), config=True) | |
|
105 | user_aliases = List(default_value=[], config=True) | |
|
106 | 106 | |
|
107 | 107 | def __init__(self, parent, config=None): |
|
108 | 108 | super(AliasManager, self).__init__(parent, config=config) |
@@ -137,13 +137,16 b' class AliasManager(Component):' | |||
|
137 | 137 | |
|
138 | 138 | def init_aliases(self): |
|
139 | 139 | # Load default aliases |
|
140 |
for name, cmd in self.aut |
|
|
140 | for name, cmd in self.default_aliases: | |
|
141 | 141 | self.soft_define_alias(name, cmd) |
|
142 | 142 | |
|
143 | 143 | # Load user aliases |
|
144 | for name, cmd in self.user_alias: | |
|
144 | for name, cmd in self.user_aliases: | |
|
145 | 145 | self.soft_define_alias(name, cmd) |
|
146 | 146 | |
|
147 | def clear_aliases(self): | |
|
148 | self.alias_table.clear() | |
|
149 | ||
|
147 | 150 | def soft_define_alias(self, name, cmd): |
|
148 | 151 | """Define an alias, but don't raise on an AliasError.""" |
|
149 | 152 | try: |
@@ -160,6 +163,10 b' class AliasManager(Component):' | |||
|
160 | 163 | nargs = self.validate_alias(name, cmd) |
|
161 | 164 | self.alias_table[name] = (nargs, cmd) |
|
162 | 165 | |
|
166 | def undefine_alias(self, name): | |
|
167 | if self.alias_table.has_key(name): | |
|
168 | del self.alias_table[name] | |
|
169 | ||
|
163 | 170 | def validate_alias(self, name, cmd): |
|
164 | 171 | """Validate an alias and return the its number of arguments.""" |
|
165 | 172 | if name in self.no_alias: |
@@ -26,13 +26,14 b' Notes' | |||
|
26 | 26 | import os |
|
27 | 27 | import sys |
|
28 | 28 | import traceback |
|
29 | ||
|
30 | 29 | from copy import deepcopy |
|
31 | from IPython.utils.ipstruct import Struct | |
|
30 | ||
|
32 | 31 | from IPython.utils.genutils import get_ipython_dir, filefind |
|
33 | 32 | from IPython.config.loader import ( |
|
34 |
|
|
|
35 |
|
|
|
33 | PyFileConfigLoader, | |
|
34 | ArgParseConfigLoader, | |
|
35 | Config, | |
|
36 | NoConfigDefault | |
|
36 | 37 | ) |
|
37 | 38 | |
|
38 | 39 | #----------------------------------------------------------------------------- |
@@ -40,6 +41,27 b' from IPython.config.loader import (' | |||
|
40 | 41 | #----------------------------------------------------------------------------- |
|
41 | 42 | |
|
42 | 43 | |
|
44 | class IPythonArgParseConfigLoader(ArgParseConfigLoader): | |
|
45 | """Default command line options for IPython based applications.""" | |
|
46 | ||
|
47 | def _add_other_arguments(self): | |
|
48 | self.parser.add_argument('-ipythondir',dest='Global.ipythondir',type=str, | |
|
49 | help='Set to override default location of Global.ipythondir.', | |
|
50 | default=NoConfigDefault, | |
|
51 | metavar='Global.ipythondir') | |
|
52 | self.parser.add_argument('-p','-profile',dest='Global.profile',type=str, | |
|
53 | help='The string name of the ipython profile to be used.', | |
|
54 | default=NoConfigDefault, | |
|
55 | metavar='Global.profile') | |
|
56 | self.parser.add_argument('-debug',dest="Global.debug",action='store_true', | |
|
57 | help='Debug the application startup process.', | |
|
58 | default=NoConfigDefault) | |
|
59 | self.parser.add_argument('-config_file',dest='Global.config_file',type=str, | |
|
60 | help='Set the config file name to override default.', | |
|
61 | default=NoConfigDefault, | |
|
62 | metavar='Global.config_file') | |
|
63 | ||
|
64 | ||
|
43 | 65 | class ApplicationError(Exception): |
|
44 | 66 | pass |
|
45 | 67 | |
@@ -79,8 +101,8 b' class Application(object):' | |||
|
79 | 101 | |
|
80 | 102 | def create_default_config(self): |
|
81 | 103 | """Create defaults that can't be set elsewhere.""" |
|
82 |
self.default_config = |
|
|
83 |
self.default_config. |
|
|
104 | self.default_config = Config() | |
|
105 | self.default_config.Global.ipythondir = get_ipython_dir() | |
|
84 | 106 | |
|
85 | 107 | def create_command_line_config(self): |
|
86 | 108 | """Create and return a command line config loader.""" |
@@ -99,7 +121,7 b' class Application(object):' | |||
|
99 | 121 | loader = self.create_command_line_config() |
|
100 | 122 | self.command_line_config = loader.load_config() |
|
101 | 123 | try: |
|
102 |
self.debug = self.command_line_config. |
|
|
124 | self.debug = self.command_line_config.Global.debug | |
|
103 | 125 | except AttributeError: |
|
104 | 126 | pass # use class default |
|
105 | 127 | self.log("Default config loaded:", self.default_config) |
@@ -120,9 +142,9 b' class Application(object):' | |||
|
120 | 142 | """ |
|
121 | 143 | |
|
122 | 144 | try: |
|
123 |
self.ipythondir = self.command_line_config. |
|
|
145 | self.ipythondir = self.command_line_config.Global.ipythondir | |
|
124 | 146 | except AttributeError: |
|
125 |
self.ipythondir = self.default_config. |
|
|
147 | self.ipythondir = self.default_config.Global.ipythondir | |
|
126 | 148 | sys.path.append(os.path.abspath(self.ipythondir)) |
|
127 | 149 | if not os.path.isdir(self.ipythondir): |
|
128 | 150 | os.makedirs(self.ipythondir, mode = 0777) |
@@ -138,12 +160,12 b' class Application(object):' | |||
|
138 | 160 | """ |
|
139 | 161 | |
|
140 | 162 | try: |
|
141 |
self.config_file_name = self.command_line_config. |
|
|
163 | self.config_file_name = self.command_line_config.Global.config_file | |
|
142 | 164 | except AttributeError: |
|
143 | 165 | pass |
|
144 | 166 | |
|
145 | 167 | try: |
|
146 |
self.profile_name = self.command_line_config. |
|
|
168 | self.profile_name = self.command_line_config.Global.profile | |
|
147 | 169 | name_parts = self.config_file_name.split('.') |
|
148 | 170 | name_parts.insert(1, '_' + self.profile_name + '.') |
|
149 | 171 | self.config_file_name = ''.join(name_parts) |
@@ -166,14 +188,14 b' class Application(object):' | |||
|
166 | 188 | location. If not successful, an empty config is used. |
|
167 | 189 | """ |
|
168 | 190 |
loader = PyFileConfigLoader(self.config_file_name, |
|
169 | self.config_file_paths) | |
|
191 | path=self.config_file_paths) | |
|
170 | 192 | try: |
|
171 | 193 | self.file_config = loader.load_config() |
|
172 |
self.file_config. |
|
|
194 | self.file_config.Global.config_file = loader.full_filename | |
|
173 | 195 | except IOError: |
|
174 | 196 | self.log("Config file not found, skipping: %s" % \ |
|
175 | 197 | self.config_file_name) |
|
176 |
self.file_config = |
|
|
198 | self.file_config = Config() | |
|
177 | 199 | else: |
|
178 | 200 | self.log("Config file loaded: %s" % loader.full_filename, |
|
179 | 201 | self.file_config) |
@@ -184,10 +206,10 b' class Application(object):' | |||
|
184 | 206 | |
|
185 | 207 | def merge_configs(self): |
|
186 | 208 | """Merge the default, command line and file config objects.""" |
|
187 |
config = |
|
|
188 |
config. |
|
|
189 |
config. |
|
|
190 |
config. |
|
|
209 | config = Config() | |
|
210 | config._merge(self.default_config) | |
|
211 | config._merge(self.file_config) | |
|
212 | config._merge(self.command_line_config) | |
|
191 | 213 | self.master_config = config |
|
192 | 214 | self.log("Master config created:", self.master_config) |
|
193 | 215 | |
@@ -223,12 +245,13 b' class Application(object):' | |||
|
223 | 245 | def attempt(self, func, action='abort'): |
|
224 | 246 | try: |
|
225 | 247 | func() |
|
248 | except SystemExit: | |
|
249 | self.exit() | |
|
226 | 250 | except: |
|
227 | 251 | if action == 'abort': |
|
228 | 252 | self.print_traceback() |
|
229 | 253 | self.abort() |
|
230 | 254 | elif action == 'exit': |
|
231 | self.print_traceback() | |
|
232 | 255 | self.exit() |
|
233 | 256 | |
|
234 | 257 | def print_traceback(self): |
@@ -40,6 +40,9 b' class BuiltinTrap(Component):' | |||
|
40 | 40 | def __init__(self, parent): |
|
41 | 41 | super(BuiltinTrap, self).__init__(parent, None, None) |
|
42 | 42 | self._orig_builtins = {} |
|
43 | # We define this to track if a single BuiltinTrap is nested. | |
|
44 | # Only turn off the trap when the outermost call to __exit__ is made. | |
|
45 | self._nested_level = 0 | |
|
43 | 46 | |
|
44 | 47 | @auto_attr |
|
45 | 48 | def shell(self): |
@@ -50,12 +53,16 b' class BuiltinTrap(Component):' | |||
|
50 | 53 | return shell |
|
51 | 54 | |
|
52 | 55 | def __enter__(self): |
|
56 | if self._nested_level == 0: | |
|
53 | 57 | self.set() |
|
58 | self._nested_level += 1 | |
|
54 | 59 | # I return self, so callers can use add_builtin in a with clause. |
|
55 | 60 | return self |
|
56 | 61 | |
|
57 | 62 | def __exit__(self, type, value, traceback): |
|
63 | if self._nested_level == 1: | |
|
58 | 64 | self.unset() |
|
65 | self._nested_level -= 1 | |
|
59 | 66 | return True |
|
60 | 67 | |
|
61 | 68 | def add_builtin(self, key, value): |
@@ -25,7 +25,7 b' import datetime' | |||
|
25 | 25 | from weakref import WeakValueDictionary |
|
26 | 26 | |
|
27 | 27 | from IPython.utils.importstring import import_item |
|
28 | from IPython.utils.ipstruct import Struct | |
|
28 | from IPython.config.loader import Config | |
|
29 | 29 | from IPython.utils.traitlets import ( |
|
30 | 30 | HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This |
|
31 | 31 | ) |
@@ -187,7 +187,7 b' class Component(HasTraitlets):' | |||
|
187 | 187 | __metaclass__ = MetaComponent |
|
188 | 188 | |
|
189 | 189 | # Traitlets are fun! |
|
190 |
config = Instance( |
|
|
190 | config = Instance(Config,(),{}) | |
|
191 | 191 | parent = This() |
|
192 | 192 | root = This() |
|
193 | 193 | created = None |
@@ -203,7 +203,7 b' class Component(HasTraitlets):' | |||
|
203 | 203 | name : str |
|
204 | 204 | The unique name of the component. If empty, then a unique |
|
205 | 205 | one will be autogenerated. |
|
206 |
config : |
|
|
206 | config : Config | |
|
207 | 207 | If this is empty, self.config = parent.config, otherwise |
|
208 | 208 | self.config = config and root.config is ignored. This argument |
|
209 | 209 | should only be used to *override* the automatic inheritance of |
@@ -274,11 +274,16 b' class Component(HasTraitlets):' | |||
|
274 | 274 | In the future, we might want to do a pop here so stale config info |
|
275 | 275 | is not passed onto children. |
|
276 | 276 | """ |
|
277 |
# Get all traitlets with a config |
|
|
278 |
traitlets = self.traitlets( |
|
|
277 | # Get all traitlets with a config metadata entry that is True | |
|
278 | traitlets = self.traitlets(config=True) | |
|
279 | ||
|
280 | # Don't do a blind getattr as that would cause the config to | |
|
281 | # dynamically create the section with name self.__class__.__name__. | |
|
282 | if new._has_section(self.__class__.__name__): | |
|
283 | my_config = new[self.__class__.__name__] | |
|
279 | 284 | for k, v in traitlets.items(): |
|
280 | 285 | try: |
|
281 |
config_value = |
|
|
286 | config_value = my_config[k] | |
|
282 | 287 | except KeyError: |
|
283 | 288 | pass |
|
284 | 289 | else: |
@@ -40,9 +40,11 b' class DisplayTrap(Component):' | |||
|
40 | 40 | |
|
41 | 41 | def __init__(self, parent, hook): |
|
42 | 42 | super(DisplayTrap, self).__init__(parent, None, None) |
|
43 | ||
|
44 | 43 | self.hook = hook |
|
45 | 44 | self.old_hook = None |
|
45 | # We define this to track if a single BuiltinTrap is nested. | |
|
46 | # Only turn off the trap when the outermost call to __exit__ is made. | |
|
47 | self._nested_level = 0 | |
|
46 | 48 | |
|
47 | 49 | @auto_attr |
|
48 | 50 | def shell(self): |
@@ -53,11 +55,15 b' class DisplayTrap(Component):' | |||
|
53 | 55 | return shell |
|
54 | 56 | |
|
55 | 57 | def __enter__(self): |
|
58 | if self._nested_level == 0: | |
|
56 | 59 | self.set() |
|
60 | self._nested_level += 1 | |
|
57 | 61 | return self |
|
58 | 62 | |
|
59 | 63 | def __exit__(self, type, value, traceback): |
|
64 | if self._nested_level == 1: | |
|
60 | 65 | self.unset() |
|
66 | self._nested_level -= 1 | |
|
61 | 67 | return True |
|
62 | 68 | |
|
63 | 69 | def set(self): |
@@ -30,10 +30,12 b' from contextlib import nested' | |||
|
30 | 30 | |
|
31 | 31 | from IPython.core import ultratb |
|
32 | 32 | from IPython.core.iplib import InteractiveShell |
|
33 | from IPython.core.ipapp import load_default_config | |
|
33 | 34 | |
|
34 | 35 | from IPython.utils.traitlets import Bool, Str, CBool |
|
35 | 36 | from IPython.utils.genutils import ask_yes_no |
|
36 | 37 | |
|
38 | ||
|
37 | 39 | #----------------------------------------------------------------------------- |
|
38 | 40 | # Classes and functions |
|
39 | 41 | #----------------------------------------------------------------------------- |
@@ -260,6 +262,8 b" def embed(header='', config=None, usage=None, banner1=None, banner2=None," | |||
|
260 | 262 | Full customization can be done by passing a :class:`Struct` in as the |
|
261 | 263 | config argument. |
|
262 | 264 | """ |
|
265 | if config is None: | |
|
266 | config = load_default_config() | |
|
263 | 267 | global _embedded_shell |
|
264 | 268 | if _embedded_shell is None: |
|
265 | 269 | _embedded_shell = InteractiveShellEmbed(config=config, |
@@ -27,13 +27,17 b' import os' | |||
|
27 | 27 | import sys |
|
28 | 28 | import warnings |
|
29 | 29 | |
|
30 | from IPython.core.application import Application | |
|
30 | from IPython.core.application import Application, IPythonArgParseConfigLoader | |
|
31 | 31 | from IPython.core import release |
|
32 | 32 | from IPython.core.iplib import InteractiveShell |
|
33 |
from IPython.config.loader import |
|
|
33 | from IPython.config.loader import ( | |
|
34 | NoConfigDefault, | |
|
35 | Config, | |
|
36 | PyFileConfigLoader | |
|
37 | ) | |
|
34 | 38 | |
|
35 | 39 | from IPython.utils.ipstruct import Struct |
|
36 | ||
|
40 | from IPython.utils.genutils import get_ipython_dir | |
|
37 | 41 | |
|
38 | 42 | #----------------------------------------------------------------------------- |
|
39 | 43 | # Utilities and helpers |
@@ -62,172 +66,187 b' deprecated. See the %gui magic for information on the new interface.' | |||
|
62 | 66 | |
|
63 | 67 | cl_args = ( |
|
64 | 68 | (('-autocall',), dict( |
|
65 |
type=int, dest=' |
|
|
66 |
help='Set the autocall value (0,1,2).' |
|
|
69 | type=int, dest='InteractiveShell.autocall', default=NoConfigDefault, | |
|
70 | help='Set the autocall value (0,1,2).', | |
|
71 | metavar='InteractiveShell.autocall') | |
|
67 | 72 | ), |
|
68 | 73 | (('-autoindent',), dict( |
|
69 |
action='store_true', dest=' |
|
|
74 | action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault, | |
|
70 | 75 | help='Turn on autoindenting.') |
|
71 | 76 | ), |
|
72 | 77 | (('-noautoindent',), dict( |
|
73 |
action='store_false', dest=' |
|
|
78 | action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault, | |
|
74 | 79 | help='Turn off autoindenting.') |
|
75 | 80 | ), |
|
76 | 81 | (('-automagic',), dict( |
|
77 |
action='store_true', dest=' |
|
|
82 | action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault, | |
|
78 | 83 | help='Turn on the auto calling of magic commands.') |
|
79 | 84 | ), |
|
80 | 85 | (('-noautomagic',), dict( |
|
81 |
action='store_false', dest=' |
|
|
86 | action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault, | |
|
82 | 87 | help='Turn off the auto calling of magic commands.') |
|
83 | 88 | ), |
|
84 | 89 | (('-autoedit_syntax',), dict( |
|
85 |
action='store_true', dest=' |
|
|
90 | action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault, | |
|
86 | 91 | help='Turn on auto editing of files with syntax errors.') |
|
87 | 92 | ), |
|
88 | 93 | (('-noautoedit_syntax',), dict( |
|
89 |
action='store_false', dest=' |
|
|
94 | action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault, | |
|
90 | 95 | help='Turn off auto editing of files with syntax errors.') |
|
91 | 96 | ), |
|
92 | 97 | (('-banner',), dict( |
|
93 |
action='store_true', dest=' |
|
|
98 | action='store_true', dest='InteractiveShell.display_banner', default=NoConfigDefault, | |
|
94 | 99 | help='Display a banner upon starting IPython.') |
|
95 | 100 | ), |
|
96 | 101 | (('-nobanner',), dict( |
|
97 |
action='store_false', dest=' |
|
|
102 | action='store_false', dest='InteractiveShell.display_banner', default=NoConfigDefault, | |
|
98 | 103 | help="Don't display a banner upon starting IPython.") |
|
99 | 104 | ), |
|
100 | 105 | (('-c',), dict( |
|
101 |
type=str, dest=' |
|
|
102 |
help="Execute |
|
|
106 | type=str, dest='InteractiveShell.c', default=NoConfigDefault, | |
|
107 | help="Execute the given command string.", | |
|
108 | metavar='InteractiveShell.c') | |
|
103 | 109 | ), |
|
104 | 110 | (('-cache_size',), dict( |
|
105 |
type=int, dest=' |
|
|
106 |
help="Set the size of the output cache." |
|
|
111 | type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault, | |
|
112 | help="Set the size of the output cache.", | |
|
113 | metavar='InteractiveShell.cache_size') | |
|
107 | 114 | ), |
|
108 | 115 | (('-classic',), dict( |
|
109 |
action='store_true', dest=' |
|
|
116 | action='store_true', dest='Global.classic', default=NoConfigDefault, | |
|
110 | 117 | help="Gives IPython a similar feel to the classic Python prompt.") |
|
111 | 118 | ), |
|
112 | 119 | (('-colors',), dict( |
|
113 |
type=str, dest=' |
|
|
114 |
help="Set the color scheme (NoColor, Linux, and LightBG)." |
|
|
120 | type=str, dest='InteractiveShell.colors', default=NoConfigDefault, | |
|
121 | help="Set the color scheme (NoColor, Linux, and LightBG).", | |
|
122 | metavar='InteractiveShell.colors') | |
|
115 | 123 | ), |
|
116 | 124 | (('-color_info',), dict( |
|
117 |
action='store_true', dest=' |
|
|
125 | action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault, | |
|
118 | 126 | help="Enable using colors for info related things.") |
|
119 | 127 | ), |
|
120 | 128 | (('-nocolor_info',), dict( |
|
121 |
action='store_false', dest=' |
|
|
129 | action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault, | |
|
122 | 130 | help="Disable using colors for info related things.") |
|
123 | 131 | ), |
|
124 | 132 | (('-confirm_exit',), dict( |
|
125 |
action='store_true', dest=' |
|
|
133 | action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault, | |
|
126 | 134 | help="Prompt the user when existing.") |
|
127 | 135 | ), |
|
128 | 136 | (('-noconfirm_exit',), dict( |
|
129 |
action='store_false', dest=' |
|
|
137 | action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault, | |
|
130 | 138 | help="Don't prompt the user when existing.") |
|
131 | 139 | ), |
|
132 | 140 | (('-deep_reload',), dict( |
|
133 |
action='store_true', dest=' |
|
|
141 | action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault, | |
|
134 | 142 | help="Enable deep (recursive) reloading by default.") |
|
135 | 143 | ), |
|
136 | 144 | (('-nodeep_reload',), dict( |
|
137 |
action='store_false', dest=' |
|
|
145 | action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault, | |
|
138 | 146 | help="Disable deep (recursive) reloading by default.") |
|
139 | 147 | ), |
|
140 | 148 | (('-editor',), dict( |
|
141 |
type=str, dest=' |
|
|
142 |
help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." |
|
|
149 | type=str, dest='InteractiveShell.editor', default=NoConfigDefault, | |
|
150 | help="Set the editor used by IPython (default to $EDITOR/vi/notepad).", | |
|
151 | metavar='InteractiveShell.editor') | |
|
143 | 152 | ), |
|
144 | 153 | (('-log','-l'), dict( |
|
145 |
action='store_true', dest=' |
|
|
154 | action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault, | |
|
146 | 155 | help="Start logging to the default file (./ipython_log.py).") |
|
147 | 156 | ), |
|
148 | 157 | (('-logfile','-lf'), dict( |
|
149 |
type=str, dest=' |
|
|
150 |
help="Specify the name of your logfile." |
|
|
158 | type=str, dest='InteractiveShell.logfile', default=NoConfigDefault, | |
|
159 | help="Specify the name of your logfile.", | |
|
160 | metavar='InteractiveShell.logfile') | |
|
151 | 161 | ), |
|
152 | 162 | (('-logplay','-lp'), dict( |
|
153 |
type=str, dest=' |
|
|
154 |
help="Re-play a log file and then append to it." |
|
|
163 | type=str, dest='InteractiveShell.logplay', default=NoConfigDefault, | |
|
164 | help="Re-play a log file and then append to it.", | |
|
165 | metavar='InteractiveShell.logplay') | |
|
155 | 166 | ), |
|
156 | 167 | (('-pdb',), dict( |
|
157 |
action='store_true', dest=' |
|
|
168 | action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault, | |
|
158 | 169 | help="Enable auto calling the pdb debugger after every exception.") |
|
159 | 170 | ), |
|
160 | 171 | (('-nopdb',), dict( |
|
161 |
action='store_false', dest=' |
|
|
172 | action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault, | |
|
162 | 173 | help="Disable auto calling the pdb debugger after every exception.") |
|
163 | 174 | ), |
|
164 | 175 | (('-pprint',), dict( |
|
165 |
action='store_true', dest=' |
|
|
176 | action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault, | |
|
166 | 177 | help="Enable auto pretty printing of results.") |
|
167 | 178 | ), |
|
168 | 179 | (('-nopprint',), dict( |
|
169 |
action='store_false', dest=' |
|
|
180 | action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault, | |
|
170 | 181 | help="Disable auto auto pretty printing of results.") |
|
171 | 182 | ), |
|
172 | 183 | (('-prompt_in1','-pi1'), dict( |
|
173 |
type=str, dest=' |
|
|
174 |
help="Set the main input prompt ('In [\#]: ')" |
|
|
184 | type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault, | |
|
185 | help="Set the main input prompt ('In [\#]: ')", | |
|
186 | metavar='InteractiveShell.prompt_in1') | |
|
175 | 187 | ), |
|
176 | 188 | (('-prompt_in2','-pi2'), dict( |
|
177 |
type=str, dest=' |
|
|
178 |
help="Set the secondary input prompt (' .\D.: ')" |
|
|
189 | type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault, | |
|
190 | help="Set the secondary input prompt (' .\D.: ')", | |
|
191 | metavar='InteractiveShell.prompt_in2') | |
|
179 | 192 | ), |
|
180 | 193 | (('-prompt_out','-po'), dict( |
|
181 |
type=str, dest=' |
|
|
182 |
help="Set the output prompt ('Out[\#]:')" |
|
|
194 | type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault, | |
|
195 | help="Set the output prompt ('Out[\#]:')", | |
|
196 | metavar='InteractiveShell.prompt_out') | |
|
183 | 197 | ), |
|
184 | 198 | (('-quick',), dict( |
|
185 |
action='store_true', dest=' |
|
|
199 | action='store_true', dest='Global.quick', default=NoConfigDefault, | |
|
186 | 200 | help="Enable quick startup with no config files.") |
|
187 | 201 | ), |
|
188 | 202 | (('-readline',), dict( |
|
189 |
action='store_true', dest=' |
|
|
203 | action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault, | |
|
190 | 204 | help="Enable readline for command line usage.") |
|
191 | 205 | ), |
|
192 | 206 | (('-noreadline',), dict( |
|
193 |
action='store_false', dest=' |
|
|
207 | action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault, | |
|
194 | 208 | help="Disable readline for command line usage.") |
|
195 | 209 | ), |
|
196 | 210 | (('-screen_length','-sl'), dict( |
|
197 |
type=int, dest=' |
|
|
198 |
help='Number of lines on screen, used to control printing of long strings.' |
|
|
211 | type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault, | |
|
212 | help='Number of lines on screen, used to control printing of long strings.', | |
|
213 | metavar='InteractiveShell.screen_length') | |
|
199 | 214 | ), |
|
200 | 215 | (('-separate_in','-si'), dict( |
|
201 |
type=str, dest=' |
|
|
202 |
help="Separator before input prompts. Default '\n'." |
|
|
216 | type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault, | |
|
217 | help="Separator before input prompts. Default '\n'.", | |
|
218 | metavar='InteractiveShell.separate_in') | |
|
203 | 219 | ), |
|
204 | 220 | (('-separate_out','-so'), dict( |
|
205 |
type=str, dest=' |
|
|
206 |
help="Separator before output prompts. Default 0 (nothing)." |
|
|
221 | type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault, | |
|
222 | help="Separator before output prompts. Default 0 (nothing).", | |
|
223 | metavar='InteractiveShell.separate_out') | |
|
207 | 224 | ), |
|
208 | 225 | (('-separate_out2','-so2'), dict( |
|
209 |
type=str, dest=' |
|
|
210 |
help="Separator after output prompts. Default 0 (nonight)." |
|
|
226 | type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault, | |
|
227 | help="Separator after output prompts. Default 0 (nonight).", | |
|
228 | metavar='InteractiveShell.separate_out2') | |
|
211 | 229 | ), |
|
212 | 230 | (('-nosep',), dict( |
|
213 |
action='store_true', dest=' |
|
|
231 | action='store_true', dest='Global.nosep', default=NoConfigDefault, | |
|
214 | 232 | help="Eliminate all spacing between prompts.") |
|
215 | 233 | ), |
|
216 | 234 | (('-term_title',), dict( |
|
217 |
action='store_true', dest=' |
|
|
235 | action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault, | |
|
218 | 236 | help="Enable auto setting the terminal title.") |
|
219 | 237 | ), |
|
220 | 238 | (('-noterm_title',), dict( |
|
221 |
action='store_false', dest=' |
|
|
239 | action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault, | |
|
222 | 240 | help="Disable auto setting the terminal title.") |
|
223 | 241 | ), |
|
224 | 242 | (('-xmode',), dict( |
|
225 |
type=str, dest=' |
|
|
226 |
help="Exception mode ('Plain','Context','Verbose')" |
|
|
243 | type=str, dest='InteractiveShell.xmode', default=NoConfigDefault, | |
|
244 | help="Exception mode ('Plain','Context','Verbose')", | |
|
245 | metavar='InteractiveShell.xmode') | |
|
227 | 246 | ), |
|
228 | 247 | # These are only here to get the proper deprecation warnings |
|
229 | 248 | (('-pylab','-wthread','-qthread','-q4thread','-gthread'), dict( |
|
230 |
action='store_true', dest=' |
|
|
249 | action='store_true', dest='Global.threaded_shell', default=NoConfigDefault, | |
|
231 | 250 | help="These command line flags are deprecated, see the 'gui' magic.") |
|
232 | 251 | ), |
|
233 | 252 | ) |
@@ -238,9 +257,11 b' class IPythonAppCLConfigLoader(IPythonArgParseConfigLoader):' | |||
|
238 | 257 | arguments = cl_args |
|
239 | 258 | |
|
240 | 259 | |
|
260 | _default_config_file_name = 'ipython_config.py' | |
|
261 | ||
|
241 | 262 | class IPythonApp(Application): |
|
242 | 263 | name = 'ipython' |
|
243 |
config_file_name = |
|
|
264 | config_file_name = _default_config_file_name | |
|
244 | 265 | |
|
245 | 266 | def create_command_line_config(self): |
|
246 | 267 | """Create and return a command line config loader.""" |
@@ -252,19 +273,15 b' class IPythonApp(Application):' | |||
|
252 | 273 | """Do actions after loading cl config.""" |
|
253 | 274 | clc = self.command_line_config |
|
254 | 275 | |
|
255 | # This needs to be set here, the rest are set in pre_construct. | |
|
256 | if hasattr(clc, 'CLASSIC'): | |
|
257 | if clc.CLASSIC: clc.QUICK = 1 | |
|
258 | ||
|
259 | 276 | # Display the deprecation warnings about threaded shells |
|
260 |
if hasattr(clc, ' |
|
|
277 | if hasattr(clc.Global, 'threaded_shell'): | |
|
261 | 278 | threaded_shell_warning() |
|
262 | del clc['THREADED_SHELL'] | |
|
279 | del clc.Global['threaded_shell'] | |
|
263 | 280 | |
|
264 | 281 | def load_file_config(self): |
|
265 |
if hasattr(self.command_line_config, ' |
|
|
266 |
if self.command_line_config. |
|
|
267 |
self.file_config = |
|
|
282 | if hasattr(self.command_line_config.Global, 'quick'): | |
|
283 | if self.command_line_config.Global.quick: | |
|
284 | self.file_config = Config() | |
|
268 | 285 | return |
|
269 | 286 | super(IPythonApp, self).load_file_config() |
|
270 | 287 | |
@@ -274,25 +291,28 b' class IPythonApp(Application):' | |||
|
274 | 291 | def pre_construct(self): |
|
275 | 292 | config = self.master_config |
|
276 | 293 | |
|
277 |
if hasattr(config, ' |
|
|
278 |
if config. |
|
|
279 |
config. |
|
|
280 |
config. |
|
|
281 | config.PPRINT = 0 | |
|
282 | config.PROMPT_IN1 = '>>> ' | |
|
283 | config.PROMPT_IN2 = '... ' | |
|
284 | config.PROMPT_OUT = '' | |
|
285 | config.SEPARATE_IN = config.SEPARATE_OUT = config.SEPARATE_OUT2 = '' | |
|
286 | config.COLORS = 'NoColor' | |
|
287 |
config. |
|
|
294 | if hasattr(config.Global, 'classic'): | |
|
295 | if config.Global.classic: | |
|
296 | config.InteractiveShell.cache_size = 0 | |
|
297 | config.InteractiveShell.pprint = 0 | |
|
298 | config.InteractiveShell.prompt_in1 = '>>> ' | |
|
299 | config.InteractiveShell.prompt_in2 = '... ' | |
|
300 | config.InteractiveShell.prompt_out = '' | |
|
301 | config.InteractiveShell.separate_in = \ | |
|
302 | config.InteractiveShell.separate_out = \ | |
|
303 | config.InteractiveShell.separate_out2 = '' | |
|
304 | config.InteractiveShell.colors = 'NoColor' | |
|
305 | config.InteractiveShell.xmode = 'Plain' | |
|
288 | 306 | |
|
289 | 307 | # All this should be moved to traitlet handlers in InteractiveShell |
|
290 | 308 | # But, currently InteractiveShell doesn't have support for changing |
|
291 | 309 | # these values at runtime. Once we support that, this should |
|
292 | 310 | # be moved there!!! |
|
293 |
if hasattr(config, ' |
|
|
294 |
if config. |
|
|
295 | config.SEPARATE_IN = config.SEPARATE_OUT = config.SEPARATE_OUT2 = '0' | |
|
311 | if hasattr(config.Global, 'nosep'): | |
|
312 | if config.Global.nosep: | |
|
313 | config.InteractiveShell.separate_in = \ | |
|
314 | config.InteractiveShell.separate_out = \ | |
|
315 | config.InteractiveShell.separate_out2 = '0' | |
|
296 | 316 | |
|
297 | 317 | def construct(self): |
|
298 | 318 | # I am a little hesitant to put these into InteractiveShell itself. |
@@ -307,12 +327,23 b' class IPythonApp(Application):' | |||
|
307 | 327 | parent=None, |
|
308 | 328 | config=self.master_config |
|
309 | 329 | ) |
|
310 | print self.shell | |
|
311 | 330 | |
|
312 | 331 | def start_app(self): |
|
313 | 332 | self.shell.mainloop() |
|
314 | 333 | |
|
315 | 334 | |
|
335 | def load_default_config(ipythondir=None): | |
|
336 | """Load the default config file from the default ipythondir. | |
|
337 | ||
|
338 | This is useful for embedded shells. | |
|
339 | """ | |
|
340 | if ipythondir is None: | |
|
341 | ipythondir = get_ipython_dir() | |
|
342 | cl = PyFileConfigLoader(_default_config_file_name, ipythondir) | |
|
343 | config = cl.load_config() | |
|
344 | return config | |
|
345 | ||
|
346 | ||
|
316 | 347 | if __name__ == '__main__': |
|
317 | 348 | app = IPythonApp() |
|
318 | 349 | app.start() No newline at end of file |
@@ -62,6 +62,7 b' from IPython.lib.backgroundjobs import BackgroundJobManager' | |||
|
62 | 62 | from IPython.utils.ipstruct import Struct |
|
63 | 63 | from IPython.utils import PyColorize |
|
64 | 64 | from IPython.utils.genutils import * |
|
65 | from IPython.utils.genutils import get_ipython_dir | |
|
65 | 66 | from IPython.utils.strdispatch import StrDispatch |
|
66 | 67 | from IPython.utils.platutils import toggle_set_term_title, set_term_title |
|
67 | 68 | |
@@ -188,50 +189,47 b' class SeparateStr(Str):' | |||
|
188 | 189 | class InteractiveShell(Component, Magic): |
|
189 | 190 | """An enhanced, interactive shell for Python.""" |
|
190 | 191 | |
|
191 |
autocall = Enum((0,1,2), config |
|
|
192 |
autoedit_syntax = CBool(False, config |
|
|
193 |
autoindent = CBool(True, config |
|
|
194 |
automagic = CBool(True, config |
|
|
195 |
display_banner = CBool(True, config |
|
|
192 | autocall = Enum((0,1,2), config=True) | |
|
193 | autoedit_syntax = CBool(False, config=True) | |
|
194 | autoindent = CBool(True, config=True) | |
|
195 | automagic = CBool(True, config=True) | |
|
196 | display_banner = CBool(True, config=True) | |
|
196 | 197 | banner = Str('') |
|
197 |
banner1 = Str(default_banner, config |
|
|
198 |
banner2 = Str('', config |
|
|
199 |
c = Str('', config |
|
|
200 |
cache_size = Int(1000, config |
|
|
201 |
c |
|
|
202 | color_info = CBool(True, config_key='COLOR_INFO') | |
|
198 | banner1 = Str(default_banner, config=True) | |
|
199 | banner2 = Str('', config=True) | |
|
200 | c = Str('', config=True) | |
|
201 | cache_size = Int(1000, config=True) | |
|
202 | color_info = CBool(True, config=True) | |
|
203 | 203 | colors = CaselessStrEnum(('NoColor','LightBG','Linux'), |
|
204 |
default_value='LightBG', config |
|
|
205 |
confirm_exit = CBool(True, config |
|
|
206 |
debug = CBool(False, config |
|
|
207 |
deep_reload = CBool(False, config |
|
|
204 | default_value='LightBG', config=True) | |
|
205 | confirm_exit = CBool(True, config=True) | |
|
206 | debug = CBool(False, config=True) | |
|
207 | deep_reload = CBool(False, config=True) | |
|
208 | 208 | embedded = CBool(False) |
|
209 | 209 | embedded_active = CBool(False) |
|
210 |
editor = Str(get_default_editor(), config |
|
|
210 | editor = Str(get_default_editor(), config=True) | |
|
211 | 211 | filename = Str("<ipython console>") |
|
212 |
interactive = CBool(False, config |
|
|
213 |
ipythondir= Unicode('', config |
|
|
214 |
logstart = CBool(False, config |
|
|
215 |
logfile = Str('', config |
|
|
216 |
logplay = Str('', config |
|
|
212 | interactive = CBool(False, config=True) | |
|
213 | ipythondir= Unicode('', config=True) # Set to get_ipython_dir() in __init__ | |
|
214 | logstart = CBool(False, config=True) | |
|
215 | logfile = Str('', config=True) | |
|
216 | logplay = Str('', config=True) | |
|
217 | 217 | object_info_string_level = Enum((0,1,2), default_value=0, |
|
218 |
config |
|
|
219 |
pager = Str('less', config |
|
|
220 |
pdb = CBool(False, config |
|
|
221 |
pprint = CBool(True, config |
|
|
222 |
profile = Str('', config |
|
|
223 |
prompt_in1 = Str('In [\\#]: ', config |
|
|
224 |
prompt_in2 = Str(' .\\D.: ', config |
|
|
225 |
prompt_out = Str('Out[\\#]: ', config |
|
|
226 |
prompts_pad_left = CBool(True, config |
|
|
227 |
quiet = CBool(False, config |
|
|
228 | ||
|
229 |
readline_use = CBool(True, config |
|
|
230 | readline_merge_completions = CBool(True, | |
|
231 | config_key='READLINE_MERGE_COMPLETIONS') | |
|
232 | readline_omit__names = Enum((0,1,2), default_value=0, | |
|
233 | config_key='READLINE_OMIT_NAMES') | |
|
234 | readline_remove_delims = Str('-/~', config_key='READLINE_REMOVE_DELIMS') | |
|
218 | config=True) | |
|
219 | pager = Str('less', config=True) | |
|
220 | pdb = CBool(False, config=True) | |
|
221 | pprint = CBool(True, config=True) | |
|
222 | profile = Str('', config=True) | |
|
223 | prompt_in1 = Str('In [\\#]: ', config=True) | |
|
224 | prompt_in2 = Str(' .\\D.: ', config=True) | |
|
225 | prompt_out = Str('Out[\\#]: ', config=True) | |
|
226 | prompts_pad_left = CBool(True, config=True) | |
|
227 | quiet = CBool(False, config=True) | |
|
228 | ||
|
229 | readline_use = CBool(True, config=True) | |
|
230 | readline_merge_completions = CBool(True, config=True) | |
|
231 | readline_omit__names = Enum((0,1,2), default_value=0, config=True) | |
|
232 | readline_remove_delims = Str('-/~', config=True) | |
|
235 | 233 | readline_parse_and_bind = List([ |
|
236 | 234 | 'tab: complete', |
|
237 | 235 | '"\C-l": possible-completions', |
@@ -248,24 +246,22 b' class InteractiveShell(Component, Magic):' | |||
|
248 | 246 | '"\e[B": history-search-forward', |
|
249 | 247 | '"\C-k": kill-line', |
|
250 | 248 | '"\C-u": unix-line-discard', |
|
251 |
], allow_none=False, config |
|
|
252 | ) | |
|
249 | ], allow_none=False, config=True) | |
|
253 | 250 | |
|
254 |
screen_length = Int(0, config |
|
|
251 | screen_length = Int(0, config=True) | |
|
255 | 252 | |
|
256 | 253 | # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n' |
|
257 |
separate_in = SeparateStr('\n', config |
|
|
258 |
separate_out = SeparateStr('', config |
|
|
259 |
separate_out2 = SeparateStr('', config |
|
|
260 | ||
|
261 |
system_header = Str('IPython system call: ', config |
|
|
262 |
system_verbose = CBool(False, config |
|
|
263 |
term_title = CBool(False, config |
|
|
264 |
wildcards_case_sensitive = CBool(True, config |
|
|
254 | separate_in = SeparateStr('\n', config=True) | |
|
255 | separate_out = SeparateStr('', config=True) | |
|
256 | separate_out2 = SeparateStr('', config=True) | |
|
257 | ||
|
258 | system_header = Str('IPython system call: ', config=True) | |
|
259 | system_verbose = CBool(False, config=True) | |
|
260 | term_title = CBool(False, config=True) | |
|
261 | wildcards_case_sensitive = CBool(True, config=True) | |
|
265 | 262 | xmode = CaselessStrEnum(('Context','Plain', 'Verbose'), |
|
266 |
default_value='Context', config |
|
|
263 | default_value='Context', config=True) | |
|
267 | 264 | |
|
268 | alias = List(allow_none=False, config_key='ALIAS') | |
|
269 | 265 | autoexec = List(allow_none=False) |
|
270 | 266 | |
|
271 | 267 | # class attribute to indicate whether the class supports threads or not. |
@@ -279,7 +275,7 b' class InteractiveShell(Component, Magic):' | |||
|
279 | 275 | |
|
280 | 276 | # This is where traitlets with a config_key argument are updated |
|
281 | 277 | # from the values on config. |
|
282 |
super(InteractiveShell, self).__init__(parent, config=config |
|
|
278 | super(InteractiveShell, self).__init__(parent, config=config) | |
|
283 | 279 | |
|
284 | 280 | # These are relatively independent and stateless |
|
285 | 281 | self.init_ipythondir(ipythondir) |
@@ -288,7 +284,7 b' class InteractiveShell(Component, Magic):' | |||
|
288 | 284 | self.init_usage(usage) |
|
289 | 285 | self.init_banner(banner1, banner2) |
|
290 | 286 | |
|
291 |
# Create namespaces (user_ns, user_global_ns, |
|
|
287 | # Create namespaces (user_ns, user_global_ns, etc.) | |
|
292 | 288 | self.init_create_namespaces(user_ns, user_global_ns) |
|
293 | 289 | # This has to be done after init_create_namespaces because it uses |
|
294 | 290 | # something in self.user_ns, but before init_sys_modules, which |
@@ -327,6 +323,9 b' class InteractiveShell(Component, Magic):' | |||
|
327 | 323 | self.init_pdb() |
|
328 | 324 | self.hooks.late_startup_hook() |
|
329 | 325 | |
|
326 | def get_ipython(self): | |
|
327 | return self | |
|
328 | ||
|
330 | 329 | #------------------------------------------------------------------------- |
|
331 | 330 | # Traitlet changed handlers |
|
332 | 331 | #------------------------------------------------------------------------- |
@@ -337,6 +336,10 b' class InteractiveShell(Component, Magic):' | |||
|
337 | 336 | def _banner2_changed(self): |
|
338 | 337 | self.compute_banner() |
|
339 | 338 | |
|
339 | def _ipythondir_changed(self, name, new): | |
|
340 | if not os.path.isdir(new): | |
|
341 | os.makedirs(new, mode = 0777) | |
|
342 | ||
|
340 | 343 | @property |
|
341 | 344 | def usable_screen_length(self): |
|
342 | 345 | if self.screen_length == 0: |
@@ -370,22 +373,16 b' class InteractiveShell(Component, Magic):' | |||
|
370 | 373 | def init_ipythondir(self, ipythondir): |
|
371 | 374 | if ipythondir is not None: |
|
372 | 375 | self.ipythondir = ipythondir |
|
373 |
self.config. |
|
|
376 | self.config.Global.ipythondir = self.ipythondir | |
|
374 | 377 | return |
|
375 | 378 | |
|
376 |
if hasattr(self.config, ' |
|
|
377 |
self.ipythondir = self.config. |
|
|
378 | if not hasattr(self.config, 'IPYTHONDIR'): | |
|
379 | # cdw is always defined | |
|
380 | self.ipythondir = os.getcwd() | |
|
381 | ||
|
382 | # The caller must make sure that ipythondir exists. We should | |
|
383 | # probably handle this using a Dir traitlet. | |
|
384 | if not os.path.isdir(self.ipythondir): | |
|
385 | raise IOError('IPython dir does not exist: %s' % self.ipythondir) | |
|
379 | if hasattr(self.config.Global, 'ipythondir'): | |
|
380 | self.ipythondir = self.config.Global.ipythondir | |
|
381 | else: | |
|
382 | self.ipythondir = get_ipython_dir() | |
|
386 | 383 | |
|
387 | 384 | # All children can just read this |
|
388 |
self.config. |
|
|
385 | self.config.Global.ipythondir = self.ipythondir | |
|
389 | 386 | |
|
390 | 387 | def init_instance_attrs(self): |
|
391 | 388 | self.jobs = BackgroundJobManager() |
@@ -825,11 +822,6 b' class InteractiveShell(Component, Magic):' | |||
|
825 | 822 | # them from cluttering user-visible stuff. Will be updated later |
|
826 | 823 | self.internal_ns = {} |
|
827 | 824 | |
|
828 | # Namespace of system aliases. Each entry in the alias | |
|
829 | # table must be a 2-tuple of the form (N,name), where N is the number | |
|
830 | # of positional arguments of the alias. | |
|
831 | self.alias_table = {} | |
|
832 | ||
|
833 | 825 | # Now that FakeModule produces a real module, we've run into a nasty |
|
834 | 826 | # problem: after script execution (via %run), the module where the user |
|
835 | 827 | # code ran is deleted. Now that this object is a true module (needed |
@@ -863,7 +855,6 b' class InteractiveShell(Component, Magic):' | |||
|
863 | 855 | # introspection facilities can search easily. |
|
864 | 856 | self.ns_table = {'user':user_ns, |
|
865 | 857 | 'user_global':user_global_ns, |
|
866 | 'alias':self.alias_table, | |
|
867 | 858 | 'internal':self.internal_ns, |
|
868 | 859 | 'builtin':__builtin__.__dict__ |
|
869 | 860 | } |
@@ -872,8 +863,7 b' class InteractiveShell(Component, Magic):' | |||
|
872 | 863 | # we can safely clear (so it can NOT include builtin). This one can be |
|
873 | 864 | # a simple list. |
|
874 | 865 | self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns, |
|
875 |
self. |
|
|
876 | self._main_ns_cache ] | |
|
866 | self.internal_ns, self._main_ns_cache ] | |
|
877 | 867 | |
|
878 | 868 | def init_sys_modules(self): |
|
879 | 869 | # We need to insert into sys.modules something that looks like a |
@@ -961,11 +951,8 b' class InteractiveShell(Component, Magic):' | |||
|
961 | 951 | method. If they were not empty before, data will simply be added to |
|
962 | 952 | therm. |
|
963 | 953 | """ |
|
964 | # The user namespace MUST have a pointer to the shell itself. | |
|
965 | self.user_ns[self.name] = self | |
|
966 | ||
|
967 | 954 | # Store myself as the public api!!! |
|
968 | self.user_ns['_ip'] = self | |
|
955 | self.user_ns['get_ipython'] = self.get_ipython | |
|
969 | 956 | |
|
970 | 957 | # make global variables for user access to the histories |
|
971 | 958 | self.user_ns['_ih'] = self.input_hist |
@@ -994,13 +981,19 b' class InteractiveShell(Component, Magic):' | |||
|
994 | 981 | for ns in self.ns_refs_table: |
|
995 | 982 | ns.clear() |
|
996 | 983 | |
|
984 | self.alias_manager.clear_aliases() | |
|
985 | ||
|
997 | 986 | # Clear input and output histories |
|
998 | 987 | self.input_hist[:] = [] |
|
999 | 988 | self.input_hist_raw[:] = [] |
|
1000 | 989 | self.output_hist.clear() |
|
990 | ||
|
1001 | 991 | # Restore the user namespaces to minimal usability |
|
1002 | 992 | self.init_user_ns() |
|
1003 | 993 | |
|
994 | # Restore the default and user aliases | |
|
995 | self.alias_manager.init_aliases() | |
|
996 | ||
|
1004 | 997 | def push(self, variables, interactive=True): |
|
1005 | 998 | """Inject a group of variables into the IPython user namespace. |
|
1006 | 999 | |
@@ -1076,7 +1069,7 b' class InteractiveShell(Component, Magic):' | |||
|
1076 | 1069 | histfname = 'history-%s' % self.profile |
|
1077 | 1070 | except AttributeError: |
|
1078 | 1071 | histfname = 'history' |
|
1079 |
self.histfile = os.path.join(self. |
|
|
1072 | self.histfile = os.path.join(self.ipythondir, histfname) | |
|
1080 | 1073 | |
|
1081 | 1074 | # Fill the history zero entry, user counter starts at 1 |
|
1082 | 1075 | self.input_hist.append('\n') |
@@ -1084,12 +1077,12 b' class InteractiveShell(Component, Magic):' | |||
|
1084 | 1077 | |
|
1085 | 1078 | def init_shadow_hist(self): |
|
1086 | 1079 | try: |
|
1087 |
self.db = pickleshare.PickleShareDB(self. |
|
|
1080 | self.db = pickleshare.PickleShareDB(self.ipythondir + "/db") | |
|
1088 | 1081 | except exceptions.UnicodeDecodeError: |
|
1089 | 1082 | print "Your ipythondir can't be decoded to unicode!" |
|
1090 | 1083 | print "Please set HOME environment variable to something that" |
|
1091 | 1084 | print r"only has ASCII characters, e.g. c:\home" |
|
1092 |
print "Now it is", self. |
|
|
1085 | print "Now it is", self.ipythondir | |
|
1093 | 1086 | sys.exit() |
|
1094 | 1087 | self.shadowhist = ipcorehist.ShadowHist(self.db) |
|
1095 | 1088 | |
@@ -1475,7 +1468,7 b' class InteractiveShell(Component, Magic):' | |||
|
1475 | 1468 |
|
|
1476 | 1469 |
|
|
1477 | 1470 |
|
|
1478 |
|
|
|
1471 | self.alias_manager.alias_table) | |
|
1479 | 1472 | sdisp = self.strdispatchers.get('complete_command', StrDispatch()) |
|
1480 | 1473 | self.strdispatchers['complete_command'] = sdisp |
|
1481 | 1474 | self.Completer.custom_completers = sdisp |
@@ -1607,8 +1600,11 b' class InteractiveShell(Component, Magic):' | |||
|
1607 | 1600 | error("Magic function `%s` not found." % magic_name) |
|
1608 | 1601 | else: |
|
1609 | 1602 | magic_args = self.var_expand(magic_args,1) |
|
1610 |
with nested(self.builtin_trap, |
|
|
1611 |
re |
|
|
1603 | with nested(self.builtin_trap,): | |
|
1604 | result = fn(magic_args) | |
|
1605 | # Unfortunately, the return statement is what will trigger | |
|
1606 | # the displayhook, but it is no longer set! | |
|
1607 | return result | |
|
1612 | 1608 | |
|
1613 | 1609 | def define_magic(self, magicname, func): |
|
1614 | 1610 | """Expose own function as magic function for ipython |
@@ -1666,6 +1662,7 b' class InteractiveShell(Component, Magic):' | |||
|
1666 | 1662 | |
|
1667 | 1663 | def init_alias(self): |
|
1668 | 1664 | self.alias_manager = AliasManager(self, config=self.config) |
|
1665 | self.ns_table['alias'] = self.alias_manager.alias_table, | |
|
1669 | 1666 | |
|
1670 | 1667 | #------------------------------------------------------------------------- |
|
1671 | 1668 | # Things related to the running of code |
@@ -1673,7 +1670,7 b' class InteractiveShell(Component, Magic):' | |||
|
1673 | 1670 | |
|
1674 | 1671 | def ex(self, cmd): |
|
1675 | 1672 | """Execute a normal python statement in user namespace.""" |
|
1676 |
with nested(self.builtin_trap, |
|
|
1673 | with nested(self.builtin_trap,): | |
|
1677 | 1674 | exec cmd in self.user_global_ns, self.user_ns |
|
1678 | 1675 | |
|
1679 | 1676 | def ev(self, expr): |
@@ -1681,7 +1678,7 b' class InteractiveShell(Component, Magic):' | |||
|
1681 | 1678 | |
|
1682 | 1679 | Returns the result of evaluation |
|
1683 | 1680 | """ |
|
1684 |
with nested(self.builtin_trap, |
|
|
1681 | with nested(self.builtin_trap,): | |
|
1685 | 1682 | return eval(expr, self.user_global_ns, self.user_ns) |
|
1686 | 1683 | |
|
1687 | 1684 | def mainloop(self, banner=None): |
@@ -47,6 +47,7 b' from IPython.utils import wildcard' | |||
|
47 | 47 | from IPython.core import debugger, oinspect |
|
48 | 48 | from IPython.core.error import TryNext |
|
49 | 49 | from IPython.core.fakemodule import FakeModule |
|
50 | from IPython.core.prefilter import ESC_MAGIC | |
|
50 | 51 | from IPython.external.Itpl import Itpl, itpl, printpl,itplns |
|
51 | 52 | from IPython.utils.PyColorize import Parser |
|
52 | 53 | from IPython.utils.ipstruct import Struct |
@@ -205,9 +206,9 b' python-profiler package from non-free.""")' | |||
|
205 | 206 | namespaces = [ ('Interactive', self.shell.user_ns), |
|
206 | 207 | ('IPython internal', self.shell.internal_ns), |
|
207 | 208 | ('Python builtin', __builtin__.__dict__), |
|
208 | ('Alias', self.shell.alias_table), | |
|
209 | ('Alias', self.shell.alias_manager.alias_table), | |
|
209 | 210 | ] |
|
210 | alias_ns = self.shell.alias_table | |
|
211 | alias_ns = self.shell.alias_manager.alias_table | |
|
211 | 212 | |
|
212 | 213 | # initialize results to 'null' |
|
213 | 214 | found = 0; obj = None; ospace = None; ds = None; |
@@ -244,7 +245,7 b' python-profiler package from non-free.""")' | |||
|
244 | 245 | |
|
245 | 246 | # Try to see if it's magic |
|
246 | 247 | if not found: |
|
247 |
if oname.startswith( |
|
|
248 | if oname.startswith(ESC_MAGIC): | |
|
248 | 249 | oname = oname[1:] |
|
249 | 250 | obj = getattr(self,'magic_'+oname,None) |
|
250 | 251 | if obj is not None: |
@@ -272,10 +273,10 b' python-profiler package from non-free.""")' | |||
|
272 | 273 | # Characters that need to be escaped for latex: |
|
273 | 274 | escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE) |
|
274 | 275 | # Magic command names as headers: |
|
275 |
cmd_name_re = re.compile(r'^(%s.*?):' % |
|
|
276 | cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC, | |
|
276 | 277 | re.MULTILINE) |
|
277 | 278 | # Magic commands |
|
278 |
cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % |
|
|
279 | cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC, | |
|
279 | 280 | re.MULTILINE) |
|
280 | 281 | # Paragraph continue |
|
281 | 282 | par_re = re.compile(r'\\$',re.MULTILINE) |
@@ -376,7 +377,7 b' python-profiler package from non-free.""")' | |||
|
376 | 377 | # Functions for IPython shell work (vars,funcs, config, etc) |
|
377 | 378 | def magic_lsmagic(self, parameter_s = ''): |
|
378 | 379 | """List currently available magic functions.""" |
|
379 |
mesc = |
|
|
380 | mesc = ESC_MAGIC | |
|
380 | 381 | print 'Available magic functions:\n'+mesc+\ |
|
381 | 382 | (' '+mesc).join(self.lsmagic()) |
|
382 | 383 | print '\n' + Magic.auto_status[self.shell.automagic] |
@@ -424,11 +425,11 b' python-profiler package from non-free.""")' | |||
|
424 | 425 | |
|
425 | 426 | |
|
426 | 427 | if mode == 'rest': |
|
427 |
rest_docs.append('**%s%s**::\n\n\t%s\n\n' %( |
|
|
428 | rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC, | |
|
428 | 429 | fname,fndoc)) |
|
429 | 430 | |
|
430 | 431 | else: |
|
431 |
magic_docs.append('%s%s:\n\t%s\n' %( |
|
|
432 | magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC, | |
|
432 | 433 | fname,fndoc)) |
|
433 | 434 | |
|
434 | 435 | magic_docs = ''.join(magic_docs) |
@@ -479,7 +480,7 b" of any of them, type %magic_name?, e.g. '%cd?'." | |||
|
479 | 480 | |
|
480 | 481 | Currently the magic system has the following functions:\n""" |
|
481 | 482 | |
|
482 |
mesc = |
|
|
483 | mesc = ESC_MAGIC | |
|
483 | 484 | outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):" |
|
484 | 485 | "\n\n%s%s\n\n%s" % (outmsg, |
|
485 | 486 | magic_docs,mesc,mesc, |
@@ -2620,52 +2621,27 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2620 | 2621 | par = parameter_s.strip() |
|
2621 | 2622 | if not par: |
|
2622 | 2623 | stored = self.db.get('stored_aliases', {} ) |
|
2623 |
a |
|
|
2624 | aliases = atab.keys() | |
|
2625 | aliases.sort() | |
|
2626 | res = [] | |
|
2627 | showlast = [] | |
|
2628 | for alias in aliases: | |
|
2629 | special = False | |
|
2630 | try: | |
|
2631 | tgt = atab[alias][1] | |
|
2632 | except (TypeError, AttributeError): | |
|
2633 | # unsubscriptable? probably a callable | |
|
2634 | tgt = atab[alias] | |
|
2635 | special = True | |
|
2636 | # 'interesting' aliases | |
|
2637 | if (alias in stored or | |
|
2638 | special or | |
|
2639 | alias.lower() != os.path.splitext(tgt)[0].lower() or | |
|
2640 | ' ' in tgt): | |
|
2641 | showlast.append((alias, tgt)) | |
|
2642 | else: | |
|
2643 | res.append((alias, tgt )) | |
|
2644 | ||
|
2645 | # show most interesting aliases last | |
|
2646 | res.extend(showlast) | |
|
2624 | aliases = sorted(self.shell.alias_manager.aliases) | |
|
2625 | # for k, v in stored: | |
|
2626 | # atab.append(k, v[0]) | |
|
2627 | ||
|
2647 | 2628 | print "Total number of aliases:",len(aliases) |
|
2648 |
return |
|
|
2629 | return aliases | |
|
2630 | ||
|
2631 | # Now try to define a new one | |
|
2649 | 2632 | try: |
|
2650 | 2633 | alias,cmd = par.split(None,1) |
|
2651 | 2634 | except: |
|
2652 | 2635 | print oinspect.getdoc(self.magic_alias) |
|
2653 | 2636 | else: |
|
2654 | nargs = cmd.count('%s') | |
|
2655 | if nargs>0 and cmd.find('%l')>=0: | |
|
2656 | error('The %s and %l specifiers are mutually exclusive ' | |
|
2657 | 'in alias definitions.') | |
|
2658 | else: # all looks OK | |
|
2659 | self.shell.alias_table[alias] = (nargs,cmd) | |
|
2660 | self.shell.alias_table_validate(verbose=0) | |
|
2637 | self.shell.alias_manager.soft_define_alias(alias, cmd) | |
|
2661 | 2638 | # end magic_alias |
|
2662 | 2639 | |
|
2663 | 2640 | def magic_unalias(self, parameter_s = ''): |
|
2664 | 2641 | """Remove an alias""" |
|
2665 | 2642 | |
|
2666 | 2643 | aname = parameter_s.strip() |
|
2667 | if aname in self.shell.alias_table: | |
|
2668 | del self.shell.alias_table[aname] | |
|
2644 | self.shell.alias_manager.undefine_alias(aname) | |
|
2669 | 2645 | stored = self.db.get('stored_aliases', {} ) |
|
2670 | 2646 | if aname in stored: |
|
2671 | 2647 | print "Removing %stored alias",aname |
@@ -2686,6 +2662,7 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2686 | 2662 | This function also resets the root module cache of module completer, |
|
2687 | 2663 | used on slow filesystems. |
|
2688 | 2664 | """ |
|
2665 | from IPython.core.alias import InvalidAliasError | |
|
2689 | 2666 | |
|
2690 | 2667 | # for the benefit of module completer in ipy_completers.py |
|
2691 | 2668 | del self.db['rootmodules'] |
@@ -2694,13 +2671,12 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2694 | 2671 | os.environ.get('PATH','').split(os.pathsep)] |
|
2695 | 2672 | path = filter(os.path.isdir,path) |
|
2696 | 2673 | |
|
2697 | alias_table = self.shell.alias_table | |
|
2698 | 2674 | syscmdlist = [] |
|
2675 | # Now define isexec in a cross platform manner. | |
|
2699 | 2676 | if os.name == 'posix': |
|
2700 | 2677 | isexec = lambda fname:os.path.isfile(fname) and \ |
|
2701 | 2678 | os.access(fname,os.X_OK) |
|
2702 | 2679 | else: |
|
2703 | ||
|
2704 | 2680 | try: |
|
2705 | 2681 | winext = os.environ['pathext'].replace(';','|').replace('.','') |
|
2706 | 2682 | except KeyError: |
@@ -2710,6 +2686,8 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2710 | 2686 | execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE) |
|
2711 | 2687 | isexec = lambda fname:os.path.isfile(fname) and execre.match(fname) |
|
2712 | 2688 | savedir = os.getcwd() |
|
2689 | ||
|
2690 | # Now walk the paths looking for executables to alias. | |
|
2713 | 2691 | try: |
|
2714 | 2692 | # write the whole loop for posix/Windows so we don't have an if in |
|
2715 | 2693 | # the innermost part |
@@ -2717,13 +2695,15 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2717 | 2695 | for pdir in path: |
|
2718 | 2696 | os.chdir(pdir) |
|
2719 | 2697 | for ff in os.listdir(pdir): |
|
2720 |
if isexec(ff) |
|
|
2721 | # each entry in the alias table must be (N,name), | |
|
2722 | # where N is the number of positional arguments of the | |
|
2723 | # alias. | |
|
2724 | # Dots will be removed from alias names, since ipython | |
|
2725 | # assumes names with dots to be python code | |
|
2726 | alias_table[ff.replace('.','')] = (0,ff) | |
|
2698 | if isexec(ff): | |
|
2699 | try: | |
|
2700 | # Removes dots from the name since ipython | |
|
2701 | # will assume names with dots to be python. | |
|
2702 | self.shell.alias_manager.define_alias( | |
|
2703 | ff.replace('.',''), ff) | |
|
2704 | except InvalidAliasError: | |
|
2705 | pass | |
|
2706 | else: | |
|
2727 | 2707 | syscmdlist.append(ff) |
|
2728 | 2708 | else: |
|
2729 | 2709 | for pdir in path: |
@@ -2733,16 +2713,14 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2733 | 2713 | if isexec(ff) and base.lower() not in self.shell.no_alias: |
|
2734 | 2714 | if ext.lower() == '.exe': |
|
2735 | 2715 | ff = base |
|
2736 | alias_table[base.lower().replace('.','')] = (0,ff) | |
|
2716 | try: | |
|
2717 | # Removes dots from the name since ipython | |
|
2718 | # will assume names with dots to be python. | |
|
2719 | self.shell.alias_manager.define_alias( | |
|
2720 | base.lower().replace('.',''), ff) | |
|
2721 | except InvalidAliasError: | |
|
2722 | pass | |
|
2737 | 2723 | syscmdlist.append(ff) |
|
2738 | # Make sure the alias table doesn't contain keywords or builtins | |
|
2739 | self.shell.alias_table_validate() | |
|
2740 | # Call again init_auto_alias() so we get 'rm -i' and other | |
|
2741 | # modified aliases since %rehashx will probably clobber them | |
|
2742 | ||
|
2743 | # no, we don't want them. if %rehashx clobbers them, good, | |
|
2744 | # we'll probably get better versions | |
|
2745 | # self.shell.init_auto_alias() | |
|
2746 | 2724 | db = self.db |
|
2747 | 2725 | db['syscmdlist'] = syscmdlist |
|
2748 | 2726 | finally: |
@@ -3167,7 +3145,7 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
3167 | 3145 | """ |
|
3168 | 3146 | |
|
3169 | 3147 | start = parameter_s.strip() |
|
3170 |
esc_magic = |
|
|
3148 | esc_magic = ESC_MAGIC | |
|
3171 | 3149 | # Identify magic commands even if automagic is on (which means |
|
3172 | 3150 | # the in-memory version is different from that typed by the user). |
|
3173 | 3151 | if self.shell.automagic: |
@@ -174,7 +174,7 b' class PrefilterManager(Component):' | |||
|
174 | 174 | to transform the input line. |
|
175 | 175 | """ |
|
176 | 176 | |
|
177 |
multi_line_specials = CBool(True, config |
|
|
177 | multi_line_specials = CBool(True, config=True) | |
|
178 | 178 | |
|
179 | 179 | def __init__(self, parent, config=None): |
|
180 | 180 | super(PrefilterManager, self).__init__(parent, config=config) |
@@ -274,16 +274,16 b' class PrefilterManager(Component):' | |||
|
274 | 274 | # the input history needs to track even empty lines |
|
275 | 275 | stripped = line.strip() |
|
276 | 276 | |
|
277 |
handle |
|
|
277 | normal_handler = self.get_handler_by_name('normal') | |
|
278 | 278 | if not stripped: |
|
279 | 279 | if not continue_prompt: |
|
280 | 280 | self.shell.outputcache.prompt_count -= 1 |
|
281 | 281 | |
|
282 |
return handle |
|
|
282 | return normal_handler.handle(line_info) | |
|
283 | 283 | |
|
284 | 284 | # special handlers are only allowed for single line statements |
|
285 | 285 | if continue_prompt and not self.multi_line_specials: |
|
286 |
return handle |
|
|
286 | return normal_handler.handle(line_info) | |
|
287 | 287 | |
|
288 | 288 | return self.prefilter_line_info(line_info) |
|
289 | 289 | |
@@ -310,7 +310,7 b' class PrefilterManager(Component):' | |||
|
310 | 310 | class PrefilterChecker(Component): |
|
311 | 311 | """Inspect an input line and return a handler for that line.""" |
|
312 | 312 | |
|
313 | priority = Int(100) | |
|
313 | priority = Int(100, config=True) | |
|
314 | 314 | shell = Any |
|
315 | 315 | prefilter_manager = Any |
|
316 | 316 | |
@@ -336,7 +336,7 b' class PrefilterChecker(Component):' | |||
|
336 | 336 | |
|
337 | 337 | class EmacsChecker(PrefilterChecker): |
|
338 | 338 | |
|
339 | priority = Int(100) | |
|
339 | priority = Int(100, config=True) | |
|
340 | 340 | |
|
341 | 341 | def check(self, line_info): |
|
342 | 342 | "Emacs ipython-mode tags certain input lines." |
@@ -348,7 +348,7 b' class EmacsChecker(PrefilterChecker):' | |||
|
348 | 348 | |
|
349 | 349 | class ShellEscapeChecker(PrefilterChecker): |
|
350 | 350 | |
|
351 | priority = Int(200) | |
|
351 | priority = Int(200, config=True) | |
|
352 | 352 | |
|
353 | 353 | def check(self, line_info): |
|
354 | 354 | if line_info.line.lstrip().startswith(ESC_SHELL): |
@@ -357,7 +357,7 b' class ShellEscapeChecker(PrefilterChecker):' | |||
|
357 | 357 | |
|
358 | 358 | class IPyAutocallChecker(PrefilterChecker): |
|
359 | 359 | |
|
360 | priority = Int(300) | |
|
360 | priority = Int(300, config=True) | |
|
361 | 361 | |
|
362 | 362 | def check(self, line_info): |
|
363 | 363 | "Instances of IPyAutocall in user_ns get autocalled immediately" |
@@ -371,7 +371,7 b' class IPyAutocallChecker(PrefilterChecker):' | |||
|
371 | 371 | |
|
372 | 372 | class MultiLineMagicChecker(PrefilterChecker): |
|
373 | 373 | |
|
374 | priority = Int(400) | |
|
374 | priority = Int(400, config=True) | |
|
375 | 375 | |
|
376 | 376 | def check(self, line_info): |
|
377 | 377 | "Allow ! and !! in multi-line statements if multi_line_specials is on" |
@@ -388,7 +388,7 b' class MultiLineMagicChecker(PrefilterChecker):' | |||
|
388 | 388 | |
|
389 | 389 | class EscCharsChecker(PrefilterChecker): |
|
390 | 390 | |
|
391 | priority = Int(500) | |
|
391 | priority = Int(500, config=True) | |
|
392 | 392 | |
|
393 | 393 | def check(self, line_info): |
|
394 | 394 | """Check for escape character and return either a handler to handle it, |
@@ -406,7 +406,7 b' class EscCharsChecker(PrefilterChecker):' | |||
|
406 | 406 | |
|
407 | 407 | class AssignmentChecker(PrefilterChecker): |
|
408 | 408 | |
|
409 | priority = Int(600) | |
|
409 | priority = Int(600, config=True) | |
|
410 | 410 | |
|
411 | 411 | def check(self, line_info): |
|
412 | 412 | """Check to see if user is assigning to a var for the first time, in |
@@ -423,7 +423,7 b' class AssignmentChecker(PrefilterChecker):' | |||
|
423 | 423 | |
|
424 | 424 | class AutoMagicChecker(PrefilterChecker): |
|
425 | 425 | |
|
426 | priority = Int(700) | |
|
426 | priority = Int(700, config=True) | |
|
427 | 427 | |
|
428 | 428 | def check(self, line_info): |
|
429 | 429 | """If the ifun is magic, and automagic is on, run it. Note: normal, |
@@ -447,7 +447,7 b' class AutoMagicChecker(PrefilterChecker):' | |||
|
447 | 447 | |
|
448 | 448 | class AliasChecker(PrefilterChecker): |
|
449 | 449 | |
|
450 | priority = Int(800) | |
|
450 | priority = Int(800, config=True) | |
|
451 | 451 | |
|
452 | 452 | @auto_attr |
|
453 | 453 | def alias_manager(self): |
@@ -467,7 +467,7 b' class AliasChecker(PrefilterChecker):' | |||
|
467 | 467 | |
|
468 | 468 | class PythonOpsChecker(PrefilterChecker): |
|
469 | 469 | |
|
470 | priority = Int(900) | |
|
470 | priority = Int(900, config=True) | |
|
471 | 471 | |
|
472 | 472 | def check(self, line_info): |
|
473 | 473 | """If the 'rest' of the line begins with a function call or pretty much |
@@ -482,7 +482,7 b' class PythonOpsChecker(PrefilterChecker):' | |||
|
482 | 482 | |
|
483 | 483 | class AutocallChecker(PrefilterChecker): |
|
484 | 484 | |
|
485 | priority = Int(1000) | |
|
485 | priority = Int(1000, config=True) | |
|
486 | 486 | |
|
487 | 487 | def check(self, line_info): |
|
488 | 488 | "Check if the initial word/function is callable and autocall is on." |
@@ -567,7 +567,7 b' class AliasHandler(PrefilterHandler):' | |||
|
567 | 567 | transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest) |
|
568 | 568 | # pre is needed, because it carries the leading whitespace. Otherwise |
|
569 | 569 | # aliases won't work in indented sections. |
|
570 | line_out = '%s_ip.system(%s)' % (line_info.pre_whitespace, | |
|
570 | line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace, | |
|
571 | 571 | make_quoted_expr(transformed)) |
|
572 | 572 | |
|
573 | 573 | self.shell.log(line_info.line, line_out, line_info.continue_prompt) |
@@ -597,7 +597,7 b' class ShellEscapeHandler(PrefilterHandler):' | |||
|
597 | 597 | return magic_handler.handle(line_info) |
|
598 | 598 | else: |
|
599 | 599 | cmd = line.lstrip().lstrip(ESC_SHELL) |
|
600 | line_out = '%s_ip.system(%s)' % (line_info.pre_whitespace, | |
|
600 | line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace, | |
|
601 | 601 | make_quoted_expr(cmd)) |
|
602 | 602 | # update cache/log and return |
|
603 | 603 | self.shell.log(line, line_out, line_info.continue_prompt) |
@@ -607,13 +607,13 b' class ShellEscapeHandler(PrefilterHandler):' | |||
|
607 | 607 | class MagicHandler(PrefilterHandler): |
|
608 | 608 | |
|
609 | 609 | handler_name = Str('magic') |
|
610 |
esc_strings = List([ |
|
|
610 | esc_strings = List([ESC_MAGIC]) | |
|
611 | 611 | |
|
612 | 612 | def handle(self, line_info): |
|
613 | 613 | """Execute magic functions.""" |
|
614 | 614 | ifun = line_info.ifun |
|
615 | 615 | the_rest = line_info.the_rest |
|
616 | cmd = '%s_ip.magic(%s)' % (line_info.pre_whitespace, | |
|
616 | cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace, | |
|
617 | 617 | make_quoted_expr(ifun + " " + the_rest)) |
|
618 | 618 | self.shell.log(line_info.line, cmd, line_info.continue_prompt) |
|
619 | 619 | return cmd |
@@ -656,7 +656,7 b' class AutoHandler(PrefilterHandler):' | |||
|
656 | 656 | # We only apply it to argument-less calls if the autocall |
|
657 | 657 | # parameter is set to 2. We only need to check that autocall is < |
|
658 | 658 | # 2, since this function isn't called unless it's at least 1. |
|
659 | if not the_rest and (self.autocall < 2) and not force_auto: | |
|
659 | if not the_rest and (self.shell.autocall < 2) and not force_auto: | |
|
660 | 660 | newcmd = '%s %s' % (ifun,the_rest) |
|
661 | 661 | auto_rewrite = False |
|
662 | 662 | else: |
@@ -546,8 +546,11 b' class CachedOutput:' | |||
|
546 | 546 | # don't use print, puts an extra space |
|
547 | 547 | cout_write(self.output_sep) |
|
548 | 548 | outprompt = self.shell.hooks.generate_output_prompt() |
|
549 | # print "Got prompt: ", outprompt | |
|
549 | 550 | if self.do_full_cache: |
|
550 | 551 | cout_write(outprompt) |
|
552 | else: | |
|
553 | print "self.do_full_cache = False" | |
|
551 | 554 | |
|
552 | 555 | # and now call a possibly user-defined print mechanism |
|
553 | 556 | manipulated_val = self.display(arg) |
@@ -31,4 +31,5 b' class A(object):' | |||
|
31 | 31 | a = A() |
|
32 | 32 | |
|
33 | 33 | # Now, we force an exit, the caller will check that the del printout was given |
|
34 | _ip = get_ipython() | |
|
34 | 35 | _ip.ask_exit() |
@@ -26,7 +26,7 b' from IPython.core.component import Component, ComponentError' | |||
|
26 | 26 | from IPython.utils.traitlets import ( |
|
27 | 27 | TraitletError, Int, Float, Str |
|
28 | 28 | ) |
|
29 | from IPython.utils.ipstruct import Struct | |
|
29 | from IPython.config.loader import Config | |
|
30 | 30 | |
|
31 | 31 | |
|
32 | 32 | #----------------------------------------------------------------------------- |
@@ -138,9 +138,9 b' class TestComponentConfig(TestCase):' | |||
|
138 | 138 | self.assertEquals(c2.config, c3.config) |
|
139 | 139 | |
|
140 | 140 | def test_custom(self): |
|
141 |
config = |
|
|
142 |
config. |
|
|
143 |
config. |
|
|
141 | config = Config() | |
|
142 | config.foo = 'foo' | |
|
143 | config.bar = 'bar' | |
|
144 | 144 | c1 = Component(None, config=config) |
|
145 | 145 | c2 = Component(c1) |
|
146 | 146 | c3 = Component(c2) |
@@ -156,19 +156,19 b' class TestComponentConfig(TestCase):' | |||
|
156 | 156 | |
|
157 | 157 | def test_inheritance(self): |
|
158 | 158 | class MyComponent(Component): |
|
159 |
a = Int(1, config |
|
|
160 |
b = Float(1.0, config |
|
|
159 | a = Int(1, config=True) | |
|
160 | b = Float(1.0, config=True) | |
|
161 | 161 | c = Str('no config') |
|
162 |
config = |
|
|
163 |
config. |
|
|
164 |
config. |
|
|
162 | config = Config() | |
|
163 | config.MyComponent.a = 2 | |
|
164 | config.MyComponent.b = 2.0 | |
|
165 | 165 | c1 = MyComponent(None, config=config) |
|
166 | 166 | c2 = MyComponent(c1) |
|
167 |
self.assertEquals(c1.a, config. |
|
|
168 |
self.assertEquals(c1.b, config. |
|
|
169 |
self.assertEquals(c2.a, config. |
|
|
170 |
self.assertEquals(c2.b, config. |
|
|
171 |
c4 = MyComponent(c2, config= |
|
|
167 | self.assertEquals(c1.a, config.MyComponent.a) | |
|
168 | self.assertEquals(c1.b, config.MyComponent.b) | |
|
169 | self.assertEquals(c2.a, config.MyComponent.a) | |
|
170 | self.assertEquals(c2.b, config.MyComponent.b) | |
|
171 | c4 = MyComponent(c2, config=Config()) | |
|
172 | 172 | self.assertEquals(c4.a, 1) |
|
173 | 173 | self.assertEquals(c4.b, 1.0) |
|
174 | 174 |
@@ -20,14 +20,15 b' from IPython.testing import tools as tt' | |||
|
20 | 20 | |
|
21 | 21 | def test_rehashx(): |
|
22 | 22 | # clear up everything |
|
23 | _ip.alias_table.clear() | |
|
23 | _ip = get_ipython() | |
|
24 | _ip.alias_manager.alias_table.clear() | |
|
24 | 25 | del _ip.db['syscmdlist'] |
|
25 | 26 | |
|
26 | 27 | _ip.magic('rehashx') |
|
27 | 28 | # Practically ALL ipython development systems will have more than 10 aliases |
|
28 | 29 | |
|
29 | yield (nt.assert_true, len(_ip.alias_table) > 10) | |
|
30 | for key, val in _ip.alias_table.items(): | |
|
30 | yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10) | |
|
31 | for key, val in _ip.alias_manager.alias_table.items(): | |
|
31 | 32 | # we must strip dots from alias names |
|
32 | 33 | nt.assert_true('.' not in key) |
|
33 | 34 | |
@@ -65,6 +66,7 b' def doctest_hist_r():' | |||
|
65 | 66 | # This test is known to fail on win32. |
|
66 | 67 | # See ticket https://bugs.launchpad.net/bugs/366334 |
|
67 | 68 | def test_obj_del(): |
|
69 | _ip = get_ipython() | |
|
68 | 70 | """Test that object's __del__ methods are called on exit.""" |
|
69 | 71 | test_dir = os.path.dirname(__file__) |
|
70 | 72 | del_file = os.path.join(test_dir,'obj_del.py') |
@@ -221,13 +223,14 b' class TestMagicRun(object):' | |||
|
221 | 223 | self.fname = fname |
|
222 | 224 | |
|
223 | 225 | def run_tmpfile(self): |
|
226 | _ip = get_ipython() | |
|
224 | 227 | # This fails on Windows if self.tmpfile.name has spaces or "~" in it. |
|
225 | 228 | # See below and ticket https://bugs.launchpad.net/bugs/366353 |
|
226 | 229 | _ip.magic('run "%s"' % self.fname) |
|
227 | 230 | |
|
228 | 231 | def test_builtins_id(self): |
|
229 | 232 | """Check that %run doesn't damage __builtins__ """ |
|
230 | ||
|
233 | _ip = get_ipython() | |
|
231 | 234 | # Test that the id of __builtins__ is not modified by %run |
|
232 | 235 | bid1 = id(_ip.user_ns['__builtins__']) |
|
233 | 236 | self.run_tmpfile() |
@@ -241,12 +244,14 b' class TestMagicRun(object):' | |||
|
241 | 244 | be a dict (it should be a module) by a previous use of %run. So we |
|
242 | 245 | also check explicitly that it really is a module: |
|
243 | 246 | """ |
|
247 | _ip = get_ipython() | |
|
244 | 248 | self.run_tmpfile() |
|
245 | 249 | tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys)) |
|
246 | 250 | |
|
247 | 251 | def test_prompts(self): |
|
248 | 252 | """Test that prompts correctly generate after %run""" |
|
249 | 253 | self.run_tmpfile() |
|
254 | _ip = get_ipython() | |
|
250 | 255 | p2 = str(_ip.outputcache.prompt2).strip() |
|
251 | 256 | nt.assert_equals(p2[:3], '...') |
|
252 | 257 | |
@@ -261,7 +266,7 b' class TestMagicRun(object):' | |||
|
261 | 266 | |
|
262 | 267 | # Multiple tests for clipboard pasting |
|
263 | 268 | def test_paste(): |
|
264 | ||
|
269 | _ip = get_ipython() | |
|
265 | 270 | def paste(txt, flags='-q'): |
|
266 | 271 | """Paste input text, by default in quiet mode""" |
|
267 | 272 | hooks.clipboard_get = lambda : txt |
@@ -21,14 +21,14 b' def hnd_magic(line,mo):' | |||
|
21 | 21 | var = mo.group('varname') |
|
22 | 22 | cmd = mo.group('cmd') |
|
23 | 23 | expr = make_quoted_expr(cmd) |
|
24 | return itpl('$var = _ip.magic($expr)') | |
|
24 | return itpl('$var = get_ipython().magic($expr)') | |
|
25 | 25 | |
|
26 | 26 | def hnd_syscmd(line,mo): |
|
27 | 27 | """ Handle a = !ls """ |
|
28 | 28 | var = mo.group('varname') |
|
29 | 29 | cmd = mo.group('cmd') |
|
30 | 30 | expr = make_quoted_expr(itpl("sc -l =$cmd")) |
|
31 | return itpl('$var = _ip.magic($expr)') | |
|
31 | return itpl('$var = get_ipython().magic($expr)') | |
|
32 | 32 | |
|
33 | 33 | def install_re_handler(pat, hnd): |
|
34 | 34 | ip.meta.re_prefilters.append((re.compile(pat), hnd)) |
@@ -1644,7 +1644,7 b' class ialias(Table):' | |||
|
1644 | 1644 | def __iter__(self): |
|
1645 | 1645 | api = ipapi.get() |
|
1646 | 1646 | |
|
1647 | for (name, (args, command)) in api.alias_table.iteritems(): | |
|
1647 | for (name, (args, command)) in api.alias_manager.alias_table.iteritems(): | |
|
1648 | 1648 | yield Alias(name, args, command) |
|
1649 | 1649 | |
|
1650 | 1650 |
@@ -109,7 +109,7 b' def main():' | |||
|
109 | 109 | cmd = noext |
|
110 | 110 | |
|
111 | 111 | key = mapper(cmd) |
|
112 | if key not in ip.alias_table: | |
|
112 | if key not in ip.alias_manager.alias_table: | |
|
113 | 113 | # Dots will be removed from alias names, since ipython |
|
114 | 114 | # assumes names with dots to be python code |
|
115 | 115 | |
@@ -159,7 +159,7 b' def slash_prefilter_f(self,line):' | |||
|
159 | 159 | """ |
|
160 | 160 | from IPython.utils import genutils |
|
161 | 161 | if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line): |
|
162 | return "_ip.system(" + genutils.make_quoted_expr(line)+")" | |
|
162 | return "get_ipython().system(" + genutils.make_quoted_expr(line)+")" | |
|
163 | 163 | raise TryNext |
|
164 | 164 | |
|
165 | 165 | # XXX You do not need to understand the next function! |
@@ -88,7 +88,7 b' def rehashdir_f(self,arg):' | |||
|
88 | 88 | if not arg: |
|
89 | 89 | arg = '.' |
|
90 | 90 | path = map(os.path.abspath,arg.split(';')) |
|
91 | alias_table = self.shell.alias_table | |
|
91 | alias_table = self.shell.alias_manager.alias_table | |
|
92 | 92 | |
|
93 | 93 | if os.name == 'posix': |
|
94 | 94 | isexec = lambda fname:os.path.isfile(fname) and \ |
@@ -126,8 +126,8 b' def jobctrl_prefilter_f(self,line):' | |||
|
126 | 126 | |
|
127 | 127 | line = ip.expand_aliases(fn,rest) |
|
128 | 128 | if not _jobq: |
|
129 | return '_ip.startjob(%s)' % genutils.make_quoted_expr(line) | |
|
130 | return '_ip.jobq(%s)' % genutils.make_quoted_expr(line) | |
|
129 | return 'get_ipython().startjob(%s)' % genutils.make_quoted_expr(line) | |
|
130 | return 'get_ipython().jobq(%s)' % genutils.make_quoted_expr(line) | |
|
131 | 131 | |
|
132 | 132 | raise TryNext |
|
133 | 133 |
@@ -157,6 +157,7 b" def magic_store(self, parameter_s=''):" | |||
|
157 | 157 | obj = ip.user_ns[args[0]] |
|
158 | 158 | except KeyError: |
|
159 | 159 | # it might be an alias |
|
160 | # This needs to be refactored to use the new AliasManager stuff. | |
|
160 | 161 | if args[0] in self.alias_table: |
|
161 | 162 | staliases = db.get('stored_aliases',{}) |
|
162 | 163 | staliases[ args[0] ] = self.alias_table[ args[0] ] |
@@ -99,7 +99,7 b' def pxrunsource(self, source, filename="<input>", symbol="single"):' | |||
|
99 | 99 | # Case 3 |
|
100 | 100 | # Because autopx is enabled, we now call executeAll or disable autopx if |
|
101 | 101 | # %autopx or autopx has been called |
|
102 | if '_ip.magic("%autopx' in source or '_ip.magic("autopx' in source: | |
|
102 | if 'get_ipython().magic("%autopx' in source or 'get_ipython().magic("autopx' in source: | |
|
103 | 103 | _disable_autopx(self) |
|
104 | 104 | return False |
|
105 | 105 | else: |
@@ -353,14 +353,17 b' class TestHasTraitlets(TestCase):' | |||
|
353 | 353 | class A(HasTraitlets): |
|
354 | 354 | i = Int(config_key='VALUE1', other_thing='VALUE2') |
|
355 | 355 | f = Float(config_key='VALUE3', other_thing='VALUE2') |
|
356 | j = Int(0) | |
|
356 | 357 | a = A() |
|
357 | self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f)) | |
|
358 | traitlets = a.traitlets(config_key=lambda v: True) | |
|
359 | self.assertEquals(traitlets, dict(i=A.i, f=A.f)) | |
|
358 | self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f, j=A.j)) | |
|
360 | 359 | traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2') |
|
361 | 360 | self.assertEquals(traitlets, dict(i=A.i)) |
|
362 | traitlets = a.traitlets('config_key') | |
|
363 | self.assertEquals(traitlets, dict(i=A.i, f=A.f)) | |
|
361 | ||
|
362 | # This passes, but it shouldn't because I am replicating a bug in | |
|
363 | # traits. | |
|
364 | traitlets = a.traitlets(config_key=lambda v: True) | |
|
365 | self.assertEquals(traitlets, dict(i=A.i, f=A.f, j=A.j)) | |
|
366 | ||
|
364 | 367 | |
|
365 | 368 | #----------------------------------------------------------------------------- |
|
366 | 369 | # Tests for specific traitlet types |
@@ -458,19 +458,22 b' class HasTraitlets(object):' | |||
|
458 | 458 | """Get a list of all the names of this classes traitlets.""" |
|
459 | 459 | return self.traitlets(**metadata).keys() |
|
460 | 460 | |
|
461 |
def traitlets(self, * |
|
|
461 | def traitlets(self, **metadata): | |
|
462 | 462 | """Get a list of all the traitlets of this class. |
|
463 | 463 | |
|
464 | 464 | The TraitletTypes returned don't know anything about the values |
|
465 | 465 | that the various HasTraitlet's instances are holding. |
|
466 | ||
|
467 | This follows the same algorithm as traits does and does not allow | |
|
468 | for any simple way of specifying merely that a metadata name | |
|
469 | exists, but has any value. This is because get_metadata returns | |
|
470 | None if a metadata key doesn't exist. | |
|
466 | 471 | """ |
|
467 | 472 | traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \ |
|
468 | 473 | isinstance(memb[1], TraitletType)]) |
|
469 | if len(metadata) == 0 and len(args) == 0: | |
|
470 | return traitlets | |
|
471 | 474 | |
|
472 |
f |
|
|
473 | metadata[meta_name] = lambda _: True | |
|
475 | if len(metadata) == 0: | |
|
476 | return traitlets | |
|
474 | 477 | |
|
475 | 478 | for meta_name, meta_eval in metadata.items(): |
|
476 | 479 | if type(meta_eval) is not FunctionType: |
General Comments 0
You need to be logged in to leave comments.
Login now