##// END OF EJS Templates
Merging the config-refactor branch....
Brian Granger -
r2278:b8ad0071 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,148 b''
1 # Get the config being loaded so we can set attributes on it
2 c = get_config()
3
4 #-----------------------------------------------------------------------------
5 # Global options
6 #-----------------------------------------------------------------------------
7
8 # c.Global.display_banner = True
9
10 # c.Global.classic = False
11
12 # c.Global.nosep = True
13
14 # Set this to determine the detail of what is logged at startup.
15 # The default is 30 and possible values are 0,10,20,30,40,50.
16 c.Global.log_level = 20
17
18 # This should be a list of importable Python modules that have an
19 # load_in_ipython(ip) method. This method gets called when the extension
20 # is loaded. You can put your extensions anywhere they can be imported
21 # but we add the extensions subdir of the ipython directory to sys.path
22 # during extension loading, so you can put them there as well.
23 # c.Global.extensions = [
24 # 'myextension'
25 # ]
26
27 # These lines are run in IPython in the user's namespace after extensions
28 # are loaded. They can contain full IPython syntax with magics etc.
29 # c.Global.exec_lines = [
30 # 'import numpy',
31 # 'a = 10; b = 20',
32 # '1/0'
33 # ]
34
35 # These files are run in IPython in the user's namespace. Files with a .py
36 # extension need to be pure Python. Files with a .ipy extension can have
37 # custom IPython syntax (like magics, etc.).
38 # These files need to be in the cwd, the ipythondir or be absolute paths.
39 # c.Global.exec_files = [
40 # 'mycode.py',
41 # 'fancy.ipy'
42 # ]
43
44 #-----------------------------------------------------------------------------
45 # InteractiveShell options
46 #-----------------------------------------------------------------------------
47
48 # c.InteractiveShell.autocall = 1
49
50 # c.InteractiveShell.autoedit_syntax = False
51
52 # c.InteractiveShell.autoindent = True
53
54 # c.InteractiveShell.automagic = False
55
56 # c.InteractiveShell.banner1 = 'This if for overriding the default IPython banner'
57
58 # c.InteractiveShell.banner2 = "This is for extra banner text"
59
60 # c.InteractiveShell.cache_size = 1000
61
62 # c.InteractiveShell.colors = 'LightBG'
63
64 # c.InteractiveShell.color_info = True
65
66 # c.InteractiveShell.confirm_exit = True
67
68 # c.InteractiveShell.deep_reload = False
69
70 # c.InteractiveShell.editor = 'nano'
71
72 # c.InteractiveShell.logstart = True
73
74 # c.InteractiveShell.logfile = 'ipython_log.py'
75
76 # c.InteractiveShell.logappend = 'mylog.py'
77
78 # c.InteractiveShell.object_info_string_level = 0
79
80 # c.InteractiveShell.pager = 'less'
81
82 # c.InteractiveShell.pdb = False
83
84 # c.InteractiveShell.pprint = True
85
86 # c.InteractiveShell.prompt_in1 = 'In [\#]: '
87 # c.InteractiveShell.prompt_in2 = ' .\D.: '
88 # c.InteractiveShell.prompt_out = 'Out[\#]: '
89 # c.InteractiveShell.prompts_pad_left = True
90
91 # c.InteractiveShell.quiet = False
92
93 # Readline
94 # c.InteractiveShell.readline_use = True
95
96 # c.InteractiveShell.readline_parse_and_bind = [
97 # 'tab: complete',
98 # '"\C-l": possible-completions',
99 # 'set show-all-if-ambiguous on',
100 # '"\C-o": tab-insert',
101 # '"\M-i": " "',
102 # '"\M-o": "\d\d\d\d"',
103 # '"\M-I": "\d\d\d\d"',
104 # '"\C-r": reverse-search-history',
105 # '"\C-s": forward-search-history',
106 # '"\C-p": history-search-backward',
107 # '"\C-n": history-search-forward',
108 # '"\e[A": history-search-backward',
109 # '"\e[B": history-search-forward',
110 # '"\C-k": kill-line',
111 # '"\C-u": unix-line-discard',
112 # ]
113 # c.InteractiveShell.readline_remove_delims = '-/~'
114 # c.InteractiveShell.readline_merge_completions = True
115 # c.InteractiveShell.readline_omit_names = 0
116
117 # c.InteractiveShell.screen_length = 0
118
119 # c.InteractiveShell.separate_in = '\n'
120 # c.InteractiveShell.separate_out = ''
121 # c.InteractiveShell.separate_out2 = ''
122
123 # c.InteractiveShell.system_header = "IPython system call: "
124
125 # c.InteractiveShell.system_verbose = True
126
127 # c.InteractiveShell.term_title = False
128
129 # c.InteractiveShell.wildcards_case_sensitive = True
130
131 # c.InteractiveShell.xmode = 'Context'
132
133 #-----------------------------------------------------------------------------
134 # PrefilterManager options
135 #-----------------------------------------------------------------------------
136
137 # c.PrefilterManager.multi_line_specials = True
138
139 #-----------------------------------------------------------------------------
140 # AliasManager options
141 #-----------------------------------------------------------------------------
142
143 # Do this to disable all defaults
144 # c.AliasManager.default_aliases = []
145
146 # c.AliasManager.user_aliases = [
147 # ('foo', 'echo Hi')
148 # ] No newline at end of file
@@ -0,0 +1,62 b''
1 from os.path import join
2 pjoin = join
3
4 from IPython.utils.genutils import get_ipython_dir, get_security_dir
5 security_dir = get_security_dir()
6
7
8 ENGINE_LOGFILE = ''
9
10 ENGINE_FURL_FILE = 'ipcontroller-engine.furl'
11
12 MPI_CONFIG_MPI4PY = """from mpi4py import MPI as mpi
13 mpi.size = mpi.COMM_WORLD.Get_size()
14 mpi.rank = mpi.COMM_WORLD.Get_rank()
15 """
16
17 MPI_CONFIG_PYTRILINOS = """from PyTrilinos import Epetra
18 class SimpleStruct:
19 pass
20 mpi = SimpleStruct()
21 mpi.rank = 0
22 mpi.size = 0
23 """
24
25 MPI_DEFAULT = ''
26
27 CONTROLLER_LOGFILE = ''
28 CONTROLLER_IMPORT_STATEMENT = ''
29 CONTROLLER_REUSE_FURLS = False
30
31 ENGINE_TUB_IP = ''
32 ENGINE_TUB_PORT = 0
33 ENGINE_TUB_LOCATION = ''
34 ENGINE_TUB_SECURE = True
35 ENGINE_TUB_CERT_FILE = 'ipcontroller-engine.pem'
36 ENGINE_FC_INTERFACE = 'IPython.kernel.enginefc.IFCControllerBase'
37 ENGINE_FURL_FILE = 'ipcontroller-engine.furl'
38
39 CONTROLLER_INTERFACES = dict(
40 TASK = dict(
41 CONTROLLER_INTERFACE = 'IPython.kernel.task.ITaskController',
42 FC_INTERFACE = 'IPython.kernel.taskfc.IFCTaskController',
43 FURL_FILE = pjoin(security_dir, 'ipcontroller-tc.furl')
44 ),
45 MULTIENGINE = dict(
46 CONTROLLER_INTERFACE = 'IPython.kernel.multiengine.IMultiEngine',
47 FC_INTERFACE = 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine',
48 FURL_FILE = pjoin(security_dir, 'ipcontroller-mec.furl')
49 )
50 )
51
52 CLIENT_TUB_IP = ''
53 CLIENT_TUB_PORT = 0
54 CLIENT_TUB_LOCATION = ''
55 CLIENT_TUB_SECURE = True
56 CLIENT_TUB_CERT_FILE = 'ipcontroller-client.pem'
57
58 CLIENT_INTERFACES = dict(
59 TASK = dict(FURL_FILE = 'ipcontroller-tc.furl'),
60 MULTIENGINE = dict(FURLFILE='ipcontroller-mec.furl')
61 )
62
@@ -0,0 +1,329 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """A simple configuration system.
4
5 Authors:
6
7 * Brian Granger
8 """
9
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Imports
19 #-----------------------------------------------------------------------------
20
21 import __builtin__
22 import os
23 import sys
24
25 from IPython.external import argparse
26 from IPython.utils.genutils import filefind
27
28 #-----------------------------------------------------------------------------
29 # Exceptions
30 #-----------------------------------------------------------------------------
31
32
33 class ConfigError(Exception):
34 pass
35
36
37 class ConfigLoaderError(ConfigError):
38 pass
39
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
153 class ConfigLoader(object):
154 """A object for loading configurations from just about anywhere.
155
156 The resulting configuration is packaged as a :class:`Struct`.
157
158 Notes
159 -----
160 A :class:`ConfigLoader` does one thing: load a config from a source
161 (file, command line arguments) and returns the data as a :class:`Struct`.
162 There are lots of things that :class:`ConfigLoader` does not do. It does
163 not implement complex logic for finding config files. It does not handle
164 default values or merge multiple configs. These things need to be
165 handled elsewhere.
166 """
167
168 def __init__(self):
169 """A base class for config loaders.
170
171 Examples
172 --------
173
174 >>> cl = ConfigLoader()
175 >>> config = cl.load_config()
176 >>> config
177 {}
178 """
179 self.clear()
180
181 def clear(self):
182 self.config = Config()
183
184 def load_config(self):
185 """Load a config from somewhere, return a Struct.
186
187 Usually, this will cause self.config to be set and then returned.
188 """
189 return self.config
190
191
192 class FileConfigLoader(ConfigLoader):
193 """A base class for file based configurations.
194
195 As we add more file based config loaders, the common logic should go
196 here.
197 """
198 pass
199
200
201 class PyFileConfigLoader(FileConfigLoader):
202 """A config loader for pure python files.
203
204 This calls execfile on a plain python file and looks for attributes
205 that are all caps. These attribute are added to the config Struct.
206 """
207
208 def __init__(self, filename, path=None):
209 """Build a config loader for a filename and path.
210
211 Parameters
212 ----------
213 filename : str
214 The file name of the config file.
215 path : str, list, tuple
216 The path to search for the config file on, or a sequence of
217 paths to try in order.
218 """
219 super(PyFileConfigLoader, self).__init__()
220 self.filename = filename
221 self.path = path
222 self.full_filename = ''
223 self.data = None
224
225 def load_config(self):
226 """Load the config from a file and return it as a Struct."""
227 self._find_file()
228 self._read_file_as_dict()
229 self._convert_to_config()
230 return self.config
231
232 def _find_file(self):
233 """Try to find the file by searching the paths."""
234 self.full_filename = filefind(self.filename, self.path)
235
236 def _read_file_as_dict(self):
237 """Load the config file into self.config, with recursive loading."""
238 # This closure is made available in the namespace that is used
239 # to exec the config file. This allows users to call
240 # load_subconfig('myconfig.py') to load config files recursively.
241 # It needs to be a closure because it has references to self.path
242 # and self.config. The sub-config is loaded with the same path
243 # as the parent, but it uses an empty config which is then merged
244 # with the parents.
245 def load_subconfig(fname):
246 loader = PyFileConfigLoader(fname, self.path)
247 sub_config = loader.load_config()
248 self.config._merge(sub_config)
249
250 # Again, this needs to be a closure and should be used in config
251 # files to get the config being loaded.
252 def get_config():
253 return self.config
254
255 namespace = dict(load_subconfig=load_subconfig, get_config=get_config)
256 execfile(self.full_filename, namespace)
257
258 def _convert_to_config(self):
259 if self.data is None:
260 ConfigLoaderError('self.data does not exist')
261
262
263 class CommandLineConfigLoader(ConfigLoader):
264 """A config loader for command line arguments.
265
266 As we add more command line based loaders, the common logic should go
267 here.
268 """
269
270
271 class NoConfigDefault(object): pass
272 NoConfigDefault = NoConfigDefault()
273
274 class ArgParseConfigLoader(CommandLineConfigLoader):
275
276 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
277 arguments = ()
278
279 def __init__(self, *args, **kw):
280 """Create a config loader for use with argparse.
281
282 The args and kwargs arguments here are passed onto the constructor
283 of :class:`argparse.ArgumentParser`.
284 """
285 super(CommandLineConfigLoader, self).__init__()
286 self.args = args
287 self.kw = kw
288
289 def load_config(self, args=None):
290 """Parse command line arguments and return as a Struct."""
291 self._create_parser()
292 self._parse_args(args)
293 self._convert_to_config()
294 return self.config
295
296 def get_extra_args(self):
297 if hasattr(self, 'extra_args'):
298 return self.extra_args
299 else:
300 return []
301
302 def _create_parser(self):
303 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
304 self._add_arguments()
305 self._add_other_arguments()
306
307 def _add_other_arguments(self):
308 pass
309
310 def _add_arguments(self):
311 for argument in self.arguments:
312 if not argument[1].has_key('default'):
313 argument[1]['default'] = NoConfigDefault
314 self.parser.add_argument(*argument[0],**argument[1])
315
316 def _parse_args(self, args=None):
317 """self.parser->self.parsed_data"""
318 if args is None:
319 self.parsed_data, self.extra_args = self.parser.parse_known_args()
320 else:
321 self.parsed_data, self.extra_args = self.parser.parse_known_args(args)
322
323 def _convert_to_config(self):
324 """self.parsed_data->self.config"""
325 for k, v in vars(self.parsed_data).items():
326 if v is not NoConfigDefault:
327 exec_str = 'self.config.' + k + '= v'
328 exec exec_str in locals(), globals()
329
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,19 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import cmath
9 from math import *
10 """
11
12 # You have to make sure that attributes that are containers already
13 # exist before using them. Simple assigning a new list will override
14 # all previous values.
15 if hasattr(c.Global, 'exec_lines'):
16 c.Global.exec_lines.append(lines)
17 else:
18 c.Global.exec_lines = [lines]
19
@@ -0,0 +1,20 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import numpy
9 import scipy
10 import numpy as np
11 import scipy as sp
12 """
13
14 # You have to make sure that attributes that are containers already
15 # exist before using them. Simple assigning a new list will override
16 # all previous values.
17 if hasattr(c.Global, 'exec_lines'):
18 c.Global.exec_lines.append(lines)
19 else:
20 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,22 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 import matplotlib
9 %gui -a wx
10 matplotlib.use('wxagg')
11 matplotlib.interactive(True)
12 from matplotlib import pyplot as plt
13 from matplotlib.pyplot import *
14 """
15
16 # You have to make sure that attributes that are containers already
17 # exist before using them. Simple assigning a new list will override
18 # all previous values.
19 if hasattr(c.Global, 'exec_lines'):
20 c.Global.exec_lines.append(lines)
21 else:
22 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,29 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 c.InteractiveShell.prompt_in1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
8 c.InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
9 c.InteractiveShell.prompt_out = '<\#> '
10
11 c.InteractiveShell.prompts_pad_left = True
12
13 c.InteractiveShell.separate_in = ''
14 c.InteractiveShell.separate_out = ''
15 c.InteractiveShell.separate_out2 = ''
16
17 c.PrefilterManager.multi_line_specials = True
18
19 lines = """
20 %rehashx
21 """
22
23 # You have to make sure that attributes that are containers already
24 # exist before using them. Simple assigning a new list will override
25 # all previous values.
26 if hasattr(c.Global, 'exec_lines'):
27 c.Global.exec_lines.append(lines)
28 else:
29 c.Global.exec_lines = [lines] No newline at end of file
@@ -0,0 +1,21 b''
1 c = get_config()
2
3 # This can be used at any point in a config file to load a sub config
4 # and merge it into the current one.
5 load_subconfig('ipython_config.py')
6
7 lines = """
8 from __future__ import division
9 from sympy import *
10 x, y, z = symbols('xyz')
11 k, m, n = symbols('kmn', integer=True)
12 f, g, h = map(Function, 'fgh')
13 """
14
15 # You have to make sure that attributes that are containers already
16 # exist before using them. Simple assigning a new list will override
17 # all previous values.
18 if hasattr(c.Global, 'exec_lines'):
19 c.Global.exec_lines.append(lines)
20 else:
21 c.Global.exec_lines = [lines]
@@ -0,0 +1,163 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Tests for IPython.config.loader
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez (design help)
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import os
24 from tempfile import mkstemp
25 from unittest import TestCase
26
27 from IPython.config.loader import (
28 Config,
29 PyFileConfigLoader,
30 ArgParseConfigLoader,
31 ConfigError
32 )
33
34 #-----------------------------------------------------------------------------
35 # Actual tests
36 #-----------------------------------------------------------------------------
37
38
39 pyfile = """
40 a = 10
41 b = 20
42 Foo.Bar.value = 10
43 Foo.Bam.value = range(10)
44 D.C.value = 'hi there'
45 """
46
47 class TestPyFileCL(TestCase):
48
49 def test_basic(self):
50 fd, fname = mkstemp()
51 f = os.fdopen(fd, 'w')
52 f.write(pyfile)
53 f.close()
54 # Unlink the file
55 cl = PyFileConfigLoader(fname)
56 config = cl.load_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')
62
63
64 class TestArgParseCL(TestCase):
65
66 def test_basic(self):
67
68 class MyLoader(ArgParseConfigLoader):
69 arguments = (
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))
74 )
75
76 cl = MyLoader()
77 config = cl.load_config('-f hi -b 10 -n wow'.split())
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')
82
83 def test_add_arguments(self):
84
85 class MyLoader(ArgParseConfigLoader):
86 def _add_arguments(self):
87 subparsers = self.parser.add_subparsers(dest='subparser_name')
88 subparser1 = subparsers.add_parser('1')
89 subparser1.add_argument('-x',dest='Global.x')
90 subparser2 = subparsers.add_parser('2')
91 subparser2.add_argument('y')
92
93 cl = MyLoader()
94 config = cl.load_config('2 frobble'.split())
95 self.assertEquals(config.subparser_name, '2')
96 self.assertEquals(config.y, 'frobble')
97 config = cl.load_config('1 -x frobble'.split())
98 self.assertEquals(config.subparser_name, '1')
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)
@@ -0,0 +1,262 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 IPython's alias component
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22 import __builtin__
23 import keyword
24 import os
25 import re
26 import sys
27
28 from IPython.core.component import Component
29 from IPython.core.splitinput import split_user_input
30
31 from IPython.utils.traitlets import CBool, List, Instance
32 from IPython.utils.genutils import error
33 from IPython.utils.autoattr import auto_attr
34
35 #-----------------------------------------------------------------------------
36 # Utilities
37 #-----------------------------------------------------------------------------
38
39 # This is used as the pattern for calls to split_user_input.
40 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
41
42 def default_aliases():
43 # Make some aliases automatically
44 # Prepare list of shell aliases to auto-define
45 if os.name == 'posix':
46 default_aliases = ('mkdir mkdir', 'rmdir rmdir',
47 'mv mv -i','rm rm -i','cp cp -i',
48 'cat cat','less less','clear clear',
49 # a better ls
50 'ls ls -F',
51 # long ls
52 'll ls -lF')
53 # Extra ls aliases with color, which need special treatment on BSD
54 # variants
55 ls_extra = ( # color ls
56 'lc ls -F -o --color',
57 # ls normal files only
58 'lf ls -F -o --color %l | grep ^-',
59 # ls symbolic links
60 'lk ls -F -o --color %l | grep ^l',
61 # directories or links to directories,
62 'ldir ls -F -o --color %l | grep /$',
63 # things which are executable
64 'lx ls -F -o --color %l | grep ^-..x',
65 )
66 # The BSDs don't ship GNU ls, so they don't understand the
67 # --color switch out of the box
68 if 'bsd' in sys.platform:
69 ls_extra = ( # ls normal files only
70 'lf ls -lF | grep ^-',
71 # ls symbolic links
72 'lk ls -lF | grep ^l',
73 # directories or links to directories,
74 'ldir ls -lF | grep /$',
75 # things which are executable
76 'lx ls -lF | grep ^-..x',
77 )
78 default_aliases = default_aliases + ls_extra
79 elif os.name in ['nt','dos']:
80 default_aliases = ('ls dir /on',
81 'ddir dir /ad /on', 'ldir dir /ad /on',
82 'mkdir mkdir','rmdir rmdir','echo echo',
83 'ren ren','cls cls','copy copy')
84 else:
85 default_aliases = ()
86 return [s.split(None,1) for s in default_aliases]
87
88
89 class AliasError(Exception):
90 pass
91
92
93 class InvalidAliasError(AliasError):
94 pass
95
96
97 #-----------------------------------------------------------------------------
98 # Main AliasManager class
99 #-----------------------------------------------------------------------------
100
101
102 class AliasManager(Component):
103
104 default_aliases = List(default_aliases(), config=True)
105 user_aliases = List(default_value=[], config=True)
106
107 def __init__(self, parent, config=None):
108 super(AliasManager, self).__init__(parent, config=config)
109 self.alias_table = {}
110 self.exclude_aliases()
111 self.init_aliases()
112
113 @auto_attr
114 def shell(self):
115 return Component.get_instances(
116 root=self.root,
117 klass='IPython.core.iplib.InteractiveShell')[0]
118
119 def __contains__(self, name):
120 if name in self.alias_table:
121 return True
122 else:
123 return False
124
125 @property
126 def aliases(self):
127 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
128
129 def exclude_aliases(self):
130 # set of things NOT to alias (keywords, builtins and some magics)
131 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
132 no_alias.update(set(keyword.kwlist))
133 no_alias.update(set(__builtin__.__dict__.keys()))
134 self.no_alias = no_alias
135
136 def init_aliases(self):
137 # Load default aliases
138 for name, cmd in self.default_aliases:
139 self.soft_define_alias(name, cmd)
140
141 # Load user aliases
142 for name, cmd in self.user_aliases:
143 self.soft_define_alias(name, cmd)
144
145 def clear_aliases(self):
146 self.alias_table.clear()
147
148 def soft_define_alias(self, name, cmd):
149 """Define an alias, but don't raise on an AliasError."""
150 try:
151 self.define_alias(name, cmd)
152 except AliasError, e:
153 error("Invalid alias: %s" % e)
154
155 def define_alias(self, name, cmd):
156 """Define a new alias after validating it.
157
158 This will raise an :exc:`AliasError` if there are validation
159 problems.
160 """
161 nargs = self.validate_alias(name, cmd)
162 self.alias_table[name] = (nargs, cmd)
163
164 def undefine_alias(self, name):
165 if self.alias_table.has_key(name):
166 del self.alias_table[name]
167
168 def validate_alias(self, name, cmd):
169 """Validate an alias and return the its number of arguments."""
170 if name in self.no_alias:
171 raise InvalidAliasError("The name %s can't be aliased "
172 "because it is a keyword or builtin." % name)
173 if not (isinstance(cmd, basestring)):
174 raise InvalidAliasError("An alias command must be a string, "
175 "got: %r" % name)
176 nargs = cmd.count('%s')
177 if nargs>0 and cmd.find('%l')>=0:
178 raise InvalidAliasError('The %s and %l specifiers are mutually '
179 'exclusive in alias definitions.')
180 return nargs
181
182 def call_alias(self, alias, rest=''):
183 """Call an alias given its name and the rest of the line."""
184 cmd = self.transform_alias(alias, rest)
185 try:
186 self.shell.system(cmd)
187 except:
188 self.shell.showtraceback()
189
190 def transform_alias(self, alias,rest=''):
191 """Transform alias to system command string."""
192 nargs, cmd = self.alias_table[alias]
193
194 if ' ' in cmd and os.path.isfile(cmd):
195 cmd = '"%s"' % cmd
196
197 # Expand the %l special to be the user's input line
198 if cmd.find('%l') >= 0:
199 cmd = cmd.replace('%l', rest)
200 rest = ''
201 if nargs==0:
202 # Simple, argument-less aliases
203 cmd = '%s %s' % (cmd, rest)
204 else:
205 # Handle aliases with positional arguments
206 args = rest.split(None, nargs)
207 if len(args) < nargs:
208 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
209 (alias, nargs, len(args)))
210 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
211 return cmd
212
213 def expand_alias(self, line):
214 """ Expand an alias in the command line
215
216 Returns the provided command line, possibly with the first word
217 (command) translated according to alias expansion rules.
218
219 [ipython]|16> _ip.expand_aliases("np myfile.txt")
220 <16> 'q:/opt/np/notepad++.exe myfile.txt'
221 """
222
223 pre,fn,rest = split_user_input(line)
224 res = pre + self.expand_aliases(fn, rest)
225 return res
226
227 def expand_aliases(self, fn, rest):
228 """Expand multiple levels of aliases:
229
230 if:
231
232 alias foo bar /tmp
233 alias baz foo
234
235 then:
236
237 baz huhhahhei -> bar /tmp huhhahhei
238
239 """
240 line = fn + " " + rest
241
242 done = set()
243 while 1:
244 pre,fn,rest = split_user_input(line, shell_line_split)
245 if fn in self.alias_table:
246 if fn in done:
247 warn("Cyclic alias definition, repeated '%s'" % fn)
248 return ""
249 done.add(fn)
250
251 l2 = self.transform_alias(fn, rest)
252 if l2 == line:
253 break
254 # ls -> ls -F should not recurse forever
255 if l2.split(None,1)[0] == line.split(None,1)[0]:
256 line = l2
257 break
258 line=l2
259 else:
260 break
261
262 return line
@@ -0,0 +1,300 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 An application for IPython
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 import logging
27 import os
28 import sys
29 import traceback
30 from copy import deepcopy
31
32 from IPython.utils.genutils import get_ipython_dir, filefind
33 from IPython.config.loader import (
34 PyFileConfigLoader,
35 ArgParseConfigLoader,
36 Config,
37 NoConfigDefault
38 )
39
40 #-----------------------------------------------------------------------------
41 # Classes and functions
42 #-----------------------------------------------------------------------------
43
44
45 class IPythonArgParseConfigLoader(ArgParseConfigLoader):
46 """Default command line options for IPython based applications."""
47
48 def _add_other_arguments(self):
49 self.parser.add_argument('-ipythondir',dest='Global.ipythondir',type=str,
50 help='Set to override default location of Global.ipythondir.',
51 default=NoConfigDefault,
52 metavar='Global.ipythondir')
53 self.parser.add_argument('-p','-profile',dest='Global.profile',type=str,
54 help='The string name of the ipython profile to be used.',
55 default=NoConfigDefault,
56 metavar='Global.profile')
57 self.parser.add_argument('-log_level',dest="Global.log_level",type=int,
58 help='Set the log level (0,10,20,30,40,50). Default is 30.',
59 default=NoConfigDefault)
60 self.parser.add_argument('-config_file',dest='Global.config_file',type=str,
61 help='Set the config file name to override default.',
62 default=NoConfigDefault,
63 metavar='Global.config_file')
64
65
66 class ApplicationError(Exception):
67 pass
68
69
70 class Application(object):
71 """Load a config, construct an app and run it.
72 """
73
74 config_file_name = 'ipython_config.py'
75 name = 'ipython'
76
77 def __init__(self):
78 self.init_logger()
79 self.default_config_file_name = self.config_file_name
80
81 def init_logger(self):
82 self.log = logging.getLogger(self.__class__.__name__)
83 # This is used as the default until the command line arguments are read.
84 self.log.setLevel(logging.WARN)
85 self._log_handler = logging.StreamHandler()
86 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
87 self._log_handler.setFormatter(self._log_formatter)
88 self.log.addHandler(self._log_handler)
89
90 def _set_log_level(self, level):
91 self.log.setLevel(level)
92
93 def _get_log_level(self):
94 return self.log.level
95
96 log_level = property(_get_log_level, _set_log_level)
97
98 def start(self):
99 """Start the application."""
100 self.attempt(self.create_default_config)
101 self.attempt(self.pre_load_command_line_config)
102 self.attempt(self.load_command_line_config, action='abort')
103 self.attempt(self.post_load_command_line_config)
104 self.attempt(self.find_ipythondir)
105 self.attempt(self.find_config_file_name)
106 self.attempt(self.find_config_file_paths)
107 self.attempt(self.pre_load_file_config)
108 self.attempt(self.load_file_config)
109 self.attempt(self.post_load_file_config)
110 self.attempt(self.merge_configs)
111 self.attempt(self.pre_construct)
112 self.attempt(self.construct)
113 self.attempt(self.post_construct)
114 self.attempt(self.start_app)
115
116 #-------------------------------------------------------------------------
117 # Various stages of Application creation
118 #-------------------------------------------------------------------------
119
120 def create_default_config(self):
121 """Create defaults that can't be set elsewhere.
122
123 For the most part, we try to set default in the class attributes
124 of Components. But, defaults the top-level Application (which is
125 not a HasTraitlets or Component) are not set in this way. Instead
126 we set them here. The Global section is for variables like this that
127 don't belong to a particular component.
128 """
129 self.default_config = Config()
130 self.default_config.Global.ipythondir = get_ipython_dir()
131 self.log.debug('Default config loaded:')
132 self.log.debug(repr(self.default_config))
133
134 def create_command_line_config(self):
135 """Create and return a command line config loader."""
136 return IPythonArgParseConfigLoader(description=self.name)
137
138 def pre_load_command_line_config(self):
139 """Do actions just before loading the command line config."""
140 pass
141
142 def load_command_line_config(self):
143 """Load the command line config.
144
145 This method also sets ``self.debug``.
146 """
147
148 loader = self.create_command_line_config()
149 self.command_line_config = loader.load_config()
150 self.extra_args = loader.get_extra_args()
151
152 try:
153 self.log_level = self.command_line_config.Global.log_level
154 except AttributeError:
155 pass # Use existing value which is set in Application.init_logger.
156 self.log.debug("Command line config loaded:")
157 self.log.debug(repr(self.command_line_config))
158
159 def post_load_command_line_config(self):
160 """Do actions just after loading the command line config."""
161 pass
162
163 def find_ipythondir(self):
164 """Set the IPython directory.
165
166 This sets ``self.ipythondir``, but the actual value that is passed
167 to the application is kept in either ``self.default_config`` or
168 ``self.command_line_config``. This also added ``self.ipythondir`` to
169 ``sys.path`` so config files there can be references by other config
170 files.
171 """
172
173 try:
174 self.ipythondir = self.command_line_config.Global.ipythondir
175 except AttributeError:
176 self.ipythondir = self.default_config.Global.ipythondir
177 sys.path.append(os.path.abspath(self.ipythondir))
178 if not os.path.isdir(self.ipythondir):
179 os.makedirs(self.ipythondir, mode = 0777)
180 self.log.debug("IPYTHONDIR set to: %s" % self.ipythondir)
181
182 def find_config_file_name(self):
183 """Find the config file name for this application.
184
185 If a profile has been set at the command line, this will resolve
186 it. The search paths for the config file are set in
187 :meth:`find_config_file_paths` and then passed to the config file
188 loader where they are resolved to an absolute path.
189 """
190
191 try:
192 self.config_file_name = self.command_line_config.Global.config_file
193 except AttributeError:
194 pass
195
196 try:
197 self.profile_name = self.command_line_config.Global.profile
198 name_parts = self.config_file_name.split('.')
199 name_parts.insert(1, '_' + self.profile_name + '.')
200 self.config_file_name = ''.join(name_parts)
201 except AttributeError:
202 pass
203
204 def find_config_file_paths(self):
205 """Set the search paths for resolving the config file."""
206 self.config_file_paths = (os.getcwd(), self.ipythondir)
207
208 def pre_load_file_config(self):
209 """Do actions before the config file is loaded."""
210 pass
211
212 def load_file_config(self):
213 """Load the config file.
214
215 This tries to load the config file from disk. If successful, the
216 ``CONFIG_FILE`` config variable is set to the resolved config file
217 location. If not successful, an empty config is used.
218 """
219 self.log.debug("Attempting to load config file: <%s>" % self.config_file_name)
220 loader = PyFileConfigLoader(self.config_file_name,
221 path=self.config_file_paths)
222 try:
223 self.file_config = loader.load_config()
224 self.file_config.Global.config_file = loader.full_filename
225 except IOError:
226 # Only warn if the default config file was NOT being used.
227 if not self.config_file_name==self.default_config_file_name:
228 self.log.warn("Config file not found, skipping: <%s>" % \
229 self.config_file_name, exc_info=True)
230 self.file_config = Config()
231 except:
232 self.log.warn("Error loading config file: <%s>" % \
233 self.config_file_name, exc_info=True)
234 self.file_config = Config()
235 else:
236 self.log.debug("Config file loaded: <%s>" % loader.full_filename)
237 self.log.debug(repr(self.file_config))
238 # We need to keeep self.log_level updated. But we only use the value
239 # of the file_config if a value was not specified at the command
240 # line.
241 if not hasattr(self.command_line_config.Global, 'log_level'):
242 try:
243 self.log_level = self.file_config.Global.log_level
244 except AttributeError:
245 pass # Use existing value
246
247 def post_load_file_config(self):
248 """Do actions after the config file is loaded."""
249 pass
250
251 def merge_configs(self):
252 """Merge the default, command line and file config objects."""
253 config = Config()
254 config._merge(self.default_config)
255 config._merge(self.file_config)
256 config._merge(self.command_line_config)
257 self.master_config = config
258 self.log.debug("Master config created:")
259 self.log.debug(repr(self.master_config))
260
261 def pre_construct(self):
262 """Do actions after the config has been built, but before construct."""
263 pass
264
265 def construct(self):
266 """Construct the main components that make up this app."""
267 self.log.debug("Constructing components for application")
268
269 def post_construct(self):
270 """Do actions after construct, but before starting the app."""
271 pass
272
273 def start_app(self):
274 """Actually start the app."""
275 self.log.debug("Starting application")
276
277 #-------------------------------------------------------------------------
278 # Utility methods
279 #-------------------------------------------------------------------------
280
281 def abort(self):
282 """Abort the starting of the application."""
283 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
284 sys.exit(1)
285
286 def exit(self):
287 self.log.critical("Aborting application: %s" % self.name)
288 sys.exit(1)
289
290 def attempt(self, func, action='abort'):
291 try:
292 func()
293 except SystemExit:
294 self.exit()
295 except:
296 if action == 'abort':
297 self.abort()
298 elif action == 'exit':
299 self.exit()
300 No newline at end of file
@@ -0,0 +1,45 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Autocall capabilities for IPython.core.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26
27 #-----------------------------------------------------------------------------
28 # Code
29 #-----------------------------------------------------------------------------
30
31 class IPyAutocall(object):
32 """ Instances of this class are always autocalled
33
34 This happens regardless of 'autocall' variable state. Use this to
35 develop macro-like mechanisms.
36 """
37
38 def set_ip(self,ip):
39 """ Will be used to set _ip point to current ipython instance b/f call
40
41 Override this method if you don't want this to happen.
42
43 """
44 self._ip = ip
45
@@ -0,0 +1,116 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A context manager for managing things injected into :mod:`__builtin__`.
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22 import __builtin__
23
24 from IPython.core.component import Component
25 from IPython.core.quitter import Quitter
26
27 from IPython.utils.autoattr import auto_attr
28
29 #-----------------------------------------------------------------------------
30 # Classes and functions
31 #-----------------------------------------------------------------------------
32
33
34 class BuiltinUndefined(object): pass
35 BuiltinUndefined = BuiltinUndefined()
36
37
38 class BuiltinTrap(Component):
39
40 def __init__(self, parent):
41 super(BuiltinTrap, self).__init__(parent, None, None)
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
46
47 @auto_attr
48 def shell(self):
49 return Component.get_instances(
50 root=self.root,
51 klass='IPython.core.iplib.InteractiveShell')[0]
52
53 def __enter__(self):
54 if self._nested_level == 0:
55 self.set()
56 self._nested_level += 1
57 # I return self, so callers can use add_builtin in a with clause.
58 return self
59
60 def __exit__(self, type, value, traceback):
61 if self._nested_level == 1:
62 self.unset()
63 self._nested_level -= 1
64 return True
65
66 def add_builtin(self, key, value):
67 """Add a builtin and save the original."""
68 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
69 self._orig_builtins[key] = orig
70 __builtin__.__dict__[key] = value
71
72 def remove_builtin(self, key):
73 """Remove an added builtin and re-set the original."""
74 try:
75 orig = self._orig_builtins.pop(key)
76 except KeyError:
77 pass
78 else:
79 if orig is BuiltinUndefined:
80 del __builtin__.__dict__[key]
81 else:
82 __builtin__.__dict__[key] = orig
83
84 def set(self):
85 """Store ipython references in the __builtin__ namespace."""
86 self.add_builtin('exit', Quitter(self.shell, 'exit'))
87 self.add_builtin('quit', Quitter(self.shell, 'quit'))
88
89 # Recursive reload function
90 try:
91 from IPython.lib import deepreload
92 if self.shell.deep_reload:
93 self.add_builtin('reload', deepreload.reload)
94 else:
95 self.add_builtin('dreload', deepreload.reload)
96 del deepreload
97 except ImportError:
98 pass
99
100 # Keep in the builtins a flag for when IPython is active. We set it
101 # with setdefault so that multiple nested IPythons don't clobber one
102 # another. Each will increase its value by one upon being activated,
103 # which also gives us a way to determine the nesting level.
104 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
105
106 def unset(self):
107 """Remove any builtins which might have been added by add_builtins, or
108 restore overwritten ones to their previous values."""
109 for key in self._orig_builtins.keys():
110 self.remove_builtin(key)
111 self._orig_builtins.clear()
112 self._builtins_added = False
113 try:
114 del __builtin__.__dict__['__IPYTHON__active']
115 except KeyError:
116 pass
@@ -0,0 +1,325 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A lightweight component system for IPython.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 from copy import deepcopy
24 import datetime
25 from weakref import WeakValueDictionary
26
27 from IPython.utils.importstring import import_item
28 from IPython.config.loader import Config
29 from IPython.utils.traitlets import (
30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
31 )
32
33
34 #-----------------------------------------------------------------------------
35 # Helper classes for Components
36 #-----------------------------------------------------------------------------
37
38
39 class ComponentError(Exception):
40 pass
41
42 class MetaComponentTracker(type):
43 """A metaclass that tracks instances of Components and its subclasses."""
44
45 def __init__(cls, name, bases, d):
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
47 cls.__instance_refs = WeakValueDictionary()
48 cls.__numcreated = 0
49
50 def __call__(cls, *args, **kw):
51 """Called when a class is called (instantiated)!!!
52
53 When a Component or subclass is instantiated, this is called and
54 the instance is saved in a WeakValueDictionary for tracking.
55 """
56 instance = cls.__new__(cls, *args, **kw)
57
58 # Register the instance before __init__ is called so get_instances
59 # works inside __init__ methods!
60 indices = cls.register_instance(instance)
61
62 # This is in a try/except because of the __init__ method fails, the
63 # instance is discarded and shouldn't be tracked.
64 try:
65 if isinstance(instance, cls):
66 cls.__init__(instance, *args, **kw)
67 except:
68 # Unregister the instance because __init__ failed!
69 cls.unregister_instances(indices)
70 raise
71 else:
72 return instance
73
74 def register_instance(cls, instance):
75 """Register instance with cls and its subclasses."""
76 # indices is a list of the keys used to register the instance
77 # with. This list is needed if the instance needs to be unregistered.
78 indices = []
79 for c in cls.__mro__:
80 if issubclass(cls, c) and issubclass(c, Component):
81 c.__numcreated += 1
82 indices.append(c.__numcreated)
83 c.__instance_refs[c.__numcreated] = instance
84 else:
85 break
86 return indices
87
88 def unregister_instances(cls, indices):
89 """Unregister instance with cls and its subclasses."""
90 for c, index in zip(cls.__mro__, indices):
91 try:
92 del c.__instance_refs[index]
93 except KeyError:
94 pass
95
96 def clear_instances(cls):
97 """Clear all instances tracked by cls."""
98 cls.__instance_refs.clear()
99 cls.__numcreated = 0
100
101 def get_instances(cls, name=None, root=None, klass=None):
102 """Get all instances of cls and its subclasses.
103
104 Parameters
105 ----------
106 name : str
107 Limit to components with this name.
108 root : Component or subclass
109 Limit to components having this root.
110 klass : class or str
111 Limits to instances of the class or its subclasses. If a str
112 is given ut must be in the form 'foo.bar.MyClass'. The str
113 form of this argument is useful for forward declarations.
114 """
115 if klass is not None:
116 if isinstance(klass, basestring):
117 klass = import_item(klass)
118 # Limit search to instances of klass for performance
119 if issubclass(klass, Component):
120 return klass.get_instances(name=name, root=root)
121 instances = cls.__instance_refs.values()
122 if name is not None:
123 instances = [i for i in instances if i.name == name]
124 if klass is not None:
125 instances = [i for i in instances if isinstance(i, klass)]
126 if root is not None:
127 instances = [i for i in instances if i.root == root]
128 return instances
129
130 def get_instances_by_condition(cls, call, name=None, root=None,
131 klass=None):
132 """Get all instances of cls, i such that call(i)==True.
133
134 This also takes the ``name`` and ``root`` and ``classname``
135 arguments of :meth:`get_instance`
136 """
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
138
139
140 def masquerade_as(instance, cls):
141 """Let instance masquerade as an instance of cls.
142
143 Sometimes, such as in testing code, it is useful to let a class
144 masquerade as another. Python, being duck typed, allows this by
145 default. But, instances of components are tracked by their class type.
146
147 After calling this, ``cls.get_instances()`` will return ``instance``. This
148 does not, however, cause ``isinstance(instance, cls)`` to return ``True``.
149
150 Parameters
151 ----------
152 instance : an instance of a Component or Component subclass
153 The instance that will pretend to be a cls.
154 cls : subclass of Component
155 The Component subclass that instance will pretend to be.
156 """
157 cls.register_instance(instance)
158
159
160 class ComponentNameGenerator(object):
161 """A Singleton to generate unique component names."""
162
163 def __init__(self, prefix):
164 self.prefix = prefix
165 self.i = 0
166
167 def __call__(self):
168 count = self.i
169 self.i += 1
170 return "%s%s" % (self.prefix, count)
171
172
173 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
174
175
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
177 pass
178
179
180 #-----------------------------------------------------------------------------
181 # Component implementation
182 #-----------------------------------------------------------------------------
183
184
185 class Component(HasTraitlets):
186
187 __metaclass__ = MetaComponent
188
189 # Traitlets are fun!
190 config = Instance(Config,(),{})
191 parent = This()
192 root = This()
193 created = None
194
195 def __init__(self, parent, name=None, config=None):
196 """Create a component given a parent and possibly and name and config.
197
198 Parameters
199 ----------
200 parent : Component subclass
201 The parent in the component graph. The parent is used
202 to get the root of the component graph.
203 name : str
204 The unique name of the component. If empty, then a unique
205 one will be autogenerated.
206 config : Config
207 If this is empty, self.config = parent.config, otherwise
208 self.config = config and root.config is ignored. This argument
209 should only be used to *override* the automatic inheritance of
210 parent.config. If a caller wants to modify parent.config
211 (not override), the caller should make a copy and change
212 attributes and then pass the copy to this argument.
213
214 Notes
215 -----
216 Subclasses of Component must call the :meth:`__init__` method of
217 :class:`Component` *before* doing anything else and using
218 :func:`super`::
219
220 class MyComponent(Component):
221 def __init__(self, parent, name=None, config=None):
222 super(MyComponent, self).__init__(parent, name, config)
223 # Then any other code you need to finish initialization.
224
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
226 attributes are handled properly.
227 """
228 super(Component, self).__init__()
229 self._children = []
230 if name is None:
231 self.name = ComponentNameGenerator()
232 else:
233 self.name = name
234 self.root = self # This is the default, it is set when parent is set
235 self.parent = parent
236 if config is not None:
237 self.config = config
238 # We used to deepcopy, but for now we are trying to just save
239 # by reference. This *could* have side effects as all components
240 # will share config.
241 # self.config = deepcopy(config)
242 else:
243 if self.parent is not None:
244 self.config = self.parent.config
245 # We used to deepcopy, but for now we are trying to just save
246 # by reference. This *could* have side effects as all components
247 # will share config.
248 # self.config = deepcopy(self.parent.config)
249
250 self.created = datetime.datetime.now()
251
252 #-------------------------------------------------------------------------
253 # Static traitlet notifiations
254 #-------------------------------------------------------------------------
255
256 def _parent_changed(self, name, old, new):
257 if old is not None:
258 old._remove_child(self)
259 if new is not None:
260 new._add_child(self)
261
262 if new is None:
263 self.root = self
264 else:
265 self.root = new.root
266
267 def _root_changed(self, name, old, new):
268 if self.parent is None:
269 if not (new is self):
270 raise ComponentError("Root not self, but parent is None.")
271 else:
272 if not self.parent.root is new:
273 raise ComponentError("Error in setting the root attribute: "
274 "root != parent.root")
275
276 def _config_changed(self, name, old, new):
277 """Update all the class traits having ``config=True`` as metadata.
278
279 For any class traitlet with a ``config`` metadata attribute that is
280 ``True``, we update the traitlet with the value of the corresponding
281 config entry.
282 """
283 # Get all traitlets with a config metadata entry that is True
284 traitlets = self.traitlets(config=True)
285
286 # We auto-load config section for this class as well as any parent
287 # classes that are Component subclasses. This starts with Component
288 # and works down the mro loading the config for each section.
289 section_names = [cls.__name__ for cls in \
290 reversed(self.__class__.__mro__) if
291 issubclass(cls, Component) and issubclass(self.__class__, cls)]
292
293 for sname in section_names:
294 # Don't do a blind getattr as that would cause the config to
295 # dynamically create the section with name self.__class__.__name__.
296 if new._has_section(sname):
297 my_config = new[sname]
298 for k, v in traitlets.items():
299 try:
300 config_value = my_config[k]
301 except KeyError:
302 pass
303 else:
304 # print "Setting %s.%s from %s.%s=%r" % \
305 # (self.__class__.__name__,k,sname,k,config_value)
306 setattr(self, k, config_value)
307
308 @property
309 def children(self):
310 """A list of all my child components."""
311 return self._children
312
313 def _remove_child(self, child):
314 """A private method for removing children components."""
315 if child in self._children:
316 index = self._children.index(child)
317 del self._children[index]
318
319 def _add_child(self, child):
320 """A private method for adding children components."""
321 if child not in self._children:
322 self._children.append(child)
323
324 def __repr__(self):
325 return "<%s('%s')>" % (self.__class__.__name__, self.name)
@@ -0,0 +1,76 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A context manager for handling sys.displayhook.
5
6 Authors:
7
8 * Robert Kern
9 * Brian Granger
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import sys
24
25 from IPython.core.component import Component
26
27 from IPython.utils.autoattr import auto_attr
28
29 #-----------------------------------------------------------------------------
30 # Classes and functions
31 #-----------------------------------------------------------------------------
32
33
34 class DisplayTrap(Component):
35 """Object to manage sys.displayhook.
36
37 This came from IPython.core.kernel.display_hook, but is simplified
38 (no callbacks or formatters) until more of the core is refactored.
39 """
40
41 def __init__(self, parent, hook):
42 super(DisplayTrap, self).__init__(parent, None, None)
43 self.hook = hook
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
48
49 @auto_attr
50 def shell(self):
51 return Component.get_instances(
52 root=self.root,
53 klass='IPython.core.iplib.InteractiveShell')[0]
54
55 def __enter__(self):
56 if self._nested_level == 0:
57 self.set()
58 self._nested_level += 1
59 return self
60
61 def __exit__(self, type, value, traceback):
62 if self._nested_level == 1:
63 self.unset()
64 self._nested_level -= 1
65 return True
66
67 def set(self):
68 """Set the hook."""
69 if sys.displayhook is not self.hook:
70 self.old_hook = sys.displayhook
71 sys.displayhook = self.hook
72
73 def unset(self):
74 """Unset the hook."""
75 sys.displayhook = self.old_hook
76
@@ -0,0 +1,280 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 An embedded IPython shell.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 from __future__ import with_statement
27
28 import sys
29 from contextlib import nested
30
31 from IPython.core import ultratb
32 from IPython.core.iplib import InteractiveShell
33 from IPython.core.ipapp import load_default_config
34
35 from IPython.utils.traitlets import Bool, Str, CBool
36 from IPython.utils.genutils import ask_yes_no
37
38
39 #-----------------------------------------------------------------------------
40 # Classes and functions
41 #-----------------------------------------------------------------------------
42
43 # This is an additional magic that is exposed in embedded shells.
44 def kill_embedded(self,parameter_s=''):
45 """%kill_embedded : deactivate for good the current embedded IPython.
46
47 This function (after asking for confirmation) sets an internal flag so that
48 an embedded IPython will never activate again. This is useful to
49 permanently disable a shell that is being called inside a loop: once you've
50 figured out what you needed from it, you may then kill it and the program
51 will then continue to run without the interactive shell interfering again.
52 """
53
54 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
55 "(y/n)? [y/N] ",'n')
56 if kill:
57 self.embedded_active = False
58 print "This embedded IPython will not reactivate anymore once you exit."
59
60
61 class InteractiveShellEmbed(InteractiveShell):
62
63 dummy_mode = Bool(False)
64 exit_msg = Str('')
65 embedded = CBool(True)
66 embedded_active = CBool(True)
67 # Like the base class display_banner is not configurable, but here it
68 # is True by default.
69 display_banner = CBool(True)
70
71 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
72 user_ns=None, user_global_ns=None,
73 banner1=None, banner2=None, display_banner=None,
74 custom_exceptions=((),None), exit_msg=''):
75
76 self.save_sys_ipcompleter()
77
78 super(InteractiveShellEmbed,self).__init__(
79 parent=parent, config=config, ipythondir=ipythondir, usage=usage,
80 user_ns=user_ns, user_global_ns=user_global_ns,
81 banner1=banner1, banner2=banner2, display_banner=display_banner,
82 custom_exceptions=custom_exceptions)
83
84 self.exit_msg = exit_msg
85 self.define_magic("kill_embedded", kill_embedded)
86
87 # don't use the ipython crash handler so that user exceptions aren't
88 # trapped
89 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
90 mode=self.xmode,
91 call_pdb=self.pdb)
92
93 self.restore_sys_ipcompleter()
94
95 def init_sys_modules(self):
96 pass
97
98 def save_sys_ipcompleter(self):
99 """Save readline completer status."""
100 try:
101 #print 'Save completer',sys.ipcompleter # dbg
102 self.sys_ipcompleter_orig = sys.ipcompleter
103 except:
104 pass # not nested with IPython
105
106 def restore_sys_ipcompleter(self):
107 """Restores the readline completer which was in place.
108
109 This allows embedded IPython within IPython not to disrupt the
110 parent's completion.
111 """
112 try:
113 self.readline.set_completer(self.sys_ipcompleter_orig)
114 sys.ipcompleter = self.sys_ipcompleter_orig
115 except:
116 pass
117
118 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
119 stack_depth=1):
120 """Activate the interactive interpreter.
121
122 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
123 the interpreter shell with the given local and global namespaces, and
124 optionally print a header string at startup.
125
126 The shell can be globally activated/deactivated using the
127 set/get_dummy_mode methods. This allows you to turn off a shell used
128 for debugging globally.
129
130 However, *each* time you call the shell you can override the current
131 state of dummy_mode with the optional keyword parameter 'dummy'. For
132 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
133 can still have a specific call work by making it as IPShell(dummy=0).
134
135 The optional keyword parameter dummy controls whether the call
136 actually does anything.
137 """
138
139 # If the user has turned it off, go away
140 if not self.embedded_active:
141 return
142
143 # Normal exits from interactive mode set this flag, so the shell can't
144 # re-enter (it checks this variable at the start of interactive mode).
145 self.exit_now = False
146
147 # Allow the dummy parameter to override the global __dummy_mode
148 if dummy or (dummy != 0 and self.dummy_mode):
149 return
150
151 if self.has_readline:
152 self.set_completer()
153
154 # self.banner is auto computed
155 if header:
156 self.old_banner2 = self.banner2
157 self.banner2 = self.banner2 + '\n' + header + '\n'
158
159 # Call the embedding code with a stack depth of 1 so it can skip over
160 # our call and get the original caller's namespaces.
161 self.mainloop(local_ns, global_ns, stack_depth=stack_depth)
162
163 self.banner2 = self.old_banner2
164
165 if self.exit_msg is not None:
166 print self.exit_msg
167
168 self.restore_sys_ipcompleter()
169
170 def mainloop(self, local_ns=None, global_ns=None, stack_depth=0,
171 display_banner=None):
172 """Embeds IPython into a running python program.
173
174 Input:
175
176 - header: An optional header message can be specified.
177
178 - local_ns, global_ns: working namespaces. If given as None, the
179 IPython-initialized one is updated with __main__.__dict__, so that
180 program variables become visible but user-specific configuration
181 remains possible.
182
183 - stack_depth: specifies how many levels in the stack to go to
184 looking for namespaces (when local_ns and global_ns are None). This
185 allows an intermediate caller to make sure that this function gets
186 the namespace from the intended level in the stack. By default (0)
187 it will get its locals and globals from the immediate caller.
188
189 Warning: it's possible to use this in a program which is being run by
190 IPython itself (via %run), but some funny things will happen (a few
191 globals get overwritten). In the future this will be cleaned up, as
192 there is no fundamental reason why it can't work perfectly."""
193
194 # Get locals and globals from caller
195 if local_ns is None or global_ns is None:
196 call_frame = sys._getframe(stack_depth).f_back
197
198 if local_ns is None:
199 local_ns = call_frame.f_locals
200 if global_ns is None:
201 global_ns = call_frame.f_globals
202
203 # Update namespaces and fire up interpreter
204
205 # The global one is easy, we can just throw it in
206 self.user_global_ns = global_ns
207
208 # but the user/local one is tricky: ipython needs it to store internal
209 # data, but we also need the locals. We'll copy locals in the user
210 # one, but will track what got copied so we can delete them at exit.
211 # This is so that a later embedded call doesn't see locals from a
212 # previous call (which most likely existed in a separate scope).
213 local_varnames = local_ns.keys()
214 self.user_ns.update(local_ns)
215 #self.user_ns['local_ns'] = local_ns # dbg
216
217 # Patch for global embedding to make sure that things don't overwrite
218 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
219 # FIXME. Test this a bit more carefully (the if.. is new)
220 if local_ns is None and global_ns is None:
221 self.user_global_ns.update(__main__.__dict__)
222
223 # make sure the tab-completer has the correct frame information, so it
224 # actually completes using the frame's locals/globals
225 self.set_completer_frame()
226
227 with nested(self.builtin_trap, self.display_trap):
228 self.interact(display_banner=display_banner)
229
230 # now, purge out the user namespace from anything we might have added
231 # from the caller's local namespace
232 delvar = self.user_ns.pop
233 for var in local_varnames:
234 delvar(var,None)
235
236 def set_completer_frame(self, frame=None):
237 if frame:
238 self.Completer.namespace = frame.f_locals
239 self.Completer.global_namespace = frame.f_globals
240 else:
241 self.Completer.namespace = self.user_ns
242 self.Completer.global_namespace = self.user_global_ns
243
244
245 _embedded_shell = None
246
247
248 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
249 display_banner=True, exit_msg=''):
250 """Call this to embed IPython at the current point in your program.
251
252 The first invocation of this will create an :class:`InteractiveShellEmbed`
253 instance and then call it. Consecutive calls just call the already
254 created instance.
255
256 Here is a simple example::
257
258 from IPython import embed
259 a = 10
260 b = 20
261 embed('First time')
262 c = 30
263 d = 40
264 embed
265
266 Full customization can be done by passing a :class:`Struct` in as the
267 config argument.
268 """
269 if config is None:
270 config = load_default_config()
271 config.InteractiveShellEmbed = config.InteractiveShell
272 global _embedded_shell
273 if _embedded_shell is None:
274 _embedded_shell = InteractiveShellEmbed(
275 config=config, usage=usage,
276 banner1=banner1, banner2=banner2,
277 display_banner=display_banner, exit_msg=exit_msg
278 )
279 _embedded_shell(header=header, stack_depth=2)
280
@@ -0,0 +1,52 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Global exception classes for IPython.core.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 #-----------------------------------------------------------------------------
27 # Exception classes
28 #-----------------------------------------------------------------------------
29
30 class IPythonCoreError(Exception):
31 pass
32
33
34 class TryNext(IPythonCoreError):
35 """Try next hook exception.
36
37 Raise this in your hook function to indicate that the next hook handler
38 should be used to handle the operation. If you pass arguments to the
39 constructor those arguments will be used by the next hook instead of the
40 original ones.
41 """
42
43 def __init__(self, *args, **kwargs):
44 self.args = args
45 self.kwargs = kwargs
46
47 class UsageError(IPythonCoreError):
48 """Error in magic function arguments, etc.
49
50 Something that probably won't warrant a full traceback, but should
51 nevertheless interrupt a macro / batch file.
52 """ No newline at end of file
This diff has been collapsed as it changes many lines, (546 lines changed) Show them Hide them
@@ -0,0 +1,546 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 The main IPython application object
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13 """
14
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
21
22 #-----------------------------------------------------------------------------
23 # Imports
24 #-----------------------------------------------------------------------------
25
26 import logging
27 import os
28 import sys
29 import warnings
30
31 from IPython.core.application import Application, IPythonArgParseConfigLoader
32 from IPython.core import release
33 from IPython.core.iplib import InteractiveShell
34 from IPython.config.loader import (
35 NoConfigDefault,
36 Config,
37 ConfigError,
38 PyFileConfigLoader
39 )
40
41 from IPython.lib import inputhook
42
43 from IPython.utils.ipstruct import Struct
44 from IPython.utils.genutils import filefind, get_ipython_dir
45
46 #-----------------------------------------------------------------------------
47 # Utilities and helpers
48 #-----------------------------------------------------------------------------
49
50
51 ipython_desc = """
52 A Python shell with automatic history (input and output), dynamic object
53 introspection, easier configuration, command completion, access to the system
54 shell and more.
55 """
56
57 def pylab_warning():
58 msg = """
59
60 IPython's -pylab mode has been disabled until matplotlib supports this version
61 of IPython. This version of IPython has greatly improved GUI integration that
62 matplotlib will soon be able to take advantage of. This will eventually
63 result in greater stability and a richer API for matplotlib under IPython.
64 However during this transition, you will either need to use an older version
65 of IPython, or do the following to use matplotlib interactively::
66
67 import matplotlib
68 matplotlib.interactive(True)
69 matplotlib.use('wxagg') # adjust for your backend
70 %gui -a wx # adjust for your GUI
71 from matplotlib import pyplot as plt
72
73 See the %gui magic for information on the new interface.
74 """
75 warnings.warn(msg, category=DeprecationWarning, stacklevel=1)
76
77
78 #-----------------------------------------------------------------------------
79 # Main classes and functions
80 #-----------------------------------------------------------------------------
81
82 cl_args = (
83 (('-autocall',), dict(
84 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
85 help='Set the autocall value (0,1,2).',
86 metavar='InteractiveShell.autocall')
87 ),
88 (('-autoindent',), dict(
89 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
90 help='Turn on autoindenting.')
91 ),
92 (('-noautoindent',), dict(
93 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
94 help='Turn off autoindenting.')
95 ),
96 (('-automagic',), dict(
97 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
98 help='Turn on the auto calling of magic commands.')
99 ),
100 (('-noautomagic',), dict(
101 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
102 help='Turn off the auto calling of magic commands.')
103 ),
104 (('-autoedit_syntax',), dict(
105 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
106 help='Turn on auto editing of files with syntax errors.')
107 ),
108 (('-noautoedit_syntax',), dict(
109 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
110 help='Turn off auto editing of files with syntax errors.')
111 ),
112 (('-banner',), dict(
113 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
114 help='Display a banner upon starting IPython.')
115 ),
116 (('-nobanner',), dict(
117 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
118 help="Don't display a banner upon starting IPython.")
119 ),
120 (('-cache_size',), dict(
121 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
122 help="Set the size of the output cache.",
123 metavar='InteractiveShell.cache_size')
124 ),
125 (('-classic',), dict(
126 action='store_true', dest='Global.classic', default=NoConfigDefault,
127 help="Gives IPython a similar feel to the classic Python prompt.")
128 ),
129 (('-colors',), dict(
130 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
131 help="Set the color scheme (NoColor, Linux, and LightBG).",
132 metavar='InteractiveShell.colors')
133 ),
134 (('-color_info',), dict(
135 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
136 help="Enable using colors for info related things.")
137 ),
138 (('-nocolor_info',), dict(
139 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
140 help="Disable using colors for info related things.")
141 ),
142 (('-confirm_exit',), dict(
143 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
144 help="Prompt the user when existing.")
145 ),
146 (('-noconfirm_exit',), dict(
147 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
148 help="Don't prompt the user when existing.")
149 ),
150 (('-deep_reload',), dict(
151 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
152 help="Enable deep (recursive) reloading by default.")
153 ),
154 (('-nodeep_reload',), dict(
155 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
156 help="Disable deep (recursive) reloading by default.")
157 ),
158 (('-editor',), dict(
159 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
160 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
161 metavar='InteractiveShell.editor')
162 ),
163 (('-log','-l'), dict(
164 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
165 help="Start logging to the default file (./ipython_log.py).")
166 ),
167 (('-logfile','-lf'), dict(
168 type=str, dest='InteractiveShell.logfile', default=NoConfigDefault,
169 help="Start logging to logfile.",
170 metavar='InteractiveShell.logfile')
171 ),
172 (('-logappend','-la'), dict(
173 type=str, dest='InteractiveShell.logappend', default=NoConfigDefault,
174 help="Start logging to logappend in append mode.",
175 metavar='InteractiveShell.logfile')
176 ),
177 (('-pdb',), dict(
178 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
179 help="Enable auto calling the pdb debugger after every exception.")
180 ),
181 (('-nopdb',), dict(
182 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
183 help="Disable auto calling the pdb debugger after every exception.")
184 ),
185 (('-pprint',), dict(
186 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
187 help="Enable auto pretty printing of results.")
188 ),
189 (('-nopprint',), dict(
190 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
191 help="Disable auto auto pretty printing of results.")
192 ),
193 (('-prompt_in1','-pi1'), dict(
194 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
195 help="Set the main input prompt ('In [\#]: ')",
196 metavar='InteractiveShell.prompt_in1')
197 ),
198 (('-prompt_in2','-pi2'), dict(
199 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
200 help="Set the secondary input prompt (' .\D.: ')",
201 metavar='InteractiveShell.prompt_in2')
202 ),
203 (('-prompt_out','-po'), dict(
204 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
205 help="Set the output prompt ('Out[\#]:')",
206 metavar='InteractiveShell.prompt_out')
207 ),
208 (('-quick',), dict(
209 action='store_true', dest='Global.quick', default=NoConfigDefault,
210 help="Enable quick startup with no config files.")
211 ),
212 (('-readline',), dict(
213 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
214 help="Enable readline for command line usage.")
215 ),
216 (('-noreadline',), dict(
217 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
218 help="Disable readline for command line usage.")
219 ),
220 (('-screen_length','-sl'), dict(
221 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
222 help='Number of lines on screen, used to control printing of long strings.',
223 metavar='InteractiveShell.screen_length')
224 ),
225 (('-separate_in','-si'), dict(
226 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
227 help="Separator before input prompts. Default '\n'.",
228 metavar='InteractiveShell.separate_in')
229 ),
230 (('-separate_out','-so'), dict(
231 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
232 help="Separator before output prompts. Default 0 (nothing).",
233 metavar='InteractiveShell.separate_out')
234 ),
235 (('-separate_out2','-so2'), dict(
236 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
237 help="Separator after output prompts. Default 0 (nonight).",
238 metavar='InteractiveShell.separate_out2')
239 ),
240 (('-nosep',), dict(
241 action='store_true', dest='Global.nosep', default=NoConfigDefault,
242 help="Eliminate all spacing between prompts.")
243 ),
244 (('-term_title',), dict(
245 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
246 help="Enable auto setting the terminal title.")
247 ),
248 (('-noterm_title',), dict(
249 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
250 help="Disable auto setting the terminal title.")
251 ),
252 (('-xmode',), dict(
253 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
254 help="Exception mode ('Plain','Context','Verbose')",
255 metavar='InteractiveShell.xmode')
256 ),
257 (('-ext',), dict(
258 type=str, dest='Global.extra_extension', default=NoConfigDefault,
259 help="The dotted module name of an IPython extension to load.",
260 metavar='Global.extra_extension')
261 ),
262 (('-c',), dict(
263 type=str, dest='Global.code_to_run', default=NoConfigDefault,
264 help="Execute the given command string.",
265 metavar='Global.code_to_run')
266 ),
267 (('-i',), dict(
268 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
269 help="If running code from the command line, become interactive afterwards.")
270 ),
271 (('-wthread',), dict(
272 action='store_true', dest='Global.wthread', default=NoConfigDefault,
273 help="Enable wxPython event loop integration.")
274 ),
275 (('-q4thread','-qthread'), dict(
276 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
277 help="Enable Qt4 event loop integration. Qt3 is no longer supported.")
278 ),
279 (('-gthread',), dict(
280 action='store_true', dest='Global.gthread', default=NoConfigDefault,
281 help="Enable GTK event loop integration.")
282 ),
283 # # These are only here to get the proper deprecation warnings
284 (('-pylab',), dict(
285 action='store_true', dest='Global.pylab', default=NoConfigDefault,
286 help="Disabled. Pylab has been disabled until matplotlib supports this version of IPython.")
287 )
288 )
289
290
291 class IPythonAppCLConfigLoader(IPythonArgParseConfigLoader):
292
293 arguments = cl_args
294
295
296 _default_config_file_name = 'ipython_config.py'
297
298 class IPythonApp(Application):
299 name = 'ipython'
300 config_file_name = _default_config_file_name
301
302 def create_default_config(self):
303 super(IPythonApp, self).create_default_config()
304 self.default_config.Global.display_banner = True
305
306 # If the -c flag is given or a file is given to run at the cmd line
307 # like "ipython foo.py", normally we exit without starting the main
308 # loop. The force_interact config variable allows a user to override
309 # this and interact. It is also set by the -i cmd line flag, just
310 # like Python.
311 self.default_config.Global.force_interact = False
312
313 # By default always interact by starting the IPython mainloop.
314 self.default_config.Global.interact = True
315
316 # Let the parent class set the default, but each time log_level
317 # changes from config, we need to update self.log_level as that is
318 # what updates the actual log level in self.log.
319 self.default_config.Global.log_level = self.log_level
320
321 # No GUI integration by default
322 self.default_config.Global.wthread = False
323 self.default_config.Global.q4thread = False
324 self.default_config.Global.gthread = False
325
326 def create_command_line_config(self):
327 """Create and return a command line config loader."""
328 return IPythonAppCLConfigLoader(
329 description=ipython_desc,
330 version=release.version)
331
332 def post_load_command_line_config(self):
333 """Do actions after loading cl config."""
334 clc = self.command_line_config
335
336 # Display the deprecation warnings about threaded shells
337 if hasattr(clc.Global, 'pylab'):
338 pylab_warning()
339 del clc.Global['pylab']
340
341 def load_file_config(self):
342 if hasattr(self.command_line_config.Global, 'quick'):
343 if self.command_line_config.Global.quick:
344 self.file_config = Config()
345 return
346 super(IPythonApp, self).load_file_config()
347
348 def post_load_file_config(self):
349 if hasattr(self.command_line_config.Global, 'extra_extension'):
350 if not hasattr(self.file_config.Global, 'extensions'):
351 self.file_config.Global.extensions = []
352 self.file_config.Global.extensions.append(
353 self.command_line_config.Global.extra_extension)
354 del self.command_line_config.Global.extra_extension
355
356 def pre_construct(self):
357 config = self.master_config
358
359 if hasattr(config.Global, 'classic'):
360 if config.Global.classic:
361 config.InteractiveShell.cache_size = 0
362 config.InteractiveShell.pprint = 0
363 config.InteractiveShell.prompt_in1 = '>>> '
364 config.InteractiveShell.prompt_in2 = '... '
365 config.InteractiveShell.prompt_out = ''
366 config.InteractiveShell.separate_in = \
367 config.InteractiveShell.separate_out = \
368 config.InteractiveShell.separate_out2 = ''
369 config.InteractiveShell.colors = 'NoColor'
370 config.InteractiveShell.xmode = 'Plain'
371
372 if hasattr(config.Global, 'nosep'):
373 if config.Global.nosep:
374 config.InteractiveShell.separate_in = \
375 config.InteractiveShell.separate_out = \
376 config.InteractiveShell.separate_out2 = ''
377
378 # if there is code of files to run from the cmd line, don't interact
379 # unless the -i flag (Global.force_interact) is true.
380 code_to_run = config.Global.get('code_to_run','')
381 file_to_run = False
382 if len(self.extra_args)>=1:
383 if self.extra_args[0]:
384 file_to_run = True
385 if file_to_run or code_to_run:
386 if not config.Global.force_interact:
387 config.Global.interact = False
388
389 def construct(self):
390 # I am a little hesitant to put these into InteractiveShell itself.
391 # But that might be the place for them
392 sys.path.insert(0, '')
393
394 # Create an InteractiveShell instance
395 self.shell = InteractiveShell(
396 parent=None,
397 config=self.master_config
398 )
399
400 def post_construct(self):
401 """Do actions after construct, but before starting the app."""
402 config = self.master_config
403
404 # shell.display_banner should always be False for the terminal
405 # based app, because we call shell.show_banner() by hand below
406 # so the banner shows *before* all extension loading stuff.
407 self.shell.display_banner = False
408
409 if config.Global.display_banner and \
410 config.Global.interact:
411 self.shell.show_banner()
412
413 # Make sure there is a space below the banner.
414 if self.log_level <= logging.INFO: print
415
416 # Now a variety of things that happen after the banner is printed.
417 self._enable_gui()
418 self._load_extensions()
419 self._run_exec_lines()
420 self._run_exec_files()
421 self._run_cmd_line_code()
422
423 def _enable_gui(self):
424 """Enable GUI event loop integration."""
425 config = self.master_config
426 try:
427 # Enable GUI integration
428 if config.Global.wthread:
429 self.log.info("Enabling wx GUI event loop integration")
430 inputhook.enable_wx(app=True)
431 elif config.Global.q4thread:
432 self.log.info("Enabling Qt4 GUI event loop integration")
433 inputhook.enable_qt4(app=True)
434 elif config.Global.gthread:
435 self.log.info("Enabling GTK GUI event loop integration")
436 inputhook.enable_gtk(app=True)
437 except:
438 self.log.warn("Error in enabling GUI event loop integration:")
439 self.shell.showtraceback()
440
441 def _load_extensions(self):
442 """Load all IPython extensions in Global.extensions.
443
444 This uses the :meth:`InteractiveShell.load_extensions` to load all
445 the extensions listed in ``self.master_config.Global.extensions``.
446 """
447 try:
448 if hasattr(self.master_config.Global, 'extensions'):
449 self.log.debug("Loading IPython extensions...")
450 extensions = self.master_config.Global.extensions
451 for ext in extensions:
452 try:
453 self.log.info("Loading IPython extension: %s" % ext)
454 self.shell.load_extension(ext)
455 except:
456 self.log.warn("Error in loading extension: %s" % ext)
457 self.shell.showtraceback()
458 except:
459 self.log.warn("Unknown error in loading extensions:")
460 self.shell.showtraceback()
461
462 def _run_exec_lines(self):
463 """Run lines of code in Global.exec_lines in the user's namespace."""
464 try:
465 if hasattr(self.master_config.Global, 'exec_lines'):
466 self.log.debug("Running code from Global.exec_lines...")
467 exec_lines = self.master_config.Global.exec_lines
468 for line in exec_lines:
469 try:
470 self.log.info("Running code in user namespace: %s" % line)
471 self.shell.runlines(line)
472 except:
473 self.log.warn("Error in executing line in user namespace: %s" % line)
474 self.shell.showtraceback()
475 except:
476 self.log.warn("Unknown error in handling Global.exec_lines:")
477 self.shell.showtraceback()
478
479 def _exec_file(self, fname):
480 full_filename = filefind(fname, ['.', self.ipythondir])
481 if os.path.isfile(full_filename):
482 if full_filename.endswith('.py'):
483 self.log.info("Running file in user namespace: %s" % full_filename)
484 self.shell.safe_execfile(full_filename, self.shell.user_ns)
485 elif full_filename.endswith('.ipy'):
486 self.log.info("Running file in user namespace: %s" % full_filename)
487 self.shell.safe_execfile_ipy(full_filename)
488 else:
489 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
490
491 def _run_exec_files(self):
492 try:
493 if hasattr(self.master_config.Global, 'exec_files'):
494 self.log.debug("Running files in Global.exec_files...")
495 exec_files = self.master_config.Global.exec_files
496 for fname in exec_files:
497 self._exec_file(fname)
498 except:
499 self.log.warn("Unknown error in handling Global.exec_files:")
500 self.shell.showtraceback()
501
502 def _run_cmd_line_code(self):
503 if hasattr(self.master_config.Global, 'code_to_run'):
504 line = self.master_config.Global.code_to_run
505 try:
506 self.log.info("Running code given at command line (-c): %s" % line)
507 self.shell.runlines(line)
508 except:
509 self.log.warn("Error in executing line in user namespace: %s" % line)
510 self.shell.showtraceback()
511 return
512 # Like Python itself, ignore the second if the first of these is present
513 try:
514 fname = self.extra_args[0]
515 except:
516 pass
517 else:
518 try:
519 self._exec_file(fname)
520 except:
521 self.log.warn("Error in executing file in user namespace: %s" % fname)
522 self.shell.showtraceback()
523
524 def start_app(self):
525 if self.master_config.Global.interact:
526 self.log.debug("Starting IPython's mainloop...")
527 self.shell.mainloop()
528
529
530 def load_default_config(ipythondir=None):
531 """Load the default config file from the default ipythondir.
532
533 This is useful for embedded shells.
534 """
535 if ipythondir is None:
536 ipythondir = get_ipython_dir()
537 cl = PyFileConfigLoader(_default_config_file_name, ipythondir)
538 config = cl.load_config()
539 return config
540
541
542 def launch_new_instance():
543 """Create a run a full blown IPython instance"""
544 app = IPythonApp()
545 app.start()
546
@@ -0,0 +1,219 b''
1 # -*- coding: utf-8 -*-
2 """
3 Main IPython Component
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 import glob
20 import os
21 import shutil
22 import sys
23
24 from IPython.utils.genutils import *
25
26 def user_setup(ipythondir,rc_suffix,mode='install',interactive=True):
27 """Install or upgrade the user configuration directory.
28
29 Can be called when running for the first time or to upgrade the user's
30 .ipython/ directory.
31
32 Parameters
33 ----------
34 ipythondir : path
35 The directory to be used for installation/upgrade. In 'install' mode,
36 if this path already exists, the function exits immediately.
37
38 rc_suffix : str
39 Extension for the config files. On *nix platforms it is typically the
40 empty string, while Windows normally uses '.ini'.
41
42 mode : str, optional
43 Valid modes are 'install' and 'upgrade'.
44
45 interactive : bool, optional
46 If False, do not wait for user input on any errors. Normally after
47 printing its status information, this function waits for the user to
48 hit Return before proceeding. This is because the default use case is
49 when first installing the IPython configuration, so we want the user to
50 acknowledge the initial message, which contains some useful
51 information.
52 """
53
54 # For automatic use, deactivate all i/o
55 if interactive:
56 def wait():
57 try:
58 raw_input("Please press <RETURN> to start IPython.")
59 except EOFError:
60 print >> Term.cout
61 print '*'*70
62
63 def printf(s):
64 print s
65 else:
66 wait = lambda : None
67 printf = lambda s : None
68
69 # Install mode should be re-entrant: if the install dir already exists,
70 # bail out cleanly.
71 # XXX. This is too hasty to return. We need to check to make sure that
72 # all the expected config files and directories are actually there. We
73 # currently have a failure mode if someone deletes a needed config file
74 # but still has the ipythondir.
75 if mode == 'install' and os.path.isdir(ipythondir):
76 return
77
78 cwd = os.getcwd() # remember where we started
79 glb = glob.glob
80
81 printf('*'*70)
82 if mode == 'install':
83 printf(
84 """Welcome to IPython. I will try to create a personal configuration directory
85 where you can customize many aspects of IPython's functionality in:\n""")
86 else:
87 printf('I am going to upgrade your configuration in:')
88
89 printf(ipythondir)
90
91 rcdirend = os.path.join('IPython','config','userconfig')
92 cfg = lambda d: os.path.join(d,rcdirend)
93 try:
94 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
95 printf("Initializing from configuration: %s" % rcdir)
96 except IndexError:
97 warning = """
98 Installation error. IPython's directory was not found.
99
100 Check the following:
101
102 The ipython/IPython directory should be in a directory belonging to your
103 PYTHONPATH environment variable (that is, it should be in a directory
104 belonging to sys.path). You can copy it explicitly there or just link to it.
105
106 IPython will create a minimal default configuration for you.
107
108 """
109 warn(warning)
110 wait()
111
112 if sys.platform =='win32':
113 inif = 'ipythonrc.ini'
114 else:
115 inif = 'ipythonrc'
116 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults',
117 inif : '# intentionally left blank' }
118 os.makedirs(ipythondir, mode = 0777)
119 for f, cont in minimal_setup.items():
120 # In 2.5, this can be more cleanly done using 'with'
121 fobj = file(ipythondir + '/' + f,'w')
122 fobj.write(cont)
123 fobj.close()
124
125 return
126
127 if mode == 'install':
128 try:
129 shutil.copytree(rcdir,ipythondir)
130 os.chdir(ipythondir)
131 rc_files = glb("ipythonrc*")
132 for rc_file in rc_files:
133 os.rename(rc_file,rc_file+rc_suffix)
134 except:
135 warning = """
136
137 There was a problem with the installation:
138 %s
139 Try to correct it or contact the developers if you think it's a bug.
140 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
141 warn(warning)
142 wait()
143 return
144
145 elif mode == 'upgrade':
146 try:
147 os.chdir(ipythondir)
148 except:
149 printf("""
150 Can not upgrade: changing to directory %s failed. Details:
151 %s
152 """ % (ipythondir,sys.exc_info()[1]) )
153 wait()
154 return
155 else:
156 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
157 for new_full_path in sources:
158 new_filename = os.path.basename(new_full_path)
159 if new_filename.startswith('ipythonrc'):
160 new_filename = new_filename + rc_suffix
161 # The config directory should only contain files, skip any
162 # directories which may be there (like CVS)
163 if os.path.isdir(new_full_path):
164 continue
165 if os.path.exists(new_filename):
166 old_file = new_filename+'.old'
167 if os.path.exists(old_file):
168 os.remove(old_file)
169 os.rename(new_filename,old_file)
170 shutil.copy(new_full_path,new_filename)
171 else:
172 raise ValueError('unrecognized mode for install: %r' % mode)
173
174 # Fix line-endings to those native to each platform in the config
175 # directory.
176 try:
177 os.chdir(ipythondir)
178 except:
179 printf("""
180 Problem: changing to directory %s failed.
181 Details:
182 %s
183
184 Some configuration files may have incorrect line endings. This should not
185 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1]) )
186 wait()
187 else:
188 for fname in glb('ipythonrc*'):
189 try:
190 native_line_ends(fname,backup=0)
191 except IOError:
192 pass
193
194 if mode == 'install':
195 printf("""
196 Successful installation!
197
198 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
199 IPython manual (there are both HTML and PDF versions supplied with the
200 distribution) to make sure that your system environment is properly configured
201 to take advantage of IPython's features.
202
203 Important note: the configuration system has changed! The old system is
204 still in place, but its setting may be partly overridden by the settings in
205 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
206 if some of the new settings bother you.
207
208 """)
209 else:
210 printf("""
211 Successful upgrade!
212
213 All files in your directory:
214 %(ipythondir)s
215 which would have been overwritten by the upgrade were backed up with a .old
216 extension. If you had made particular customizations in those files you may
217 want to merge them back into the new files.""" % locals() )
218 wait()
219 os.chdir(cwd) No newline at end of file
@@ -0,0 +1,308 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Paging capabilities for IPython.core
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10
11 Notes
12 -----
13
14 For now this uses ipapi, so it can't be in IPython.utils. If we can get
15 rid of that dependency, we could move it there.
16 -----
17 """
18
19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2008-2009 The IPython Development Team
21 #
22 # Distributed under the terms of the BSD License. The full license is in
23 # the file COPYING, distributed as part of this software.
24 #-----------------------------------------------------------------------------
25
26 #-----------------------------------------------------------------------------
27 # Imports
28 #-----------------------------------------------------------------------------
29
30 import os
31 import re
32 import sys
33
34 from IPython.core import ipapi
35 from IPython.core.error import TryNext
36 from IPython.utils.genutils import (
37 chop, Term, USE_CURSES
38 )
39
40 if os.name == "nt":
41 from IPython.utils.winconsole import get_console_size
42
43
44 #-----------------------------------------------------------------------------
45 # Classes and functions
46 #-----------------------------------------------------------------------------
47
48 esc_re = re.compile(r"(\x1b[^m]+m)")
49
50 def page_dumb(strng,start=0,screen_lines=25):
51 """Very dumb 'pager' in Python, for when nothing else works.
52
53 Only moves forward, same interface as page(), except for pager_cmd and
54 mode."""
55
56 out_ln = strng.splitlines()[start:]
57 screens = chop(out_ln,screen_lines-1)
58 if len(screens) == 1:
59 print >>Term.cout, os.linesep.join(screens[0])
60 else:
61 last_escape = ""
62 for scr in screens[0:-1]:
63 hunk = os.linesep.join(scr)
64 print >>Term.cout, last_escape + hunk
65 if not page_more():
66 return
67 esc_list = esc_re.findall(hunk)
68 if len(esc_list) > 0:
69 last_escape = esc_list[-1]
70 print >>Term.cout, last_escape + os.linesep.join(screens[-1])
71
72 #----------------------------------------------------------------------------
73 def page(strng,start=0,screen_lines=0,pager_cmd = None):
74 """Print a string, piping through a pager after a certain length.
75
76 The screen_lines parameter specifies the number of *usable* lines of your
77 terminal screen (total lines minus lines you need to reserve to show other
78 information).
79
80 If you set screen_lines to a number <=0, page() will try to auto-determine
81 your screen size and will only use up to (screen_size+screen_lines) for
82 printing, paging after that. That is, if you want auto-detection but need
83 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
84 auto-detection without any lines reserved simply use screen_lines = 0.
85
86 If a string won't fit in the allowed lines, it is sent through the
87 specified pager command. If none given, look for PAGER in the environment,
88 and ultimately default to less.
89
90 If no system pager works, the string is sent through a 'dumb pager'
91 written in python, very simplistic.
92 """
93
94 # Some routines may auto-compute start offsets incorrectly and pass a
95 # negative value. Offset to 0 for robustness.
96 start = max(0,start)
97
98 # first, try the hook
99 ip = ipapi.get()
100 if ip:
101 try:
102 ip.hooks.show_in_pager(strng)
103 return
104 except TryNext:
105 pass
106
107 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
108 TERM = os.environ.get('TERM','dumb')
109 if TERM in ['dumb','emacs'] and os.name != 'nt':
110 print strng
111 return
112 # chop off the topmost part of the string we don't want to see
113 str_lines = strng.split(os.linesep)[start:]
114 str_toprint = os.linesep.join(str_lines)
115 num_newlines = len(str_lines)
116 len_str = len(str_toprint)
117
118 # Dumb heuristics to guesstimate number of on-screen lines the string
119 # takes. Very basic, but good enough for docstrings in reasonable
120 # terminals. If someone later feels like refining it, it's not hard.
121 numlines = max(num_newlines,int(len_str/80)+1)
122
123 if os.name == "nt":
124 screen_lines_def = get_console_size(defaulty=25)[1]
125 else:
126 screen_lines_def = 25 # default value if we can't auto-determine
127
128 # auto-determine screen size
129 if screen_lines <= 0:
130 if TERM=='xterm' or TERM=='xterm-color':
131 use_curses = USE_CURSES
132 else:
133 # curses causes problems on many terminals other than xterm.
134 use_curses = False
135 if use_curses:
136 import termios
137 import curses
138 # There is a bug in curses, where *sometimes* it fails to properly
139 # initialize, and then after the endwin() call is made, the
140 # terminal is left in an unusable state. Rather than trying to
141 # check everytime for this (by requesting and comparing termios
142 # flags each time), we just save the initial terminal state and
143 # unconditionally reset it every time. It's cheaper than making
144 # the checks.
145 term_flags = termios.tcgetattr(sys.stdout)
146 scr = curses.initscr()
147 screen_lines_real,screen_cols = scr.getmaxyx()
148 curses.endwin()
149 # Restore terminal state in case endwin() didn't.
150 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
151 # Now we have what we needed: the screen size in rows/columns
152 screen_lines += screen_lines_real
153 #print '***Screen size:',screen_lines_real,'lines x',\
154 #screen_cols,'columns.' # dbg
155 else:
156 screen_lines += screen_lines_def
157
158 #print 'numlines',numlines,'screenlines',screen_lines # dbg
159 if numlines <= screen_lines :
160 #print '*** normal print' # dbg
161 print >>Term.cout, str_toprint
162 else:
163 # Try to open pager and default to internal one if that fails.
164 # All failure modes are tagged as 'retval=1', to match the return
165 # value of a failed system command. If any intermediate attempt
166 # sets retval to 1, at the end we resort to our own page_dumb() pager.
167 pager_cmd = get_pager_cmd(pager_cmd)
168 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
169 if os.name == 'nt':
170 if pager_cmd.startswith('type'):
171 # The default WinXP 'type' command is failing on complex strings.
172 retval = 1
173 else:
174 tmpname = tempfile.mktemp('.txt')
175 tmpfile = file(tmpname,'wt')
176 tmpfile.write(strng)
177 tmpfile.close()
178 cmd = "%s < %s" % (pager_cmd,tmpname)
179 if os.system(cmd):
180 retval = 1
181 else:
182 retval = None
183 os.remove(tmpname)
184 else:
185 try:
186 retval = None
187 # if I use popen4, things hang. No idea why.
188 #pager,shell_out = os.popen4(pager_cmd)
189 pager = os.popen(pager_cmd,'w')
190 pager.write(strng)
191 pager.close()
192 retval = pager.close() # success returns None
193 except IOError,msg: # broken pipe when user quits
194 if msg.args == (32,'Broken pipe'):
195 retval = None
196 else:
197 retval = 1
198 except OSError:
199 # Other strange problems, sometimes seen in Win2k/cygwin
200 retval = 1
201 if retval is not None:
202 page_dumb(strng,screen_lines=screen_lines)
203
204 #----------------------------------------------------------------------------
205 def page_file(fname,start = 0, pager_cmd = None):
206 """Page a file, using an optional pager command and starting line.
207 """
208
209 pager_cmd = get_pager_cmd(pager_cmd)
210 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
211
212 try:
213 if os.environ['TERM'] in ['emacs','dumb']:
214 raise EnvironmentError
215 xsys(pager_cmd + ' ' + fname)
216 except:
217 try:
218 if start > 0:
219 start -= 1
220 page(open(fname).read(),start)
221 except:
222 print 'Unable to show file',`fname`
223
224 #----------------------------------------------------------------------------
225 def get_pager_cmd(pager_cmd = None):
226 """Return a pager command.
227
228 Makes some attempts at finding an OS-correct one."""
229
230 if os.name == 'posix':
231 default_pager_cmd = 'less -r' # -r for color control sequences
232 elif os.name in ['nt','dos']:
233 default_pager_cmd = 'type'
234
235 if pager_cmd is None:
236 try:
237 pager_cmd = os.environ['PAGER']
238 except:
239 pager_cmd = default_pager_cmd
240 return pager_cmd
241
242 #-----------------------------------------------------------------------------
243 def get_pager_start(pager,start):
244 """Return the string for paging files with an offset.
245
246 This is the '+N' argument which less and more (under Unix) accept.
247 """
248
249 if pager in ['less','more']:
250 if start:
251 start_string = '+' + str(start)
252 else:
253 start_string = ''
254 else:
255 start_string = ''
256 return start_string
257
258 #----------------------------------------------------------------------------
259 # (X)emacs on W32 doesn't like to be bypassed with msvcrt.getch()
260 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
261 import msvcrt
262 def page_more():
263 """ Smart pausing between pages
264
265 @return: True if need print more lines, False if quit
266 """
267 Term.cout.write('---Return to continue, q to quit--- ')
268 ans = msvcrt.getch()
269 if ans in ("q", "Q"):
270 result = False
271 else:
272 result = True
273 Term.cout.write("\b"*37 + " "*37 + "\b"*37)
274 return result
275 else:
276 def page_more():
277 ans = raw_input('---Return to continue, q to quit--- ')
278 if ans.lower().startswith('q'):
279 return False
280 else:
281 return True
282
283 #----------------------------------------------------------------------------
284 def snip_print(str,width = 75,print_full = 0,header = ''):
285 """Print a string snipping the midsection to fit in width.
286
287 print_full: mode control:
288 - 0: only snip long strings
289 - 1: send to page() directly.
290 - 2: snip long strings and ask for full length viewing with page()
291 Return 1 if snipping was necessary, 0 otherwise."""
292
293 if print_full == 1:
294 page(header+str)
295 return 0
296
297 print header,
298 if len(str) < width:
299 print str
300 snip = 0
301 else:
302 whalf = int((width -5)/2)
303 print str[:whalf] + ' <...> ' + str[-whalf:]
304 snip = 1
305 if snip and print_full == 2:
306 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
307 page(str)
308 return snip No newline at end of file
@@ -0,0 +1,38 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A simple class for quitting IPython.
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22
23 class Quitter(object):
24 """Simple class to handle exit, similar to Python 2.5's.
25
26 It handles exiting in an ipython-safe manner, which the one in Python 2.5
27 doesn't do (obviously, since it doesn't know about ipython)."""
28
29 def __init__(self, shell, name):
30 self.shell = shell
31 self.name = name
32
33 def __repr__(self):
34 return 'Type %s() to exit.' % self.name
35 __str__ = __repr__
36
37 def __call__(self):
38 self.shell.exit() No newline at end of file
@@ -0,0 +1,83 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Simple utility for splitting user input.
5
6 Authors:
7
8 * Brian Granger
9 * Fernando Perez
10 """
11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
22
23 import re
24
25 #-----------------------------------------------------------------------------
26 # Main function
27 #-----------------------------------------------------------------------------
28
29
30 # RegExp for splitting line contents into pre-char//first word-method//rest.
31 # For clarity, each group in on one line.
32
33 # WARNING: update the regexp if the escapes in iplib are changed, as they
34 # are hardwired in.
35
36 # Although it's not solely driven by the regex, note that:
37 # ,;/% only trigger if they are the first character on the line
38 # ! and !! trigger if they are first char(s) *or* follow an indent
39 # ? triggers as first or last char.
40
41 # The three parts of the regex are:
42 # 1) pre: pre_char *or* initial whitespace
43 # 2) ifun: first word/method (mix of \w and '.')
44 # 3) the_rest: rest of line (separated from ifun by space if non-empty)
45 line_split = re.compile(r'^([,;/%?]|!!?|\s*)'
46 r'\s*([\w\.]+)'
47 r'(\s+.*$|$)')
48
49 # r'[\w\.]+'
50 # r'\s*=\s*%.*'
51
52 def split_user_input(line, pattern=None):
53 """Split user input into pre-char/whitespace, function part and rest.
54
55 This is currently handles lines with '=' in them in a very inconsistent
56 manner.
57 """
58
59 if pattern is None:
60 pattern = line_split
61 match = pattern.match(line)
62 if not match:
63 # print "match failed for line '%s'" % line
64 try:
65 ifun, the_rest = line.split(None,1)
66 except ValueError:
67 # print "split failed for line '%s'" % line
68 ifun, the_rest = line,''
69 pre = re.match('^(\s*)(.*)',line).groups()[0]
70 else:
71 pre,ifun,the_rest = match.groups()
72
73 # ifun has to be a valid python identifier, so it better be only pure
74 # ascii, no unicode:
75 try:
76 ifun = ifun.encode('ascii')
77 except UnicodeEncodeError:
78 the_rest = ifun + u' ' + the_rest
79 ifun = u''
80
81 #print 'line:<%s>' % line # dbg
82 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
83 return pre, ifun.strip(), the_rest.lstrip()
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -19,11 +19,24 b' the new code in IPython.core.shell.'
19 from warnings import warn
19 from warnings import warn
20
20
21 msg = """
21 msg = """
22 This module (IPython.Shell) has been moved to a new location
22 This module (IPython.Shell) is deprecated. The classes that were in this
23 (IPython.core.shell) and is being refactored. Please update your code
23 module have been replaced by:
24 to use the new IPython.core.shell module"""
24
25 IPShell->IPython.core.iplib.InteractiveShell
26 IPShellEmbed->IPython.core.embed.InteractiveShellEmbed
27
28 Please migrate your code to use these classes instead.
29 """
25
30
26 warn(msg, category=DeprecationWarning, stacklevel=1)
31 warn(msg, category=DeprecationWarning, stacklevel=1)
27
32
28 from IPython.core.shell import start, IPShell, IPShellEmbed
33 from IPython.core.iplib import InteractiveShell as IPShell
34 from IPython.core.embed import InteractiveShellEmbed as IPShellEmbed
35
36 def start(user_ns=None, embedded=False):
37 """Return an instance of :class:`InteractiveShell`."""
38 if embedded:
39 return InteractiveShellEmbed(user_ns=user_ns)
40 else:
41 return InteractiveShell(user_ns=user_ns)
29
42
@@ -1,67 +1,47 b''
1 # -*- coding: utf-8 -*-
1 #!/usr/bin/env python
2 # encoding: utf-8
2 """
3 """
3 IPython -- An enhanced Interactive Python
4 IPython.
4
5
5 One of Python's nicest features is its interactive interpreter. This allows
6 IPython is a set of tools for interactive and exploratory computing in Python.
6 very fast testing of ideas without the overhead of creating test files as is
7 typical in most programming languages. However, the interpreter supplied with
8 the standard Python distribution is fairly primitive (and IDLE isn't really
9 much better).
10
11 IPython tries to:
12
13 i - provide an efficient environment for interactive work in Python
14 programming. It tries to address what we see as shortcomings of the standard
15 Python prompt, and adds many features to make interactive work much more
16 efficient.
17
18 ii - offer a flexible framework so that it can be used as the base
19 environment for other projects and problems where Python can be the
20 underlying language. Specifically scientific environments like Mathematica,
21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
22 fields. Python is a fabulous language for implementing this kind of system
23 (due to its dynamic and introspective features), and with suitable libraries
24 entire systems could be built leveraging Python's power.
25
26 iii - serve as an embeddable, ready to go interpreter for your own programs.
27
28 IPython requires Python 2.4 or newer.
29 """
7 """
30
8
31 #*****************************************************************************
9 #-----------------------------------------------------------------------------
32 # Copyright (C) 2008-2009 The IPython Development Team
10 # Copyright (C) 2008-2009 The IPython Development Team
33 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
34 #
11 #
35 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
36 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
37 #*****************************************************************************
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
38
19
39 # Enforce proper version requirements
20 import os
40 import sys
21 import sys
22 from IPython.core import release
23
24 #-----------------------------------------------------------------------------
25 # Setup everything
26 #-----------------------------------------------------------------------------
27
41
28
42 if sys.version[0:3] < '2.4':
29 if sys.version[0:3] < '2.4':
43 raise ImportError('Python Version 2.4 or above is required for IPython.')
30 raise ImportError('Python Version 2.4 or above is required for IPython.')
44
31
32
45 # Make it easy to import extensions - they are always directly on pythonpath.
33 # Make it easy to import extensions - they are always directly on pythonpath.
46 # Therefore, non-IPython modules can be added to extensions directory
34 # Therefore, non-IPython modules can be added to extensions directory
47 import os
48 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
35 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
49
36
50 # Define what gets imported with a 'from IPython import *'
37 #-----------------------------------------------------------------------------
51 __all__ = ['IPython.core.ipapi','utils.generics','utils.ipstruct',
38 # Setup the top level names
52 'core.release','core.shell']
39 #-----------------------------------------------------------------------------
53
54 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
55 # access to them via IPython.<name>
56 glob,loc = globals(),locals()
57 for name in __all__:
58 #print 'Importing: ',name # dbg
59 __import__(name,glob,loc,[])
60
40
61 from IPython.core import shell
41 # In some cases, these are causing circular imports.
62 Shell = shell
42 from IPython.core.iplib import InteractiveShell
63 from IPython.core import ipapi
43 from IPython.core.embed import embed
64 from IPython.core import iplib
44 from IPython.core.error import TryNext
65
45
66 from IPython.lib import (
46 from IPython.lib import (
67 enable_wx, disable_wx,
47 enable_wx, disable_wx,
@@ -75,13 +55,10 b' from IPython.lib import ('
75 )
55 )
76
56
77 # Release data
57 # Release data
78 from IPython.core import release # do it explicitly so pydoc can see it - pydoc bug
58 __author__ = ''
79 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
59 for author, email in release.authors.values():
80 ( release.authors['Fernando'] + release.authors['Janko'] + \
60 __author__ += author + ' <' + email + '>\n'
81 release.authors['Nathan'] )
82 __license__ = release.license
61 __license__ = release.license
83 __version__ = release.version
62 __version__ = release.version
84 __revision__ = release.revision
63 __revision__ = release.revision
85
64
86 # Namespace cleanup
87 del name,glob,loc
1 NO CONTENT: file renamed from IPython/config/userconfig/__init__.py to IPython/config/default/__init__.py
NO CONTENT: file renamed from IPython/config/userconfig/__init__.py to IPython/config/default/__init__.py
@@ -1,10 +1,5 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 def test_import_configloader():
5 from IPython.config import configloader
6
7 def test_import_userconfig():
8 from IPython.config import userconfig
9
4
10
5
@@ -65,17 +65,20 b' used, and this module (and the readline module) are silently inactive.'
65 import __builtin__
65 import __builtin__
66 import __main__
66 import __main__
67 import glob
67 import glob
68 import itertools
68 import keyword
69 import keyword
69 import os
70 import os
70 import re
71 import re
71 import shlex
72 import shlex
72 import sys
73 import sys
73 import IPython.utils.rlineimpl as readline
74 import types
74 import itertools
75
76 from IPython.core.error import TryNext
77 from IPython.core.prefilter import ESC_MAGIC
78
79 import IPython.utils.rlineimpl as readline
75 from IPython.utils.ipstruct import Struct
80 from IPython.utils.ipstruct import Struct
76 from IPython.core import ipapi
77 from IPython.utils import generics
81 from IPython.utils import generics
78 import types
79
82
80 # Python 2.4 offers sets as a builtin
83 # Python 2.4 offers sets as a builtin
81 try:
84 try:
@@ -195,7 +198,7 b' class Completer:'
195
198
196 try:
199 try:
197 words = generics.complete_object(obj, words)
200 words = generics.complete_object(obj, words)
198 except ipapi.TryNext:
201 except TryNext:
199 pass
202 pass
200 # Build match list to return
203 # Build match list to return
201 n = len(attr)
204 n = len(attr)
@@ -233,7 +236,7 b' class IPCompleter(Completer):'
233
236
234 Completer.__init__(self,namespace,global_namespace)
237 Completer.__init__(self,namespace,global_namespace)
235 self.magic_prefix = shell.name+'.magic_'
238 self.magic_prefix = shell.name+'.magic_'
236 self.magic_escape = shell.ESC_MAGIC
239 self.magic_escape = ESC_MAGIC
237 self.readline = readline
240 self.readline = readline
238 delims = self.readline.get_completer_delims()
241 delims = self.readline.get_completer_delims()
239 delims = delims.replace(self.magic_escape,'')
242 delims = delims.replace(self.magic_escape,'')
@@ -241,7 +244,7 b' class IPCompleter(Completer):'
241 self.get_line_buffer = self.readline.get_line_buffer
244 self.get_line_buffer = self.readline.get_line_buffer
242 self.get_endidx = self.readline.get_endidx
245 self.get_endidx = self.readline.get_endidx
243 self.omit__names = omit__names
246 self.omit__names = omit__names
244 self.merge_completions = shell.rc.readline_merge_completions
247 self.merge_completions = shell.readline_merge_completions
245 if alias_table is None:
248 if alias_table is None:
246 alias_table = {}
249 alias_table = {}
247 self.alias_table = alias_table
250 self.alias_table = alias_table
@@ -553,7 +556,7 b' class IPCompleter(Completer):'
553 return withcase
556 return withcase
554 # if none, then case insensitive ones are ok too
557 # if none, then case insensitive ones are ok too
555 return [r for r in res if r.lower().startswith(text.lower())]
558 return [r for r in res if r.lower().startswith(text.lower())]
556 except ipapi.TryNext:
559 except TryNext:
557 pass
560 pass
558
561
559 return None
562 return None
@@ -124,7 +124,7 b' $self.bug_tracker'
124 #color_scheme = 'Linux' # dbg
124 #color_scheme = 'Linux' # dbg
125
125
126 try:
126 try:
127 rptdir = self.IP.rc.ipythondir
127 rptdir = self.IP.config.IPYTHONDIR
128 except:
128 except:
129 rptdir = os.getcwd()
129 rptdir = os.getcwd()
130 if not os.path.isdir(rptdir):
130 if not os.path.isdir(rptdir):
@@ -171,7 +171,7 b' $self.bug_tracker'
171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
172 (os.name,sys.platform) )
172 (os.name,sys.platform) )
173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
174 rpt_add(pformat(self.IP.rc.dict()))
174 rpt_add(pformat(self.IP.dict()))
175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
176 try:
176 try:
177 rpt_add(sec_sep+"History of session input:")
177 rpt_add(sec_sep+"History of session input:")
@@ -215,7 +215,7 b' class IPythonCrashHandler(CrashHandler):'
215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
216 (os.name,sys.platform) )
216 (os.name,sys.platform) )
217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
218 rpt_add(pformat(self.IP.rc.dict()))
218 # rpt_add(pformat(self.IP.dict()))
219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
220 try:
220 try:
221 rpt_add(sec_sep+"History of session input:")
221 rpt_add(sec_sep+"History of session input:")
@@ -110,7 +110,7 b' class Tracer(object):'
110 __IPYTHON__
110 __IPYTHON__
111 except NameError:
111 except NameError:
112 # Outside of ipython, we set our own exception hook manually
112 # Outside of ipython, we set our own exception hook manually
113 __IPYTHON__ = ipapi.get(True,False)
113 __IPYTHON__ = ipapi.get()
114 BdbQuit_excepthook.excepthook_ori = sys.excepthook
114 BdbQuit_excepthook.excepthook_ori = sys.excepthook
115 sys.excepthook = BdbQuit_excepthook
115 sys.excepthook = BdbQuit_excepthook
116 def_colors = 'NoColor'
116 def_colors = 'NoColor'
@@ -123,7 +123,7 b' class Tracer(object):'
123 else:
123 else:
124 # In ipython, we use its custom exception handler mechanism
124 # In ipython, we use its custom exception handler mechanism
125 ip = ipapi.get()
125 ip = ipapi.get()
126 def_colors = ip.options.colors
126 def_colors = ip.colors
127 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
127 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
128
128
129 if colors is None:
129 if colors is None:
@@ -34,9 +34,9 b' def exception_colors():'
34 >>> ec.active_scheme_name
34 >>> ec.active_scheme_name
35 'NoColor'
35 'NoColor'
36 >>> ec.active_colors.keys()
36 >>> ec.active_colors.keys()
37 ['em', 'caret', '__allownew', 'name', 'val', 'vName', 'Normal', 'normalEm',
37 ['em', 'filenameEm', 'excName', 'valEm', 'nameEm', 'line', 'topline',
38 'filename', 'linenoEm', 'excName', 'lineno', 'valEm', 'filenameEm',
38 'name', 'caret', 'val', 'vName', 'Normal', 'filename', 'linenoEm',
39 'nameEm', 'line', 'topline']
39 'lineno', 'normalEm']
40 """
40 """
41
41
42 ex_colors = ColorSchemeTable()
42 ex_colors = ColorSchemeTable()
@@ -47,9 +47,7 b" def magic_history(self, parameter_s = ''):"
47 confirmation first if it already exists.
47 confirmation first if it already exists.
48 """
48 """
49
49
50 ip = self.api
50 if not self.outputcache.do_full_cache:
51 shell = self.shell
52 if not shell.outputcache.do_full_cache:
53 print 'This feature is only available if numbered prompts are in use.'
51 print 'This feature is only available if numbered prompts are in use.'
54 return
52 return
55 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
53 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
@@ -71,11 +69,11 b" def magic_history(self, parameter_s = ''):"
71 close_at_end = True
69 close_at_end = True
72
70
73 if 't' in opts:
71 if 't' in opts:
74 input_hist = shell.input_hist
72 input_hist = self.input_hist
75 elif 'r' in opts:
73 elif 'r' in opts:
76 input_hist = shell.input_hist_raw
74 input_hist = self.input_hist_raw
77 else:
75 else:
78 input_hist = shell.input_hist
76 input_hist = self.input_hist
79
77
80 default_length = 40
78 default_length = 40
81 pattern = None
79 pattern = None
@@ -105,7 +103,7 b" def magic_history(self, parameter_s = ''):"
105
103
106 found = False
104 found = False
107 if pattern is not None:
105 if pattern is not None:
108 sh = ip.IP.shadowhist.all()
106 sh = self.shadowhist.all()
109 for idx, s in sh:
107 for idx, s in sh:
110 if fnmatch.fnmatch(s, pattern):
108 if fnmatch.fnmatch(s, pattern):
111 print "0%d: %s" %(idx, s)
109 print "0%d: %s" %(idx, s)
@@ -168,9 +166,8 b' def rep_f(self, arg):'
168 """
166 """
169
167
170 opts,args = self.parse_options(arg,'',mode='list')
168 opts,args = self.parse_options(arg,'',mode='list')
171 ip = self.api
172 if not args:
169 if not args:
173 ip.set_next_input(str(ip.user_ns["_"]))
170 self.set_next_input(str(self.user_ns["_"]))
174 return
171 return
175
172
176 if len(args) == 1 and not '-' in args[0]:
173 if len(args) == 1 and not '-' in args[0]:
@@ -179,33 +176,33 b' def rep_f(self, arg):'
179 # get from shadow hist
176 # get from shadow hist
180 num = int(arg[1:])
177 num = int(arg[1:])
181 line = self.shadowhist.get(num)
178 line = self.shadowhist.get(num)
182 ip.set_next_input(str(line))
179 self.set_next_input(str(line))
183 return
180 return
184 try:
181 try:
185 num = int(args[0])
182 num = int(args[0])
186 ip.set_next_input(str(ip.IP.input_hist_raw[num]).rstrip())
183 self.set_next_input(str(self.input_hist_raw[num]).rstrip())
187 return
184 return
188 except ValueError:
185 except ValueError:
189 pass
186 pass
190
187
191 for h in reversed(self.shell.input_hist_raw):
188 for h in reversed(self.input_hist_raw):
192 if 'rep' in h:
189 if 'rep' in h:
193 continue
190 continue
194 if fnmatch.fnmatch(h,'*' + arg + '*'):
191 if fnmatch.fnmatch(h,'*' + arg + '*'):
195 ip.set_next_input(str(h).rstrip())
192 self.set_next_input(str(h).rstrip())
196 return
193 return
197
194
198 try:
195 try:
199 lines = self.extract_input_slices(args, True)
196 lines = self.extract_input_slices(args, True)
200 print "lines",lines
197 print "lines",lines
201 ip.runlines(lines)
198 self.runlines(lines)
202 except ValueError:
199 except ValueError:
203 print "Not found in recent history:", args
200 print "Not found in recent history:", args
204
201
205
202
206 _sentinel = object()
203 _sentinel = object()
207
204
208 class ShadowHist:
205 class ShadowHist(object):
209 def __init__(self,db):
206 def __init__(self,db):
210 # cmd => idx mapping
207 # cmd => idx mapping
211 self.curidx = 0
208 self.curidx = 0
@@ -228,7 +225,7 b' class ShadowHist:'
228 #print "new",newidx # dbg
225 #print "new",newidx # dbg
229 self.db.hset('shadowhist',ent, newidx)
226 self.db.hset('shadowhist',ent, newidx)
230 except:
227 except:
231 ipapi.get().IP.showtraceback()
228 ipapi.get().showtraceback()
232 print "WARNING: disabling shadow history"
229 print "WARNING: disabling shadow history"
233 self.disabled = True
230 self.disabled = True
234
231
@@ -250,8 +247,8 b' class ShadowHist:'
250 def init_ipython(ip):
247 def init_ipython(ip):
251 import ipy_completers
248 import ipy_completers
252
249
253 ip.expose_magic("rep",rep_f)
250 ip.define_magic("rep",rep_f)
254 ip.expose_magic("hist",magic_hist)
251 ip.define_magic("hist",magic_hist)
255 ip.expose_magic("history",magic_history)
252 ip.define_magic("history",magic_history)
256
253
257 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
254 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -26,7 +26,7 b' def calljed(self,filename, linenum):'
26 "My editor hook calls the jed editor directly."
26 "My editor hook calls the jed editor directly."
27 print "Calling my own editor, jed ..."
27 print "Calling my own editor, jed ..."
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
29 raise ipapi.TryNext()
29 raise TryNext()
30
30
31 ip.set_hook('editor', calljed)
31 ip.set_hook('editor', calljed)
32
32
@@ -41,22 +41,21 b' somewhere in your configuration files or ipython command line.'
41 # the file COPYING, distributed as part of this software.
41 # the file COPYING, distributed as part of this software.
42 #*****************************************************************************
42 #*****************************************************************************
43
43
44 from IPython.core import ipapi
45
46 import os, bisect
44 import os, bisect
47 import sys
45 import sys
48 from IPython.utils.genutils import Term, shell
46 from IPython.utils.genutils import Term, shell
49 from pprint import PrettyPrinter
47 from pprint import PrettyPrinter
50
48
49 from IPython.core.error import TryNext
50
51 # List here all the default hooks. For now it's just the editor functions
51 # List here all the default hooks. For now it's just the editor functions
52 # but over time we'll move here all the public API for user-accessible things.
52 # but over time we'll move here all the public API for user-accessible things.
53 # vds: >>
53
54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', 'result_display',
55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
56 'generate_prompt', 'generate_output_prompt','shell_hook',
56 'generate_prompt', 'generate_output_prompt','shell_hook',
57 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
57 'show_in_pager','pre_prompt_hook', 'pre_runcode_hook',
58 'clipboard_get']
58 'clipboard_get']
59 # vds: <<
60
59
61 pformat = PrettyPrinter().pformat
60 pformat = PrettyPrinter().pformat
62
61
@@ -69,7 +68,7 b' def editor(self,filename, linenum=None):'
69
68
70 # IPython configures a default editor at startup by reading $EDITOR from
69 # IPython configures a default editor at startup by reading $EDITOR from
71 # the environment, and falling back on vi (unix) or notepad (win32).
70 # the environment, and falling back on vi (unix) or notepad (win32).
72 editor = self.rc.editor
71 editor = self.editor
73
72
74 # marker for at which line to open the file (for existing objects)
73 # marker for at which line to open the file (for existing objects)
75 if linenum is None or editor=='notepad':
74 if linenum is None or editor=='notepad':
@@ -83,7 +82,7 b' def editor(self,filename, linenum=None):'
83
82
84 # Call the actual editor
83 # Call the actual editor
85 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
84 if os.system('%s %s %s' % (editor,linemark,filename)) != 0:
86 raise ipapi.TryNext()
85 raise TryNext()
87
86
88 import tempfile
87 import tempfile
89 def fix_error_editor(self,filename,linenum,column,msg):
88 def fix_error_editor(self,filename,linenum,column,msg):
@@ -99,20 +98,20 b' def fix_error_editor(self,filename,linenum,column,msg):'
99 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
98 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
100 t.flush()
99 t.flush()
101 return t
100 return t
102 if os.path.basename(self.rc.editor) != 'vim':
101 if os.path.basename(self.editor) != 'vim':
103 self.hooks.editor(filename,linenum)
102 self.hooks.editor(filename,linenum)
104 return
103 return
105 t = vim_quickfix_file()
104 t = vim_quickfix_file()
106 try:
105 try:
107 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
106 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
108 raise ipapi.TryNext()
107 raise TryNext()
109 finally:
108 finally:
110 t.close()
109 t.close()
111
110
112 # vds: >>
111
113 def synchronize_with_editor(self, filename, linenum, column):
112 def synchronize_with_editor(self, filename, linenum, column):
114 pass
113 pass
115 # vds: <<
114
116
115
117 class CommandChainDispatcher:
116 class CommandChainDispatcher:
118 """ Dispatch calls to a chain of commands until some func can handle it
117 """ Dispatch calls to a chain of commands until some func can handle it
@@ -140,12 +139,12 b' class CommandChainDispatcher:'
140 try:
139 try:
141 ret = cmd(*args, **kw)
140 ret = cmd(*args, **kw)
142 return ret
141 return ret
143 except ipapi.TryNext, exc:
142 except TryNext, exc:
144 if exc.args or exc.kwargs:
143 if exc.args or exc.kwargs:
145 args = exc.args
144 args = exc.args
146 kw = exc.kwargs
145 kw = exc.kwargs
147 # if no function will accept it, raise TryNext up to the caller
146 # if no function will accept it, raise TryNext up to the caller
148 raise ipapi.TryNext
147 raise TryNext
149
148
150 def __str__(self):
149 def __str__(self):
151 return str(self.chain)
150 return str(self.chain)
@@ -160,14 +159,15 b' class CommandChainDispatcher:'
160 Handy if the objects are not callable.
159 Handy if the objects are not callable.
161 """
160 """
162 return iter(self.chain)
161 return iter(self.chain)
163
162
163
164 def result_display(self,arg):
164 def result_display(self,arg):
165 """ Default display hook.
165 """ Default display hook.
166
166
167 Called for displaying the result to the user.
167 Called for displaying the result to the user.
168 """
168 """
169
169
170 if self.rc.pprint:
170 if self.pprint:
171 out = pformat(arg)
171 out = pformat(arg)
172 if '\n' in out:
172 if '\n' in out:
173 # So that multi-line strings line up with the left column of
173 # So that multi-line strings line up with the left column of
@@ -183,6 +183,7 b' def result_display(self,arg):'
183 # the default display hook doesn't manipulate the value to put in history
183 # the default display hook doesn't manipulate the value to put in history
184 return None
184 return None
185
185
186
186 def input_prefilter(self,line):
187 def input_prefilter(self,line):
187 """ Default input prefilter
188 """ Default input prefilter
188
189
@@ -197,6 +198,7 b' def input_prefilter(self,line):'
197 #print "attempt to rewrite",line #dbg
198 #print "attempt to rewrite",line #dbg
198 return line
199 return line
199
200
201
200 def shutdown_hook(self):
202 def shutdown_hook(self):
201 """ default shutdown hook
203 """ default shutdown hook
202
204
@@ -206,32 +208,36 b' def shutdown_hook(self):'
206 #print "default shutdown hook ok" # dbg
208 #print "default shutdown hook ok" # dbg
207 return
209 return
208
210
211
209 def late_startup_hook(self):
212 def late_startup_hook(self):
210 """ Executed after ipython has been constructed and configured
213 """ Executed after ipython has been constructed and configured
211
214
212 """
215 """
213 #print "default startup hook ok" # dbg
216 #print "default startup hook ok" # dbg
214
217
218
215 def generate_prompt(self, is_continuation):
219 def generate_prompt(self, is_continuation):
216 """ calculate and return a string with the prompt to display """
220 """ calculate and return a string with the prompt to display """
217 ip = self.api
218 if is_continuation:
221 if is_continuation:
219 return str(ip.IP.outputcache.prompt2)
222 return str(self.outputcache.prompt2)
220 return str(ip.IP.outputcache.prompt1)
223 return str(self.outputcache.prompt1)
224
221
225
222 def generate_output_prompt(self):
226 def generate_output_prompt(self):
223 ip = self.api
227 return str(self.outputcache.prompt_out)
224 return str(ip.IP.outputcache.prompt_out)
228
225
229
226 def shell_hook(self,cmd):
230 def shell_hook(self,cmd):
227 """ Run system/shell command a'la os.system() """
231 """ Run system/shell command a'la os.system() """
228
232
229 shell(cmd, header=self.rc.system_header, verbose=self.rc.system_verbose)
233 shell(cmd, header=self.system_header, verbose=self.system_verbose)
234
230
235
231 def show_in_pager(self,s):
236 def show_in_pager(self,s):
232 """ Run a string through pager """
237 """ Run a string through pager """
233 # raising TryNext here will use the default paging functionality
238 # raising TryNext here will use the default paging functionality
234 raise ipapi.TryNext
239 raise TryNext
240
235
241
236 def pre_prompt_hook(self):
242 def pre_prompt_hook(self):
237 """ Run before displaying the next prompt
243 """ Run before displaying the next prompt
@@ -242,10 +248,12 b' def pre_prompt_hook(self):'
242
248
243 return None
249 return None
244
250
251
245 def pre_runcode_hook(self):
252 def pre_runcode_hook(self):
246 """ Executed before running the (prefiltered) code in IPython """
253 """ Executed before running the (prefiltered) code in IPython """
247 return None
254 return None
248
255
256
249 def clipboard_get(self):
257 def clipboard_get(self):
250 """ Get text from the clipboard.
258 """ Get text from the clipboard.
251 """
259 """
This diff has been collapsed as it changes many lines, (704 lines changed) Show them Hide them
@@ -1,685 +1,35 b''
1 """IPython customization API
1 #!/usr/bin/env python
2
2 # encoding: utf-8
3 Your one-stop module for configuring & extending ipython
3 """
4
4 This module is *completely* deprecated and should no longer be used for
5 The API will probably break when ipython 1.0 is released, but so
5 any purpose. Currently, we have a few parts of the core that have
6 will the other configuration method (rc files).
6 not been componentized and thus, still rely on this module. When everything
7
7 has been made into a component, this module will be sent to deathrow.
8 All names prefixed by underscores are for internal use, not part
9 of the public api.
10
11 Below is an example that you can just put to a module and import from ipython.
12
13 A good practice is to install the config script below as e.g.
14
15 ~/.ipython/my_private_conf.py
16
17 And do
18
19 import_mod my_private_conf
20
21 in ~/.ipython/ipythonrc
22
23 That way the module is imported at startup and you can have all your
24 personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME
25 stuff) in there.
26
27 from IPython.core import ipapi
28 ip = ipapi.get()
29
30 def ankka_f(self, arg):
31 print 'Ankka',self,'says uppercase:',arg.upper()
32
33 ip.expose_magic('ankka',ankka_f)
34
35 ip.magic('alias sayhi echo "Testing, hi ok"')
36 ip.magic('alias helloworld echo "Hello world"')
37 ip.system('pwd')
38
39 ip.ex('import re')
40 ip.ex('''
41 def funcci(a,b):
42 print a+b
43 print funcci(3,4)
44 ''')
45 ip.ex('funcci(348,9)')
46
47 def jed_editor(self,filename, linenum=None):
48 print 'Calling my own editor, jed ... via hook!'
49 import os
50 if linenum is None: linenum = 0
51 os.system('jed +%d %s' % (linenum, filename))
52 print 'exiting jed'
53
54 ip.set_hook('editor',jed_editor)
55
56 o = ip.options
57 o.autocall = 2 # FULL autocall mode
58
59 print 'done!'
60 """
8 """
61
9
62 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
63 # Modules and globals
11 # Copyright (C) 2008-2009 The IPython Development Team
64
12 #
65 # stdlib imports
13 # Distributed under the terms of the BSD License. The full license is in
66 import __builtin__
14 # the file COPYING, distributed as part of this software.
67 import sys
68
69 # contains the most recently instantiated IPApi
70 _RECENT_IP = None
71
72 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
73 # Code begins
74
75 class TryNext(Exception):
76 """Try next hook exception.
77
78 Raise this in your hook function to indicate that the next hook handler
79 should be used to handle the operation. If you pass arguments to the
80 constructor those arguments will be used by the next hook instead of the
81 original ones.
82 """
83
84 def __init__(self, *args, **kwargs):
85 self.args = args
86 self.kwargs = kwargs
87
88
89 class UsageError(Exception):
90 """ Error in magic function arguments, etc.
91
92 Something that probably won't warrant a full traceback, but should
93 nevertheless interrupt a macro / batch file.
94 """
95
96
97 class IPyAutocall:
98 """ Instances of this class are always autocalled
99
100 This happens regardless of 'autocall' variable state. Use this to
101 develop macro-like mechanisms.
102 """
103
104 def set_ip(self,ip):
105 """ Will be used to set _ip point to current ipython instance b/f call
106
107 Override this method if you don't want this to happen.
108
109 """
110 self._ip = ip
111
112
113 class IPythonNotRunning:
114 """Dummy do-nothing class.
115
116 Instances of this class return a dummy attribute on all accesses, which
117 can be called and warns. This makes it easier to write scripts which use
118 the ipapi.get() object for informational purposes to operate both with and
119 without ipython. Obviously code which uses the ipython object for
120 computations will not work, but this allows a wider range of code to
121 transparently work whether ipython is being used or not."""
122
123 def __init__(self,warn=True):
124 if warn:
125 self.dummy = self._dummy_warn
126 else:
127 self.dummy = self._dummy_silent
128
129 def __str__(self):
130 return "<IPythonNotRunning>"
131
132 __repr__ = __str__
133
134 def __getattr__(self,name):
135 return self.dummy
136
137 def _dummy_warn(self,*args,**kw):
138 """Dummy function, which doesn't do anything but warn."""
139
140 print ("IPython is not running, this is a dummy no-op function")
141
142 def _dummy_silent(self,*args,**kw):
143 """Dummy function, which doesn't do anything and emits no warnings."""
144 pass
145
146
147 def get(allow_dummy=False,dummy_warn=True):
148 """Get an IPApi object.
149
150 If allow_dummy is true, returns an instance of IPythonNotRunning
151 instead of None if not running under IPython.
152
153 If dummy_warn is false, the dummy instance will be completely silent.
154
155 Running this should be the first thing you do when writing extensions that
156 can be imported as normal modules. You can then direct all the
157 configuration operations against the returned object.
158 """
159 global _RECENT_IP
160 if allow_dummy and not _RECENT_IP:
161 _RECENT_IP = IPythonNotRunning(dummy_warn)
162 return _RECENT_IP
163
164
165 class IPApi(object):
166 """ The actual API class for configuring IPython
167
168 You should do all of the IPython configuration by getting an IPApi object
169 with IPython.ipapi.get() and using the attributes and methods of the
170 returned object."""
171
172 def __init__(self,ip):
173
174 global _RECENT_IP
175
176 # All attributes exposed here are considered to be the public API of
177 # IPython. As needs dictate, some of these may be wrapped as
178 # properties.
179
180 self.magic = ip.ipmagic
181
182 self.system = ip.system
183
184 self.set_hook = ip.set_hook
185
186 self.set_custom_exc = ip.set_custom_exc
187
188 self.user_ns = ip.user_ns
189
190 self.set_crash_handler = ip.set_crash_handler
191
192 # Session-specific data store, which can be used to store
193 # data that should persist through the ipython session.
194 self.meta = ip.meta
195
196 # The ipython instance provided
197 self.IP = ip
198
199 self.extensions = {}
200
201 self.dbg = DebugTools(self)
202
203 _RECENT_IP = self
204
205 # Use a property for some things which are added to the instance very
206 # late. I don't have time right now to disentangle the initialization
207 # order issues, so a property lets us delay item extraction while
208 # providing a normal attribute API.
209 def get_db(self):
210 """A handle to persistent dict-like database (a PickleShareDB object)"""
211 return self.IP.db
212
213 db = property(get_db,None,None,get_db.__doc__)
214
215 def get_options(self):
216 """All configurable variables."""
217
218 # catch typos by disabling new attribute creation. If new attr creation
219 # is in fact wanted (e.g. when exposing new options), do
220 # allow_new_attr(True) for the received rc struct.
221
222 self.IP.rc.allow_new_attr(False)
223 return self.IP.rc
224
225 options = property(get_options,None,None,get_options.__doc__)
226
227 def expose_magic(self,magicname, func):
228 """Expose own function as magic function for ipython
229
230 def foo_impl(self,parameter_s=''):
231 'My very own magic!. (Use docstrings, IPython reads them).'
232 print 'Magic function. Passed parameter is between < >:'
233 print '<%s>' % parameter_s
234 print 'The self object is:',self
235
236 ipapi.expose_magic('foo',foo_impl)
237 """
238
239 import new
240 im = new.instancemethod(func,self.IP, self.IP.__class__)
241 old = getattr(self.IP, "magic_" + magicname, None)
242 if old:
243 self.dbg.debug_stack("Magic redefinition '%s', old %s" %
244 (magicname,old) )
245
246 setattr(self.IP, "magic_" + magicname, im)
247
248 def ex(self,cmd):
249 """ Execute a normal python statement in user namespace """
250 exec cmd in self.user_ns
251
252 def ev(self,expr):
253 """ Evaluate python expression expr in user namespace
254
255 Returns the result of evaluation"""
256 return eval(expr,self.user_ns)
257
258 def runlines(self,lines):
259 """ Run the specified lines in interpreter, honoring ipython directives.
260
261 This allows %magic and !shell escape notations.
262
263 Takes either all lines in one string or list of lines.
264 """
265
266 def cleanup_ipy_script(script):
267 """ Make a script safe for _ip.runlines()
268
269 - Removes empty lines Suffixes all indented blocks that end with
270 - unindented lines with empty lines
271 """
272
273 res = []
274 lines = script.splitlines()
275
16
276 level = 0
17 #-----------------------------------------------------------------------------
277 for l in lines:
18 # Imports
278 lstripped = l.lstrip()
19 #-----------------------------------------------------------------------------
279 stripped = l.strip()
280 if not stripped:
281 continue
282 newlevel = len(l) - len(lstripped)
283 def is_secondary_block_start(s):
284 if not s.endswith(':'):
285 return False
286 if (s.startswith('elif') or
287 s.startswith('else') or
288 s.startswith('except') or
289 s.startswith('finally')):
290 return True
291
292 if level > 0 and newlevel == 0 and \
293 not is_secondary_block_start(stripped):
294 # add empty line
295 res.append('')
296
297 res.append(l)
298 level = newlevel
299 return '\n'.join(res) + '\n'
300
301 if isinstance(lines,basestring):
302 script = lines
303 else:
304 script = '\n'.join(lines)
305 clean=cleanup_ipy_script(script)
306 # print "_ip.runlines() script:\n",clean # dbg
307 self.IP.runlines(clean)
308
309 def to_user_ns(self,vars, interactive = True):
310 """Inject a group of variables into the IPython user namespace.
311
312 Inputs:
313
314 - vars: string with variable names separated by whitespace, or a
315 dict with name/value pairs.
316
317 - interactive: if True (default), the var will be listed with
318 %whos et. al.
319
320 This utility routine is meant to ease interactive debugging work,
321 where you want to easily propagate some internal variable in your code
322 up to the interactive namespace for further exploration.
323
324 When you run code via %run, globals in your script become visible at
325 the interactive prompt, but this doesn't happen for locals inside your
326 own functions and methods. Yet when debugging, it is common to want
327 to explore some internal variables further at the interactive propmt.
328
329 Examples:
330
331 To use this, you first must obtain a handle on the ipython object as
332 indicated above, via:
333
334 from IPython.core import ipapi
335 ip = ipapi.get()
336
337 Once this is done, inside a routine foo() where you want to expose
338 variables x and y, you do the following:
339
340 def foo():
341 ...
342 x = your_computation()
343 y = something_else()
344
345 # This pushes x and y to the interactive prompt immediately, even
346 # if this routine crashes on the next line after:
347 ip.to_user_ns('x y')
348 ...
349
350 # To expose *ALL* the local variables from the function, use:
351 ip.to_user_ns(locals())
352
353 ...
354 # return
355
356
357 If you need to rename variables, the dict input makes it easy. For
358 example, this call exposes variables 'foo' as 'x' and 'bar' as 'y'
359 in IPython user namespace:
360
361 ip.to_user_ns(dict(x=foo,y=bar))
362 """
363
364 # print 'vars given:',vars # dbg
365
366 # We need a dict of name/value pairs to do namespace updates.
367 if isinstance(vars,dict):
368 # If a dict was given, no need to change anything.
369 vdict = vars
370 elif isinstance(vars,basestring):
371 # If a string with names was given, get the caller's frame to
372 # evaluate the given names in
373 cf = sys._getframe(1)
374 vdict = {}
375 for name in vars.split():
376 try:
377 vdict[name] = eval(name,cf.f_globals,cf.f_locals)
378 except:
379 print ('could not get var. %s from %s' %
380 (name,cf.f_code.co_name))
381 else:
382 raise ValueError('vars must be a string or a dict')
383
384 # Propagate variables to user namespace
385 self.user_ns.update(vdict)
386
387 # And configure interactive visibility
388 config_ns = self.IP.user_config_ns
389 if interactive:
390 for name,val in vdict.iteritems():
391 config_ns.pop(name,None)
392 else:
393 for name,val in vdict.iteritems():
394 config_ns[name] = val
395
396 def expand_alias(self,line):
397 """ Expand an alias in the command line
398
399 Returns the provided command line, possibly with the first word
400 (command) translated according to alias expansion rules.
401
402 [ipython]|16> _ip.expand_aliases("np myfile.txt")
403 <16> 'q:/opt/np/notepad++.exe myfile.txt'
404 """
405
406 pre,fn,rest = self.IP.split_user_input(line)
407 res = pre + self.IP.expand_aliases(fn,rest)
408 return res
409
410 def itpl(self, s, depth = 1):
411 """ Expand Itpl format string s.
412
413 Only callable from command line (i.e. prefilter results);
414 If you use in your scripts, you need to use a bigger depth!
415 """
416 return self.IP.var_expand(s, depth)
417
418 def defalias(self, name, cmd):
419 """ Define a new alias
420
421 _ip.defalias('bb','bldmake bldfiles')
422
423 Creates a new alias named 'bb' in ipython user namespace
424 """
425
426 self.dbg.check_hotname(name)
427
428 if name in self.IP.alias_table:
429 self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')"
430 % (name, cmd, self.IP.alias_table[name]))
431
432 if callable(cmd):
433 self.IP.alias_table[name] = cmd
434 from IPython.core import shadowns
435 setattr(shadowns, name,cmd)
436 return
437
438 if isinstance(cmd,basestring):
439 nargs = cmd.count('%s')
440 if nargs>0 and cmd.find('%l')>=0:
441 raise Exception('The %s and %l specifiers are mutually '
442 'exclusive in alias definitions.')
443
444 self.IP.alias_table[name] = (nargs,cmd)
445 return
446
447 # just put it in - it's probably (0,'foo')
448 self.IP.alias_table[name] = cmd
449
450 def defmacro(self, *args):
451 """ Define a new macro
452
453 2 forms of calling:
454
455 mac = _ip.defmacro('print "hello"\nprint "world"')
456
457 (doesn't put the created macro on user namespace)
458
459 _ip.defmacro('build', 'bldmake bldfiles\nabld build winscw udeb')
460
461 (creates a macro named 'build' in user namespace)
462 """
463
464 from IPython.core import macro
465
466 if len(args) == 1:
467 return macro.Macro(args[0])
468 elif len(args) == 2:
469 self.user_ns[args[0]] = macro.Macro(args[1])
470 else:
471 return Exception("_ip.defmacro must be called with 1 or 2 arguments")
472
473 def set_next_input(self, s):
474 """ Sets the 'default' input string for the next command line.
475
476 Requires readline.
477
478 Example:
479
480 [D:\ipython]|1> _ip.set_next_input("Hello Word")
481 [D:\ipython]|2> Hello Word_ # cursor is here
482 """
483
484 self.IP.rl_next_input = s
485
486 def load(self, mod):
487 """ Load an extension.
488
489 Some modules should (or must) be 'load()':ed, rather than just imported.
490
491 Loading will do:
492
493 - run init_ipython(ip)
494 - run ipython_firstrun(ip)
495 """
496
497 if mod in self.extensions:
498 # just to make sure we don't init it twice
499 # note that if you 'load' a module that has already been
500 # imported, init_ipython gets run anyway
501
502 return self.extensions[mod]
503 __import__(mod)
504 m = sys.modules[mod]
505 if hasattr(m,'init_ipython'):
506 m.init_ipython(self)
507
508 if hasattr(m,'ipython_firstrun'):
509 already_loaded = self.db.get('firstrun_done', set())
510 if mod not in already_loaded:
511 m.ipython_firstrun(self)
512 already_loaded.add(mod)
513 self.db['firstrun_done'] = already_loaded
514
515 self.extensions[mod] = m
516 return m
517
518
519 class DebugTools:
520 """ Used for debugging mishaps in api usage
521
522 So far, tracing redefinitions is supported.
523 """
524
525 def __init__(self, ip):
526 self.ip = ip
527 self.debugmode = False
528 self.hotnames = set()
529
530 def hotname(self, name_to_catch):
531 self.hotnames.add(name_to_catch)
532
533 def debug_stack(self, msg = None):
534 if not self.debugmode:
535 return
536
537 import traceback
538 if msg is not None:
539 print '====== %s ========' % msg
540 traceback.print_stack()
541
542 def check_hotname(self,name):
543 if name in self.hotnames:
544 self.debug_stack( "HotName '%s' caught" % name)
545
546
547 def launch_new_instance(user_ns = None,shellclass = None):
548 """ Make and start a new ipython instance.
549
550 This can be called even without having an already initialized
551 ipython session running.
552
553 This is also used as the egg entry point for the 'ipython' script.
554
555 """
556 ses = make_session(user_ns,shellclass)
557 ses.mainloop()
558
559
560 def make_user_ns(user_ns = None):
561 """Return a valid user interactive namespace.
562
563 This builds a dict with the minimal information needed to operate as a
564 valid IPython user namespace, which you can pass to the various embedding
565 classes in ipython.
566
567 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
568 to make both the local and global namespace objects simultaneously.
569
570 :Parameters:
571 user_ns : dict-like, optional
572 The current user namespace. The items in this namespace should be
573 included in the output. If None, an appropriate blank namespace
574 should be created.
575
576 :Returns:
577 A dictionary-like object to be used as the local namespace of the
578 interpreter.
579 """
580
581 raise NotImplementedError
582
583
584 def make_user_global_ns(ns = None):
585 """Return a valid user global namespace.
586
587 Similar to make_user_ns(), but global namespaces are really only needed in
588 embedded applications, where there is a distinction between the user's
589 interactive namespace and the global one where ipython is running.
590
591 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
592 to make both the local and global namespace objects simultaneously.
593
594 :Parameters:
595 ns : dict, optional
596 The current user global namespace. The items in this namespace
597 should be included in the output. If None, an appropriate blank
598 namespace should be created.
599
600 :Returns:
601 A true dict to be used as the global namespace of the interpreter.
602 """
603
604 raise NotImplementedError
605
606 # Record the true objects in order to be able to test if the user has overridden
607 # these API functions.
608 _make_user_ns = make_user_ns
609 _make_user_global_ns = make_user_global_ns
610
611
612 def make_user_namespaces(user_ns = None,user_global_ns = None):
613 """Return a valid local and global user interactive namespaces.
614
615 This builds a dict with the minimal information needed to operate as a
616 valid IPython user namespace, which you can pass to the various embedding
617 classes in ipython. The default implementation returns the same dict for
618 both the locals and the globals to allow functions to refer to variables in
619 the namespace. Customized implementations can return different dicts. The
620 locals dictionary can actually be anything following the basic mapping
621 protocol of a dict, but the globals dict must be a true dict, not even
622 a subclass. It is recommended that any custom object for the locals
623 namespace synchronize with the globals dict somehow.
624
625 Raises TypeError if the provided globals namespace is not a true dict.
626
627 :Parameters:
628 user_ns : dict-like, optional
629 The current user namespace. The items in this namespace should be
630 included in the output. If None, an appropriate blank namespace
631 should be created.
632 user_global_ns : dict, optional
633 The current user global namespace. The items in this namespace
634 should be included in the output. If None, an appropriate blank
635 namespace should be created.
636
637 :Returns:
638 A tuple pair of dictionary-like object to be used as the local namespace
639 of the interpreter and a dict to be used as the global namespace.
640 """
641
642 if user_ns is None:
643 if make_user_ns is not _make_user_ns:
644 # Old API overridden.
645 # FIXME: Issue DeprecationWarning, or just let the old API live on?
646 user_ns = make_user_ns(user_ns)
647 else:
648 # Set __name__ to __main__ to better match the behavior of the
649 # normal interpreter.
650 user_ns = {'__name__' :'__main__',
651 '__builtins__' : __builtin__,
652 }
653 else:
654 user_ns.setdefault('__name__','__main__')
655 user_ns.setdefault('__builtins__',__builtin__)
656
657 if user_global_ns is None:
658 if make_user_global_ns is not _make_user_global_ns:
659 # Old API overridden.
660 user_global_ns = make_user_global_ns(user_global_ns)
661 else:
662 user_global_ns = user_ns
663 if type(user_global_ns) is not dict:
664 raise TypeError("user_global_ns must be a true dict; got %r"
665 % type(user_global_ns))
666
667 return user_ns, user_global_ns
668
669
670 def make_session(user_ns = None, shellclass = None):
671 """Makes, but does not launch an IPython session.
672
673 Later on you can call obj.mainloop() on the returned object.
674
20
675 Inputs:
21 from IPython.core.error import TryNext, UsageError
676
22
677 - user_ns(None): a dict to be used as the user's namespace with initial
23 #-----------------------------------------------------------------------------
678 data.
24 # Classes and functions
679
25 #-----------------------------------------------------------------------------
680 WARNING: This should *not* be run when a session exists already."""
681
26
682 import IPython.core.shell
27 def get():
683 if shellclass is None:
28 """Get the most recently created InteractiveShell instance."""
684 return IPython.core.shell.start(user_ns)
29 from IPython.core.iplib import InteractiveShell
685 return shellclass(user_ns = user_ns)
30 insts = InteractiveShell.get_instances()
31 most_recent = insts[0]
32 for inst in insts[1:]:
33 if inst.created > most_recent.created:
34 most_recent = inst
35 return most_recent
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -7,10 +7,8 b''
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #*****************************************************************************
8 #*****************************************************************************
9
9
10 from IPython.core import ipapi
11
12 from IPython.utils.genutils import Term
10 from IPython.utils.genutils import Term
13 from IPython.core.ipapi import IPyAutocall
11 from IPython.core.autocall import IPyAutocall
14
12
15 class Macro(IPyAutocall):
13 class Macro(IPyAutocall):
16 """Simple class to store the value of macros as strings.
14 """Simple class to store the value of macros as strings.
@@ -45,16 +45,18 b' except ImportError:'
45 import IPython
45 import IPython
46 from IPython.utils import wildcard
46 from IPython.utils import wildcard
47 from IPython.core import debugger, oinspect
47 from IPython.core import debugger, oinspect
48 from IPython.core.error import TryNext
48 from IPython.core.fakemodule import FakeModule
49 from IPython.core.fakemodule import FakeModule
50 from IPython.core.prefilter import ESC_MAGIC
49 from IPython.external.Itpl import Itpl, itpl, printpl,itplns
51 from IPython.external.Itpl import Itpl, itpl, printpl,itplns
50 from IPython.utils.PyColorize import Parser
52 from IPython.utils.PyColorize import Parser
51 from IPython.utils.ipstruct import Struct
53 from IPython.utils.ipstruct import Struct
52 from IPython.core.macro import Macro
54 from IPython.core.macro import Macro
53 from IPython.utils.genutils import *
55 from IPython.utils.genutils import *
56 from IPython.core.page import page
54 from IPython.utils import platutils
57 from IPython.utils import platutils
55 import IPython.utils.generics
58 import IPython.utils.generics
56 from IPython.core import ipapi
59 from IPython.core.error import UsageError
57 from IPython.core.ipapi import UsageError
58 from IPython.testing import decorators as testdec
60 from IPython.testing import decorators as testdec
59
61
60 #***************************************************************************
62 #***************************************************************************
@@ -204,9 +206,9 b' python-profiler package from non-free.""")'
204 namespaces = [ ('Interactive', self.shell.user_ns),
206 namespaces = [ ('Interactive', self.shell.user_ns),
205 ('IPython internal', self.shell.internal_ns),
207 ('IPython internal', self.shell.internal_ns),
206 ('Python builtin', __builtin__.__dict__),
208 ('Python builtin', __builtin__.__dict__),
207 ('Alias', self.shell.alias_table),
209 ('Alias', self.shell.alias_manager.alias_table),
208 ]
210 ]
209 alias_ns = self.shell.alias_table
211 alias_ns = self.shell.alias_manager.alias_table
210
212
211 # initialize results to 'null'
213 # initialize results to 'null'
212 found = 0; obj = None; ospace = None; ds = None;
214 found = 0; obj = None; ospace = None; ds = None;
@@ -243,7 +245,7 b' python-profiler package from non-free.""")'
243
245
244 # Try to see if it's magic
246 # Try to see if it's magic
245 if not found:
247 if not found:
246 if oname.startswith(self.shell.ESC_MAGIC):
248 if oname.startswith(ESC_MAGIC):
247 oname = oname[1:]
249 oname = oname[1:]
248 obj = getattr(self,'magic_'+oname,None)
250 obj = getattr(self,'magic_'+oname,None)
249 if obj is not None:
251 if obj is not None:
@@ -271,10 +273,10 b' python-profiler package from non-free.""")'
271 # Characters that need to be escaped for latex:
273 # Characters that need to be escaped for latex:
272 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
274 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
273 # Magic command names as headers:
275 # Magic command names as headers:
274 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
276 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
275 re.MULTILINE)
277 re.MULTILINE)
276 # Magic commands
278 # Magic commands
277 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
279 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
278 re.MULTILINE)
280 re.MULTILINE)
279 # Paragraph continue
281 # Paragraph continue
280 par_re = re.compile(r'\\$',re.MULTILINE)
282 par_re = re.compile(r'\\$',re.MULTILINE)
@@ -375,10 +377,10 b' python-profiler package from non-free.""")'
375 # Functions for IPython shell work (vars,funcs, config, etc)
377 # Functions for IPython shell work (vars,funcs, config, etc)
376 def magic_lsmagic(self, parameter_s = ''):
378 def magic_lsmagic(self, parameter_s = ''):
377 """List currently available magic functions."""
379 """List currently available magic functions."""
378 mesc = self.shell.ESC_MAGIC
380 mesc = ESC_MAGIC
379 print 'Available magic functions:\n'+mesc+\
381 print 'Available magic functions:\n'+mesc+\
380 (' '+mesc).join(self.lsmagic())
382 (' '+mesc).join(self.lsmagic())
381 print '\n' + Magic.auto_status[self.shell.rc.automagic]
383 print '\n' + Magic.auto_status[self.shell.automagic]
382 return None
384 return None
383
385
384 def magic_magic(self, parameter_s = ''):
386 def magic_magic(self, parameter_s = ''):
@@ -423,11 +425,11 b' python-profiler package from non-free.""")'
423
425
424
426
425 if mode == 'rest':
427 if mode == 'rest':
426 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
428 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(ESC_MAGIC,
427 fname,fndoc))
429 fname,fndoc))
428
430
429 else:
431 else:
430 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
432 magic_docs.append('%s%s:\n\t%s\n' %(ESC_MAGIC,
431 fname,fndoc))
433 fname,fndoc))
432
434
433 magic_docs = ''.join(magic_docs)
435 magic_docs = ''.join(magic_docs)
@@ -470,22 +472,22 b' ipythonrc file, placing a line like:'
470
472
471 will define %pf as a new name for %profile.
473 will define %pf as a new name for %profile.
472
474
473 You can also call magics in code using the ipmagic() function, which IPython
475 You can also call magics in code using the magic() function, which IPython
474 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
476 automatically adds to the builtin namespace. Type 'magic?' for details.
475
477
476 For a list of the available magic functions, use %lsmagic. For a description
478 For a list of the available magic functions, use %lsmagic. For a description
477 of any of them, type %magic_name?, e.g. '%cd?'.
479 of any of them, type %magic_name?, e.g. '%cd?'.
478
480
479 Currently the magic system has the following functions:\n"""
481 Currently the magic system has the following functions:\n"""
480
482
481 mesc = self.shell.ESC_MAGIC
483 mesc = ESC_MAGIC
482 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
484 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
483 "\n\n%s%s\n\n%s" % (outmsg,
485 "\n\n%s%s\n\n%s" % (outmsg,
484 magic_docs,mesc,mesc,
486 magic_docs,mesc,mesc,
485 (' '+mesc).join(self.lsmagic()),
487 (' '+mesc).join(self.lsmagic()),
486 Magic.auto_status[self.shell.rc.automagic] ) )
488 Magic.auto_status[self.shell.automagic] ) )
487
489
488 page(outmsg,screen_lines=self.shell.rc.screen_length)
490 page(outmsg,screen_lines=self.shell.usable_screen_length)
489
491
490
492
491 def magic_autoindent(self, parameter_s = ''):
493 def magic_autoindent(self, parameter_s = ''):
@@ -512,15 +514,14 b' Currently the magic system has the following functions:\\n"""'
512 delete the variable (del var), the previously shadowed magic function
514 delete the variable (del var), the previously shadowed magic function
513 becomes visible to automagic again."""
515 becomes visible to automagic again."""
514
516
515 rc = self.shell.rc
516 arg = parameter_s.lower()
517 arg = parameter_s.lower()
517 if parameter_s in ('on','1','true'):
518 if parameter_s in ('on','1','true'):
518 rc.automagic = True
519 self.shell.automagic = True
519 elif parameter_s in ('off','0','false'):
520 elif parameter_s in ('off','0','false'):
520 rc.automagic = False
521 self.shell.automagic = False
521 else:
522 else:
522 rc.automagic = not rc.automagic
523 self.shell.automagic = not self.shell.automagic
523 print '\n' + Magic.auto_status[rc.automagic]
524 print '\n' + Magic.auto_status[self.shell.automagic]
524
525
525 @testdec.skip_doctest
526 @testdec.skip_doctest
526 def magic_autocall(self, parameter_s = ''):
527 def magic_autocall(self, parameter_s = ''):
@@ -566,8 +567,6 b' Currently the magic system has the following functions:\\n"""'
566 # all-random (note for auto-testing)
567 # all-random (note for auto-testing)
567 """
568 """
568
569
569 rc = self.shell.rc
570
571 if parameter_s:
570 if parameter_s:
572 arg = int(parameter_s)
571 arg = int(parameter_s)
573 else:
572 else:
@@ -578,18 +577,18 b' Currently the magic system has the following functions:\\n"""'
578 return
577 return
579
578
580 if arg in (0,1,2):
579 if arg in (0,1,2):
581 rc.autocall = arg
580 self.shell.autocall = arg
582 else: # toggle
581 else: # toggle
583 if rc.autocall:
582 if self.shell.autocall:
584 self._magic_state.autocall_save = rc.autocall
583 self._magic_state.autocall_save = self.shell.autocall
585 rc.autocall = 0
584 self.shell.autocall = 0
586 else:
585 else:
587 try:
586 try:
588 rc.autocall = self._magic_state.autocall_save
587 self.shell.autocall = self._magic_state.autocall_save
589 except AttributeError:
588 except AttributeError:
590 rc.autocall = self._magic_state.autocall_save = 1
589 self.shell.autocall = self._magic_state.autocall_save = 1
591
590
592 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
591 print "Automatic calling is:",['OFF','Smart','Full'][self.shell.autocall]
593
592
594 def magic_system_verbose(self, parameter_s = ''):
593 def magic_system_verbose(self, parameter_s = ''):
595 """Set verbose printing of system calls.
594 """Set verbose printing of system calls.
@@ -600,10 +599,13 b' Currently the magic system has the following functions:\\n"""'
600 val = bool(eval(parameter_s))
599 val = bool(eval(parameter_s))
601 else:
600 else:
602 val = None
601 val = None
603
602
604 self.shell.rc_set_toggle('system_verbose',val)
603 if self.shell.system_verbose:
604 self.shell.system_verbose = False
605 else:
606 self.shell.system_verbose = True
605 print "System verbose printing is:",\
607 print "System verbose printing is:",\
606 ['OFF','ON'][self.shell.rc.system_verbose]
608 ['OFF','ON'][self.shell.system_verbose]
607
609
608
610
609 def magic_page(self, parameter_s=''):
611 def magic_page(self, parameter_s=''):
@@ -633,8 +635,8 b' Currently the magic system has the following functions:\\n"""'
633
635
634 def magic_profile(self, parameter_s=''):
636 def magic_profile(self, parameter_s=''):
635 """Print your currently active IPyhton profile."""
637 """Print your currently active IPyhton profile."""
636 if self.shell.rc.profile:
638 if self.shell.profile:
637 printpl('Current IPython profile: $self.shell.rc.profile.')
639 printpl('Current IPython profile: $self.shell.profile.')
638 else:
640 else:
639 print 'No profile active.'
641 print 'No profile active.'
640
642
@@ -720,7 +722,7 b' Currently the magic system has the following functions:\\n"""'
720 try:
722 try:
721 IPython.utils.generics.inspect_object(info.obj)
723 IPython.utils.generics.inspect_object(info.obj)
722 return
724 return
723 except ipapi.TryNext:
725 except TryNext:
724 pass
726 pass
725 # Get the docstring of the class property if it exists.
727 # Get the docstring of the class property if it exists.
726 path = oname.split('.')
728 path = oname.split('.')
@@ -848,7 +850,7 b' Currently the magic system has the following functions:\\n"""'
848 elif opts.has_key('c'):
850 elif opts.has_key('c'):
849 ignore_case = False
851 ignore_case = False
850 else:
852 else:
851 ignore_case = not shell.rc.wildcards_case_sensitive
853 ignore_case = not shell.wildcards_case_sensitive
852
854
853 # Build list of namespaces to search from user options
855 # Build list of namespaces to search from user options
854 def_search.extend(opt('s',[]))
856 def_search.extend(opt('s',[]))
@@ -1132,7 +1134,6 b' Currently the magic system has the following functions:\\n"""'
1132 log_raw_input = 'r' in opts
1134 log_raw_input = 'r' in opts
1133 timestamp = 't' in opts
1135 timestamp = 't' in opts
1134
1136
1135 rc = self.shell.rc
1136 logger = self.shell.logger
1137 logger = self.shell.logger
1137
1138
1138 # if no args are given, the defaults set in the logger constructor by
1139 # if no args are given, the defaults set in the logger constructor by
@@ -1149,11 +1150,12 b' Currently the magic system has the following functions:\\n"""'
1149 # put logfname into rc struct as if it had been called on the command
1150 # put logfname into rc struct as if it had been called on the command
1150 # line, so it ends up saved in the log header Save it in case we need
1151 # line, so it ends up saved in the log header Save it in case we need
1151 # to restore it...
1152 # to restore it...
1152 old_logfile = rc.opts.get('logfile','')
1153 old_logfile = self.shell.logfile
1153 if logfname:
1154 if logfname:
1154 logfname = os.path.expanduser(logfname)
1155 logfname = os.path.expanduser(logfname)
1155 rc.opts.logfile = logfname
1156 self.shell.logfile = logfname
1156 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1157
1158 loghead = '# IPython log file\n\n'
1157 try:
1159 try:
1158 started = logger.logstart(logfname,loghead,logmode,
1160 started = logger.logstart(logfname,loghead,logmode,
1159 log_output,timestamp,log_raw_input)
1161 log_output,timestamp,log_raw_input)
@@ -1421,7 +1423,7 b' Currently the magic system has the following functions:\\n"""'
1421 output = stdout_trap.getvalue()
1423 output = stdout_trap.getvalue()
1422 output = output.rstrip()
1424 output = output.rstrip()
1423
1425
1424 page(output,screen_lines=self.shell.rc.screen_length)
1426 page(output,screen_lines=self.shell.usable_screen_length)
1425 print sys_exit,
1427 print sys_exit,
1426
1428
1427 dump_file = opts.D[0]
1429 dump_file = opts.D[0]
@@ -1569,7 +1571,7 b' Currently the magic system has the following functions:\\n"""'
1569 return
1571 return
1570
1572
1571 if filename.lower().endswith('.ipy'):
1573 if filename.lower().endswith('.ipy'):
1572 self.api.runlines(open(filename).read())
1574 self.safe_execfile_ipy(filename)
1573 return
1575 return
1574
1576
1575 # Control the response to exit() calls made by the script being run
1577 # Control the response to exit() calls made by the script being run
@@ -1622,7 +1624,7 b' Currently the magic system has the following functions:\\n"""'
1622 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1624 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1623 else:
1625 else:
1624 if opts.has_key('d'):
1626 if opts.has_key('d'):
1625 deb = debugger.Pdb(self.shell.rc.colors)
1627 deb = debugger.Pdb(self.shell.colors)
1626 # reset Breakpoint state, which is moronically kept
1628 # reset Breakpoint state, which is moronically kept
1627 # in a class
1629 # in a class
1628 bdb.Breakpoint.next = 1
1630 bdb.Breakpoint.next = 1
@@ -1739,25 +1741,6 b' Currently the magic system has the following functions:\\n"""'
1739
1741
1740 return stats
1742 return stats
1741
1743
1742 def magic_runlog(self, parameter_s =''):
1743 """Run files as logs.
1744
1745 Usage:\\
1746 %runlog file1 file2 ...
1747
1748 Run the named files (treating them as log files) in sequence inside
1749 the interpreter, and return to the prompt. This is much slower than
1750 %run because each line is executed in a try/except block, but it
1751 allows running files with syntax errors in them.
1752
1753 Normally IPython will guess when a file is one of its own logfiles, so
1754 you can typically use %run even for logs. This shorthand allows you to
1755 force any file to be treated as a log file."""
1756
1757 for f in parameter_s.split():
1758 self.shell.safe_execfile(f,self.shell.user_ns,
1759 self.shell.user_ns,islog=1)
1760
1761 @testdec.skip_doctest
1744 @testdec.skip_doctest
1762 def magic_timeit(self, parameter_s =''):
1745 def magic_timeit(self, parameter_s =''):
1763 """Time execution of a Python statement or expression
1746 """Time execution of a Python statement or expression
@@ -2061,7 +2044,7 b' Currently the magic system has the following functions:\\n"""'
2061 #print 'rng',ranges # dbg
2044 #print 'rng',ranges # dbg
2062 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2045 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2063 macro = Macro(lines)
2046 macro = Macro(lines)
2064 self.shell.user_ns.update({name:macro})
2047 self.shell.define_macro(name, macro)
2065 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2048 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2066 print 'Macro contents:'
2049 print 'Macro contents:'
2067 print macro,
2050 print macro,
@@ -2391,7 +2374,7 b' Currently the magic system has the following functions:\\n"""'
2391 sys.stdout.flush()
2374 sys.stdout.flush()
2392 try:
2375 try:
2393 self.shell.hooks.editor(filename,lineno)
2376 self.shell.hooks.editor(filename,lineno)
2394 except ipapi.TryNext:
2377 except TryNext:
2395 warn('Could not open editor')
2378 warn('Could not open editor')
2396 return
2379 return
2397
2380
@@ -2492,7 +2475,7 b' Defaulting color scheme to \'NoColor\'"""'
2492 except:
2475 except:
2493 color_switch_err('prompt')
2476 color_switch_err('prompt')
2494 else:
2477 else:
2495 shell.rc.colors = \
2478 shell.colors = \
2496 shell.outputcache.color_table.active_scheme_name
2479 shell.outputcache.color_table.active_scheme_name
2497 # Set exception colors
2480 # Set exception colors
2498 try:
2481 try:
@@ -2509,7 +2492,7 b' Defaulting color scheme to \'NoColor\'"""'
2509 color_switch_err('system exception handler')
2492 color_switch_err('system exception handler')
2510
2493
2511 # Set info (for 'object?') colors
2494 # Set info (for 'object?') colors
2512 if shell.rc.color_info:
2495 if shell.color_info:
2513 try:
2496 try:
2514 shell.inspector.set_active_scheme(new_scheme)
2497 shell.inspector.set_active_scheme(new_scheme)
2515 except:
2498 except:
@@ -2528,17 +2511,17 b' Defaulting color scheme to \'NoColor\'"""'
2528 than more) in your system, using colored object information displays
2511 than more) in your system, using colored object information displays
2529 will not work properly. Test it and see."""
2512 will not work properly. Test it and see."""
2530
2513
2531 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2514 self.shell.color_info = not self.shell.color_info
2532 self.magic_colors(self.shell.rc.colors)
2515 self.magic_colors(self.shell.colors)
2533 print 'Object introspection functions have now coloring:',
2516 print 'Object introspection functions have now coloring:',
2534 print ['OFF','ON'][self.shell.rc.color_info]
2517 print ['OFF','ON'][int(self.shell.color_info)]
2535
2518
2536 def magic_Pprint(self, parameter_s=''):
2519 def magic_Pprint(self, parameter_s=''):
2537 """Toggle pretty printing on/off."""
2520 """Toggle pretty printing on/off."""
2538
2521
2539 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2522 self.shell.pprint = 1 - self.shell.pprint
2540 print 'Pretty printing has been turned', \
2523 print 'Pretty printing has been turned', \
2541 ['OFF','ON'][self.shell.rc.pprint]
2524 ['OFF','ON'][self.shell.pprint]
2542
2525
2543 def magic_exit(self, parameter_s=''):
2526 def magic_exit(self, parameter_s=''):
2544 """Exit IPython, confirming if configured to do so.
2527 """Exit IPython, confirming if configured to do so.
@@ -2617,52 +2600,27 b' Defaulting color scheme to \'NoColor\'"""'
2617 par = parameter_s.strip()
2600 par = parameter_s.strip()
2618 if not par:
2601 if not par:
2619 stored = self.db.get('stored_aliases', {} )
2602 stored = self.db.get('stored_aliases', {} )
2620 atab = self.shell.alias_table
2603 aliases = sorted(self.shell.alias_manager.aliases)
2621 aliases = atab.keys()
2604 # for k, v in stored:
2622 aliases.sort()
2605 # atab.append(k, v[0])
2623 res = []
2606
2624 showlast = []
2607 print "Total number of aliases:", len(aliases)
2625 for alias in aliases:
2608 return aliases
2626 special = False
2609
2627 try:
2610 # Now try to define a new one
2628 tgt = atab[alias][1]
2629 except (TypeError, AttributeError):
2630 # unsubscriptable? probably a callable
2631 tgt = atab[alias]
2632 special = True
2633 # 'interesting' aliases
2634 if (alias in stored or
2635 special or
2636 alias.lower() != os.path.splitext(tgt)[0].lower() or
2637 ' ' in tgt):
2638 showlast.append((alias, tgt))
2639 else:
2640 res.append((alias, tgt ))
2641
2642 # show most interesting aliases last
2643 res.extend(showlast)
2644 print "Total number of aliases:",len(aliases)
2645 return res
2646 try:
2611 try:
2647 alias,cmd = par.split(None,1)
2612 alias,cmd = par.split(None, 1)
2648 except:
2613 except:
2649 print oinspect.getdoc(self.magic_alias)
2614 print oinspect.getdoc(self.magic_alias)
2650 else:
2615 else:
2651 nargs = cmd.count('%s')
2616 self.shell.alias_manager.soft_define_alias(alias, cmd)
2652 if nargs>0 and cmd.find('%l')>=0:
2653 error('The %s and %l specifiers are mutually exclusive '
2654 'in alias definitions.')
2655 else: # all looks OK
2656 self.shell.alias_table[alias] = (nargs,cmd)
2657 self.shell.alias_table_validate(verbose=0)
2658 # end magic_alias
2617 # end magic_alias
2659
2618
2660 def magic_unalias(self, parameter_s = ''):
2619 def magic_unalias(self, parameter_s = ''):
2661 """Remove an alias"""
2620 """Remove an alias"""
2662
2621
2663 aname = parameter_s.strip()
2622 aname = parameter_s.strip()
2664 if aname in self.shell.alias_table:
2623 self.shell.alias_manager.undefine_alias(aname)
2665 del self.shell.alias_table[aname]
2666 stored = self.db.get('stored_aliases', {} )
2624 stored = self.db.get('stored_aliases', {} )
2667 if aname in stored:
2625 if aname in stored:
2668 print "Removing %stored alias",aname
2626 print "Removing %stored alias",aname
@@ -2683,24 +2641,21 b' Defaulting color scheme to \'NoColor\'"""'
2683 This function also resets the root module cache of module completer,
2641 This function also resets the root module cache of module completer,
2684 used on slow filesystems.
2642 used on slow filesystems.
2685 """
2643 """
2686
2644 from IPython.core.alias import InvalidAliasError
2687
2688 ip = self.api
2689
2645
2690 # for the benefit of module completer in ipy_completers.py
2646 # for the benefit of module completer in ipy_completers.py
2691 del ip.db['rootmodules']
2647 del self.db['rootmodules']
2692
2648
2693 path = [os.path.abspath(os.path.expanduser(p)) for p in
2649 path = [os.path.abspath(os.path.expanduser(p)) for p in
2694 os.environ.get('PATH','').split(os.pathsep)]
2650 os.environ.get('PATH','').split(os.pathsep)]
2695 path = filter(os.path.isdir,path)
2651 path = filter(os.path.isdir,path)
2696
2652
2697 alias_table = self.shell.alias_table
2698 syscmdlist = []
2653 syscmdlist = []
2654 # Now define isexec in a cross platform manner.
2699 if os.name == 'posix':
2655 if os.name == 'posix':
2700 isexec = lambda fname:os.path.isfile(fname) and \
2656 isexec = lambda fname:os.path.isfile(fname) and \
2701 os.access(fname,os.X_OK)
2657 os.access(fname,os.X_OK)
2702 else:
2658 else:
2703
2704 try:
2659 try:
2705 winext = os.environ['pathext'].replace(';','|').replace('.','')
2660 winext = os.environ['pathext'].replace(';','|').replace('.','')
2706 except KeyError:
2661 except KeyError:
@@ -2710,6 +2665,8 b' Defaulting color scheme to \'NoColor\'"""'
2710 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2665 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2711 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2666 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2712 savedir = os.getcwd()
2667 savedir = os.getcwd()
2668
2669 # Now walk the paths looking for executables to alias.
2713 try:
2670 try:
2714 # write the whole loop for posix/Windows so we don't have an if in
2671 # write the whole loop for posix/Windows so we don't have an if in
2715 # the innermost part
2672 # the innermost part
@@ -2717,14 +2674,16 b' Defaulting color scheme to \'NoColor\'"""'
2717 for pdir in path:
2674 for pdir in path:
2718 os.chdir(pdir)
2675 os.chdir(pdir)
2719 for ff in os.listdir(pdir):
2676 for ff in os.listdir(pdir):
2720 if isexec(ff) and ff not in self.shell.no_alias:
2677 if isexec(ff):
2721 # each entry in the alias table must be (N,name),
2678 try:
2722 # where N is the number of positional arguments of the
2679 # Removes dots from the name since ipython
2723 # alias.
2680 # will assume names with dots to be python.
2724 # Dots will be removed from alias names, since ipython
2681 self.shell.alias_manager.define_alias(
2725 # assumes names with dots to be python code
2682 ff.replace('.',''), ff)
2726 alias_table[ff.replace('.','')] = (0,ff)
2683 except InvalidAliasError:
2727 syscmdlist.append(ff)
2684 pass
2685 else:
2686 syscmdlist.append(ff)
2728 else:
2687 else:
2729 for pdir in path:
2688 for pdir in path:
2730 os.chdir(pdir)
2689 os.chdir(pdir)
@@ -2733,17 +2692,15 b' Defaulting color scheme to \'NoColor\'"""'
2733 if isexec(ff) and base.lower() not in self.shell.no_alias:
2692 if isexec(ff) and base.lower() not in self.shell.no_alias:
2734 if ext.lower() == '.exe':
2693 if ext.lower() == '.exe':
2735 ff = base
2694 ff = base
2736 alias_table[base.lower().replace('.','')] = (0,ff)
2695 try:
2737 syscmdlist.append(ff)
2696 # Removes dots from the name since ipython
2738 # Make sure the alias table doesn't contain keywords or builtins
2697 # will assume names with dots to be python.
2739 self.shell.alias_table_validate()
2698 self.shell.alias_manager.define_alias(
2740 # Call again init_auto_alias() so we get 'rm -i' and other
2699 base.lower().replace('.',''), ff)
2741 # modified aliases since %rehashx will probably clobber them
2700 except InvalidAliasError:
2742
2701 pass
2743 # no, we don't want them. if %rehashx clobbers them, good,
2702 syscmdlist.append(ff)
2744 # we'll probably get better versions
2703 db = self.db
2745 # self.shell.init_auto_alias()
2746 db = ip.db
2747 db['syscmdlist'] = syscmdlist
2704 db['syscmdlist'] = syscmdlist
2748 finally:
2705 finally:
2749 os.chdir(savedir)
2706 os.chdir(savedir)
@@ -2853,9 +2810,8 b' Defaulting color scheme to \'NoColor\'"""'
2853 if ps:
2810 if ps:
2854 try:
2811 try:
2855 os.chdir(os.path.expanduser(ps))
2812 os.chdir(os.path.expanduser(ps))
2856 if self.shell.rc.term_title:
2813 if self.shell.term_title:
2857 #print 'set term title:',self.shell.rc.term_title # dbg
2814 platutils.set_term_title('IPython: ' + abbrev_cwd())
2858 platutils.set_term_title('IPy ' + abbrev_cwd())
2859 except OSError:
2815 except OSError:
2860 print sys.exc_info()[1]
2816 print sys.exc_info()[1]
2861 else:
2817 else:
@@ -2867,8 +2823,8 b' Defaulting color scheme to \'NoColor\'"""'
2867
2823
2868 else:
2824 else:
2869 os.chdir(self.shell.home_dir)
2825 os.chdir(self.shell.home_dir)
2870 if self.shell.rc.term_title:
2826 if self.shell.term_title:
2871 platutils.set_term_title("IPy ~")
2827 platutils.set_term_title('IPython: ' + '~')
2872 cwd = os.getcwd()
2828 cwd = os.getcwd()
2873 dhist = self.shell.user_ns['_dh']
2829 dhist = self.shell.user_ns['_dh']
2874
2830
@@ -3168,10 +3124,10 b' Defaulting color scheme to \'NoColor\'"""'
3168 """
3124 """
3169
3125
3170 start = parameter_s.strip()
3126 start = parameter_s.strip()
3171 esc_magic = self.shell.ESC_MAGIC
3127 esc_magic = ESC_MAGIC
3172 # Identify magic commands even if automagic is on (which means
3128 # Identify magic commands even if automagic is on (which means
3173 # the in-memory version is different from that typed by the user).
3129 # the in-memory version is different from that typed by the user).
3174 if self.shell.rc.automagic:
3130 if self.shell.automagic:
3175 start_magic = esc_magic+start
3131 start_magic = esc_magic+start
3176 else:
3132 else:
3177 start_magic = start
3133 start_magic = start
@@ -3265,7 +3221,7 b' Defaulting color scheme to \'NoColor\'"""'
3265 return
3221 return
3266
3222
3267 page(self.shell.pycolorize(cont),
3223 page(self.shell.pycolorize(cont),
3268 screen_lines=self.shell.rc.screen_length)
3224 screen_lines=self.shell.usable_screen_length)
3269
3225
3270 def _rerun_pasted(self):
3226 def _rerun_pasted(self):
3271 """ Rerun a previously pasted command.
3227 """ Rerun a previously pasted command.
@@ -3438,7 +3394,7 b' Defaulting color scheme to \'NoColor\'"""'
3438 ipinstallation = path(IPython.__file__).dirname()
3394 ipinstallation = path(IPython.__file__).dirname()
3439 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'utils' / 'upgradedir.py')
3395 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'utils' / 'upgradedir.py')
3440 src_config = ipinstallation / 'config' / 'userconfig'
3396 src_config = ipinstallation / 'config' / 'userconfig'
3441 userdir = path(ip.options.ipythondir)
3397 userdir = path(ip.config.IPYTHONDIR)
3442 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3398 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3443 print ">",cmd
3399 print ">",cmd
3444 shell(cmd)
3400 shell(cmd)
@@ -3478,7 +3434,6 b' Defaulting color scheme to \'NoColor\'"""'
3478 # Shorthands
3434 # Shorthands
3479 shell = self.shell
3435 shell = self.shell
3480 oc = shell.outputcache
3436 oc = shell.outputcache
3481 rc = shell.rc
3482 meta = shell.meta
3437 meta = shell.meta
3483 # dstore is a data store kept in the instance metadata bag to track any
3438 # dstore is a data store kept in the instance metadata bag to track any
3484 # changes we make, so we can undo them later.
3439 # changes we make, so we can undo them later.
@@ -3487,12 +3442,12 b' Defaulting color scheme to \'NoColor\'"""'
3487
3442
3488 # save a few values we'll need to recover later
3443 # save a few values we'll need to recover later
3489 mode = save_dstore('mode',False)
3444 mode = save_dstore('mode',False)
3490 save_dstore('rc_pprint',rc.pprint)
3445 save_dstore('rc_pprint',shell.pprint)
3491 save_dstore('xmode',shell.InteractiveTB.mode)
3446 save_dstore('xmode',shell.InteractiveTB.mode)
3492 save_dstore('rc_separate_out',rc.separate_out)
3447 save_dstore('rc_separate_out',shell.separate_out)
3493 save_dstore('rc_separate_out2',rc.separate_out2)
3448 save_dstore('rc_separate_out2',shell.separate_out2)
3494 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3449 save_dstore('rc_prompts_pad_left',shell.prompts_pad_left)
3495 save_dstore('rc_separate_in',rc.separate_in)
3450 save_dstore('rc_separate_in',shell.separate_in)
3496
3451
3497 if mode == False:
3452 if mode == False:
3498 # turn on
3453 # turn on
@@ -3510,7 +3465,7 b' Defaulting color scheme to \'NoColor\'"""'
3510 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3465 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3511 oc.prompt_out.pad_left = False
3466 oc.prompt_out.pad_left = False
3512
3467
3513 rc.pprint = False
3468 shell.pprint = False
3514
3469
3515 shell.magic_xmode('Plain')
3470 shell.magic_xmode('Plain')
3516
3471
@@ -3518,9 +3473,9 b' Defaulting color scheme to \'NoColor\'"""'
3518 # turn off
3473 # turn off
3519 ipaste.deactivate_prefilter()
3474 ipaste.deactivate_prefilter()
3520
3475
3521 oc.prompt1.p_template = rc.prompt_in1
3476 oc.prompt1.p_template = shell.prompt_in1
3522 oc.prompt2.p_template = rc.prompt_in2
3477 oc.prompt2.p_template = shell.prompt_in2
3523 oc.prompt_out.p_template = rc.prompt_out
3478 oc.prompt_out.p_template = shell.prompt_out
3524
3479
3525 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3480 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3526
3481
@@ -28,7 +28,8 b' import types'
28
28
29 # IPython's own
29 # IPython's own
30 from IPython.utils import PyColorize
30 from IPython.utils import PyColorize
31 from IPython.utils.genutils import page,indent,Term
31 from IPython.utils.genutils import indent, Term
32 from IPython.core.page import page
32 from IPython.external.Itpl import itpl
33 from IPython.external.Itpl import itpl
33 from IPython.utils.wildcard import list_namespace
34 from IPython.utils.wildcard import list_namespace
34 from IPython.utils.coloransi import *
35 from IPython.utils.coloransi import *
This diff has been collapsed as it changes many lines, (1151 lines changed) Show them Hide them
@@ -1,14 +1,103 b''
1 # -*- coding: utf-8 -*-
1 #!/usr/bin/env python
2 # encoding: utf-8
2 """
3 """
3 Classes and functions for prefiltering (transforming) a line of user input.
4 Prefiltering components.
4 This module is responsible, primarily, for breaking the line up into useful
5
5 pieces and triggering the appropriate handlers in iplib to do the actual
6 Prefilters transform user input before it is exec'd by Python. These
6 transforming work.
7 transforms are used to implement additional syntax such as !ls and %magic.
8
9 Authors:
10
11 * Brian Granger
12 * Fernando Perez
13 * Dan Milstein
14 * Ville Vainio
7 """
15 """
8 __docformat__ = "restructuredtext en"
9
16
17 #-----------------------------------------------------------------------------
18 # Copyright (C) 2008-2009 The IPython Development Team
19 #
20 # Distributed under the terms of the BSD License. The full license is in
21 # the file COPYING, distributed as part of this software.
22 #-----------------------------------------------------------------------------
23
24 #-----------------------------------------------------------------------------
25 # Imports
26 #-----------------------------------------------------------------------------
27
28 import __builtin__
29 import codeop
30 import keyword
31 import os
10 import re
32 import re
11 from IPython.core import ipapi
33 import sys
34
35 from IPython.core.alias import AliasManager
36 from IPython.core.autocall import IPyAutocall
37 from IPython.core.component import Component
38 from IPython.core.splitinput import split_user_input
39 from IPython.core.page import page
40
41 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool
42 from IPython.utils.genutils import make_quoted_expr
43 from IPython.utils.autoattr import auto_attr
44
45 #-----------------------------------------------------------------------------
46 # Global utilities, errors and constants
47 #-----------------------------------------------------------------------------
48
49 # Warning, these cannot be changed unless various regular expressions
50 # are updated in a number of places. Not great, but at least we told you.
51 ESC_SHELL = '!'
52 ESC_SH_CAP = '!!'
53 ESC_HELP = '?'
54 ESC_MAGIC = '%'
55 ESC_QUOTE = ','
56 ESC_QUOTE2 = ';'
57 ESC_PAREN = '/'
58
59
60 class PrefilterError(Exception):
61 pass
62
63
64 # RegExp to identify potential function names
65 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
66
67 # RegExp to exclude strings with this start from autocalling. In
68 # particular, all binary operators should be excluded, so that if foo is
69 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
70 # characters '!=()' don't need to be checked for, as the checkPythonChars
71 # routine explicitely does so, to catch direct calls and rebindings of
72 # existing names.
73
74 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
75 # it affects the rest of the group in square brackets.
76 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
77 r'|^is |^not |^in |^and |^or ')
78
79 # try to catch also methods for stuff in lists/tuples/dicts: off
80 # (experimental). For this to work, the line_split regexp would need
81 # to be modified so it wouldn't break things at '['. That line is
82 # nasty enough that I shouldn't change it until I can test it _well_.
83 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
84
85
86 # Handler Check Utilities
87 def is_shadowed(identifier, ip):
88 """Is the given identifier defined in one of the namespaces which shadow
89 the alias and magic namespaces? Note that an identifier is different
90 than ifun, because it can not contain a '.' character."""
91 # This is much safer than calling ofind, which can change state
92 return (identifier in ip.user_ns \
93 or identifier in ip.internal_ns \
94 or identifier in ip.ns_table['builtin'])
95
96
97 #-----------------------------------------------------------------------------
98 # The LineInfo class used throughout
99 #-----------------------------------------------------------------------------
100
12
101
13 class LineInfo(object):
102 class LineInfo(object):
14 """A single line of input and associated info.
103 """A single line of input and associated info.
@@ -24,39 +113,39 b' class LineInfo(object):'
24 pre
113 pre
25 The initial esc character or whitespace.
114 The initial esc character or whitespace.
26
115
27 preChar
116 pre_char
28 The escape character(s) in pre or the empty string if there isn't one.
117 The escape character(s) in pre or the empty string if there isn't one.
29 Note that '!!' is a possible value for preChar. Otherwise it will
118 Note that '!!' is a possible value for pre_char. Otherwise it will
30 always be a single character.
119 always be a single character.
31
120
32 preWhitespace
121 pre_whitespace
33 The leading whitespace from pre if it exists. If there is a preChar,
122 The leading whitespace from pre if it exists. If there is a pre_char,
34 this is just ''.
123 this is just ''.
35
124
36 iFun
125 ifun
37 The 'function part', which is basically the maximal initial sequence
126 The 'function part', which is basically the maximal initial sequence
38 of valid python identifiers and the '.' character. This is what is
127 of valid python identifiers and the '.' character. This is what is
39 checked for alias and magic transformations, used for auto-calling,
128 checked for alias and magic transformations, used for auto-calling,
40 etc.
129 etc.
41
130
42 theRest
131 the_rest
43 Everything else on the line.
132 Everything else on the line.
44 """
133 """
45 def __init__(self, line, continue_prompt):
134 def __init__(self, line, continue_prompt):
46 self.line = line
135 self.line = line
47 self.continue_prompt = continue_prompt
136 self.continue_prompt = continue_prompt
48 self.pre, self.iFun, self.theRest = splitUserInput(line)
137 self.pre, self.ifun, self.the_rest = split_user_input(line)
49
138
50 self.preChar = self.pre.strip()
139 self.pre_char = self.pre.strip()
51 if self.preChar:
140 if self.pre_char:
52 self.preWhitespace = '' # No whitespace allowd before esc chars
141 self.pre_whitespace = '' # No whitespace allowd before esc chars
53 else:
142 else:
54 self.preWhitespace = self.pre
143 self.pre_whitespace = self.pre
55
144
56 self._oinfo = None
145 self._oinfo = None
57
146
58 def ofind(self, ip):
147 def ofind(self, ip):
59 """Do a full, attribute-walking lookup of the iFun in the various
148 """Do a full, attribute-walking lookup of the ifun in the various
60 namespaces for the given IPython InteractiveShell instance.
149 namespaces for the given IPython InteractiveShell instance.
61
150
62 Return a dict with keys: found,obj,ospace,ismagic
151 Return a dict with keys: found,obj,ospace,ismagic
@@ -69,252 +158,838 b' class LineInfo(object):'
69 without worrying about *further* damaging state.
158 without worrying about *further* damaging state.
70 """
159 """
71 if not self._oinfo:
160 if not self._oinfo:
72 self._oinfo = ip._ofind(self.iFun)
161 self._oinfo = ip._ofind(self.ifun)
73 return self._oinfo
162 return self._oinfo
163
74 def __str__(self):
164 def __str__(self):
75 return "Lineinfo [%s|%s|%s]" %(self.pre,self.iFun,self.theRest)
165 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
76
166
77 def splitUserInput(line, pattern=None):
78 """Split user input into pre-char/whitespace, function part and rest.
79
167
80 Mostly internal to this module, but also used by iplib.expand_aliases,
168 #-----------------------------------------------------------------------------
81 which passes in a shell pattern.
169 # Main Prefilter manager
82 """
170 #-----------------------------------------------------------------------------
83 # It seems to me that the shell splitting should be a separate method.
84
85 if not pattern:
86 pattern = line_split
87 match = pattern.match(line)
88 if not match:
89 #print "match failed for line '%s'" % line
90 try:
91 iFun,theRest = line.split(None,1)
92 except ValueError:
93 #print "split failed for line '%s'" % line
94 iFun,theRest = line,''
95 pre = re.match('^(\s*)(.*)',line).groups()[0]
96 else:
97 pre,iFun,theRest = match.groups()
98
99 # iFun has to be a valid python identifier, so it better be only pure
100 # ascii, no unicode:
101 try:
102 iFun = iFun.encode('ascii')
103 except UnicodeEncodeError:
104 theRest = iFun + u' ' + theRest
105 iFun = u''
106
107 #print 'line:<%s>' % line # dbg
108 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
109 return pre,iFun.strip(),theRest.lstrip()
110
111
112 # RegExp for splitting line contents into pre-char//first word-method//rest.
113 # For clarity, each group in on one line.
114
115 # WARNING: update the regexp if the escapes in iplib are changed, as they
116 # are hardwired in.
117
118 # Although it's not solely driven by the regex, note that:
119 # ,;/% only trigger if they are the first character on the line
120 # ! and !! trigger if they are first char(s) *or* follow an indent
121 # ? triggers as first or last char.
122
123 # The three parts of the regex are:
124 # 1) pre: pre_char *or* initial whitespace
125 # 2) iFun: first word/method (mix of \w and '.')
126 # 3) theRest: rest of line (separated from iFun by space if non-empty)
127 line_split = re.compile(r'^([,;/%?]|!!?|\s*)'
128 r'\s*([\w\.]+)'
129 r'(\s+.*$|$)')
130
131 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
132
133 def prefilter(line_info, ip):
134 """Call one of the passed-in InteractiveShell's handler preprocessors,
135 depending on the form of the line. Return the results, which must be a
136 value, even if it's a blank ('')."""
137 # Note: the order of these checks does matter.
138 for check in [ checkEmacs,
139 checkShellEscape,
140 checkIPyAutocall,
141 checkMultiLineMagic,
142 checkEscChars,
143 checkAssignment,
144 checkAutomagic,
145 checkAlias,
146 checkPythonOps,
147 checkAutocall,
148 ]:
149 handler = check(line_info, ip)
150 if handler:
151 return handler(line_info)
152
153 return ip.handle_normal(line_info)
154
155 # Handler checks
156 #
157 # All have the same interface: they take a LineInfo object and a ref to the
158 # iplib.InteractiveShell object. They check the line to see if a particular
159 # handler should be called, and return either a handler or None. The
160 # handlers which they return are *bound* methods of the InteractiveShell
161 # object.
162 #
163 # In general, these checks should only take responsibility for their 'own'
164 # handler. If it doesn't get triggered, they should just return None and
165 # let the rest of the check sequence run.
166
167 def checkShellEscape(l_info,ip):
168 if l_info.line.lstrip().startswith(ip.ESC_SHELL):
169 return ip.handle_shell_escape
170
171 def checkEmacs(l_info,ip):
172 "Emacs ipython-mode tags certain input lines."
173 if l_info.line.endswith('# PYTHON-MODE'):
174 return ip.handle_emacs
175 else:
176 return None
177
171
178 def checkIPyAutocall(l_info,ip):
179 "Instances of IPyAutocall in user_ns get autocalled immediately"
180 obj = ip.user_ns.get(l_info.iFun, None)
181 if isinstance(obj, ipapi.IPyAutocall):
182 obj.set_ip(ip.api)
183 return ip.handle_auto
184 else:
185 return None
186
187
188 def checkMultiLineMagic(l_info,ip):
189 "Allow ! and !! in multi-line statements if multi_line_specials is on"
190 # Note that this one of the only places we check the first character of
191 # iFun and *not* the preChar. Also note that the below test matches
192 # both ! and !!.
193 if l_info.continue_prompt \
194 and ip.rc.multi_line_specials:
195 if l_info.iFun.startswith(ip.ESC_MAGIC):
196 return ip.handle_magic
197 else:
198 return None
199
172
200 def checkEscChars(l_info,ip):
173 class PrefilterManager(Component):
201 """Check for escape character and return either a handler to handle it,
174 """Main prefilter component.
202 or None if there is no escape char."""
175
203 if l_info.line[-1] == ip.ESC_HELP \
176 The IPython prefilter is run on all user input before it is run. The
204 and l_info.preChar != ip.ESC_SHELL \
177 prefilter consumes lines of input and produces transformed lines of
205 and l_info.preChar != ip.ESC_SH_CAP:
178 input.
206 # the ? can be at the end, but *not* for either kind of shell escape,
179
207 # because a ? can be a vaild final char in a shell cmd
180 The iplementation consists of two phases:
208 return ip.handle_help
181
209 elif l_info.preChar in ip.esc_handlers:
182 1. Transformers
210 return ip.esc_handlers[l_info.preChar]
183 2. Checkers and handlers
211 else:
184
212 return None
185 Over time, we plan on deprecating the checkers and handlers and doing
186 everything in the transformers.
213
187
188 The transformers are instances of :class:`PrefilterTransformer` and have
189 a single method :meth:`transform` that takes a line and returns a
190 transformed line. The transformation can be accomplished using any
191 tool, but our current ones use regular expressions for speed. We also
192 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
214
193
215 def checkAssignment(l_info,ip):
194 After all the transformers have been run, the line is fed to the checkers,
216 """Check to see if user is assigning to a var for the first time, in
195 which are instances of :class:`PrefilterChecker`. The line is passed to
217 which case we want to avoid any sort of automagic / autocall games.
196 the :meth:`check` method, which either returns `None` or a
197 :class:`PrefilterHandler` instance. If `None` is returned, the other
198 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
199 the line is passed to the :meth:`handle` method of the returned
200 handler and no further checkers are tried.
218
201
219 This allows users to assign to either alias or magic names true python
202 Both transformers and checkers have a `priority` attribute, that determines
220 variables (the magic/alias systems always take second seat to true
203 the order in which they are called. Smaller priorities are tried first.
221 python code). E.g. ls='hi', or ls,that=1,2"""
222 if l_info.theRest and l_info.theRest[0] in '=,':
223 return ip.handle_normal
224 else:
225 return None
226
204
205 Both transformers and checkers also have `enabled` attribute, which is
206 a boolean that determines if the instance is used.
227
207
228 def checkAutomagic(l_info,ip):
208 Users or developers can change the priority or enabled attribute of
229 """If the iFun is magic, and automagic is on, run it. Note: normal,
209 transformers or checkers, but they must call the :meth:`sort_checkers`
230 non-auto magic would already have been triggered via '%' in
210 or :meth:`sort_transformers` method after changing the priority.
231 check_esc_chars. This just checks for automagic. Also, before
211 """
232 triggering the magic handler, make sure that there is nothing in the
233 user namespace which could shadow it."""
234 if not ip.rc.automagic or not hasattr(ip,'magic_'+l_info.iFun):
235 return None
236
212
237 # We have a likely magic method. Make sure we should actually call it.
213 multi_line_specials = CBool(True, config=True)
238 if l_info.continue_prompt and not ip.rc.multi_line_specials:
239 return None
240
214
241 head = l_info.iFun.split('.',1)[0]
215 def __init__(self, parent, config=None):
242 if isShadowed(head,ip):
216 super(PrefilterManager, self).__init__(parent, config=config)
243 return None
217 self.init_transformers()
218 self.init_handlers()
219 self.init_checkers()
220
221 @auto_attr
222 def shell(self):
223 return Component.get_instances(
224 root=self.root,
225 klass='IPython.core.iplib.InteractiveShell')[0]
244
226
245 return ip.handle_magic
227 #-------------------------------------------------------------------------
228 # API for managing transformers
229 #-------------------------------------------------------------------------
246
230
231 def init_transformers(self):
232 """Create the default transformers."""
233 self._transformers = []
234 for transformer_cls in _default_transformers:
235 transformer_cls(self, config=self.config)
236
237 def sort_transformers(self):
238 """Sort the transformers by priority.
239
240 This must be called after the priority of a transformer is changed.
241 The :meth:`register_transformer` method calls this automatically.
242 """
243 self._transformers.sort(cmp=lambda x,y: x.priority-y.priority)
244
245 @property
246 def transformers(self):
247 """Return a list of checkers, sorted by priority."""
248 return self._transformers
249
250 def register_transformer(self, transformer):
251 """Register a transformer instance."""
252 if transformer not in self._transformers:
253 self._transformers.append(transformer)
254 self.sort_transformers()
255
256 def unregister_transformer(self, transformer):
257 """Unregister a transformer instance."""
258 if transformer in self._transformers:
259 self._transformers.remove(transformer)
260
261 #-------------------------------------------------------------------------
262 # API for managing checkers
263 #-------------------------------------------------------------------------
264
265 def init_checkers(self):
266 """Create the default checkers."""
267 self._checkers = []
268 for checker in _default_checkers:
269 checker(self, config=self.config)
270
271 def sort_checkers(self):
272 """Sort the checkers by priority.
273
274 This must be called after the priority of a checker is changed.
275 The :meth:`register_checker` method calls this automatically.
276 """
277 self._checkers.sort(cmp=lambda x,y: x.priority-y.priority)
278
279 @property
280 def checkers(self):
281 """Return a list of checkers, sorted by priority."""
282 return self._checkers
283
284 def register_checker(self, checker):
285 """Register a checker instance."""
286 if checker not in self._checkers:
287 self._checkers.append(checker)
288 self.sort_checkers()
289
290 def unregister_checker(self, checker):
291 """Unregister a checker instance."""
292 if checker in self._checkers:
293 self._checkers.remove(checker)
294
295 #-------------------------------------------------------------------------
296 # API for managing checkers
297 #-------------------------------------------------------------------------
298
299 def init_handlers(self):
300 """Create the default handlers."""
301 self._handlers = {}
302 self._esc_handlers = {}
303 for handler in _default_handlers:
304 handler(self, config=self.config)
305
306 @property
307 def handlers(self):
308 """Return a dict of all the handlers."""
309 return self._handlers
310
311 def register_handler(self, name, handler, esc_strings):
312 """Register a handler instance by name with esc_strings."""
313 self._handlers[name] = handler
314 for esc_str in esc_strings:
315 self._esc_handlers[esc_str] = handler
316
317 def unregister_handler(self, name, handler, esc_strings):
318 """Unregister a handler instance by name with esc_strings."""
319 try:
320 del self._handlers[name]
321 except KeyError:
322 pass
323 for esc_str in esc_strings:
324 h = self._esc_handlers.get(esc_str)
325 if h is handler:
326 del self._esc_handlers[esc_str]
327
328 def get_handler_by_name(self, name):
329 """Get a handler by its name."""
330 return self._handlers.get(name)
331
332 def get_handler_by_esc(self, esc_str):
333 """Get a handler by its escape string."""
334 return self._esc_handlers.get(esc_str)
335
336 #-------------------------------------------------------------------------
337 # Main prefiltering API
338 #-------------------------------------------------------------------------
339
340 def prefilter_line_info(self, line_info):
341 """Prefilter a line that has been converted to a LineInfo object.
342
343 This implements the checker/handler part of the prefilter pipe.
344 """
345 # print "prefilter_line_info: ", line_info
346 handler = self.find_handler(line_info)
347 return handler.handle(line_info)
348
349 def find_handler(self, line_info):
350 """Find a handler for the line_info by trying checkers."""
351 for checker in self.checkers:
352 if checker.enabled:
353 handler = checker.check(line_info)
354 if handler:
355 return handler
356 return self.get_handler_by_name('normal')
357
358 def transform_line(self, line, continue_prompt):
359 """Calls the enabled transformers in order of increasing priority."""
360 for transformer in self.transformers:
361 if transformer.enabled:
362 line = transformer.transform(line, continue_prompt)
363 return line
364
365 def prefilter_line(self, line, continue_prompt):
366 """Prefilter a single input line as text.
367
368 This method prefilters a single line of text by calling the
369 transformers and then the checkers/handlers.
370 """
371
372 # print "prefilter_line: ", line, continue_prompt
373 # All handlers *must* return a value, even if it's blank ('').
374
375 # Lines are NOT logged here. Handlers should process the line as
376 # needed, update the cache AND log it (so that the input cache array
377 # stays synced).
378
379 # save the line away in case we crash, so the post-mortem handler can
380 # record it
381 self.shell._last_input_line = line
382
383 if not line:
384 # Return immediately on purely empty lines, so that if the user
385 # previously typed some whitespace that started a continuation
386 # prompt, he can break out of that loop with just an empty line.
387 # This is how the default python prompt works.
388
389 # Only return if the accumulated input buffer was just whitespace!
390 if ''.join(self.shell.buffer).isspace():
391 self.shell.buffer[:] = []
392 return ''
393
394 # At this point, we invoke our transformers.
395 if not continue_prompt or (continue_prompt and self.multi_line_specials):
396 line = self.transform_line(line, continue_prompt)
397
398 # Now we compute line_info for the checkers and handlers
399 line_info = LineInfo(line, continue_prompt)
247
400
248 def checkAlias(l_info,ip):
401 # the input history needs to track even empty lines
249 "Check if the initital identifier on the line is an alias."
402 stripped = line.strip()
250 # Note: aliases can not contain '.'
251 head = l_info.iFun.split('.',1)[0]
252
253 if l_info.iFun not in ip.alias_table \
254 or head not in ip.alias_table \
255 or isShadowed(head,ip):
256 return None
257
403
258 return ip.handle_alias
404 normal_handler = self.get_handler_by_name('normal')
405 if not stripped:
406 if not continue_prompt:
407 self.shell.outputcache.prompt_count -= 1
259
408
409 return normal_handler.handle(line_info)
260
410
261 def checkPythonOps(l_info,ip):
411 # special handlers are only allowed for single line statements
262 """If the 'rest' of the line begins with a function call or pretty much
412 if continue_prompt and not self.multi_line_specials:
263 any python operator, we should simply execute the line (regardless of
413 return normal_handler.handle(line_info)
264 whether or not there's a possible autocall expansion). This avoids
265 spurious (and very confusing) geattr() accesses."""
266 if l_info.theRest and l_info.theRest[0] in '!=()<>,+*/%^&|':
267 return ip.handle_normal
268 else:
269 return None
270
414
415 prefiltered = self.prefilter_line_info(line_info)
416 # print "prefiltered line: %r" % prefiltered
417 return prefiltered
271
418
272 def checkAutocall(l_info,ip):
419 def prefilter_lines(self, lines, continue_prompt):
273 "Check if the initial word/function is callable and autocall is on."
420 """Prefilter multiple input lines of text.
274 if not ip.rc.autocall:
421
275 return None
422 This is the main entry point for prefiltering multiple lines of
423 input. This simply calls :meth:`prefilter_line` for each line of
424 input.
425
426 This covers cases where there are multiple lines in the user entry,
427 which is the case when the user goes back to a multiline history
428 entry and presses enter.
429 """
430 out = []
431 for line in lines.rstrip('\n').split('\n'):
432 out.append(self.prefilter_line(line, continue_prompt))
433 return '\n'.join(out)
434
435
436 #-----------------------------------------------------------------------------
437 # Prefilter transformers
438 #-----------------------------------------------------------------------------
439
440
441 class PrefilterTransformer(Component):
442 """Transform a line of user input."""
443
444 priority = Int(100, config=True)
445 shell = Any
446 prefilter_manager = Any
447 enabled = Bool(True, config=True)
448
449 def __init__(self, parent, config=None):
450 super(PrefilterTransformer, self).__init__(parent, config=config)
451 self.prefilter_manager.register_transformer(self)
452
453 @auto_attr
454 def shell(self):
455 return Component.get_instances(
456 root=self.root,
457 klass='IPython.core.iplib.InteractiveShell')[0]
458
459 @auto_attr
460 def prefilter_manager(self):
461 return PrefilterManager.get_instances(root=self.root)[0]
276
462
277 oinfo = l_info.ofind(ip) # This can mutate state via getattr
463 def transform(self, line, continue_prompt):
278 if not oinfo['found']:
464 """Transform a line, returning the new one."""
279 return None
465 return None
280
466
281 if callable(oinfo['obj']) \
467 def __repr__(self):
282 and (not re_exclude_auto.match(l_info.theRest)) \
468 return "<%s(priority=%r, enabled=%r)>" % (
283 and re_fun_name.match(l_info.iFun):
469 self.__class__.__name__, self.priority, self.enabled)
284 #print 'going auto' # dbg
470
285 return ip.handle_auto
471
286 else:
472 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
287 #print 'was callable?', callable(l_info.oinfo['obj']) # dbg
473 r'\s*=\s*!(?P<cmd>.*)')
474
475
476 class AssignSystemTransformer(PrefilterTransformer):
477 """Handle the `files = !ls` syntax."""
478
479 priority = Int(100, config=True)
480
481 def transform(self, line, continue_prompt):
482 m = _assign_system_re.match(line)
483 if m is not None:
484 cmd = m.group('cmd')
485 lhs = m.group('lhs')
486 expr = make_quoted_expr("sc -l =%s" % cmd)
487 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
488 return new_line
489 return line
490
491
492 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
493 r'\s*=\s*%(?P<cmd>.*)')
494
495 class AssignMagicTransformer(PrefilterTransformer):
496 """Handle the `a = %who` syntax."""
497
498 priority = Int(200, config=True)
499
500 def transform(self, line, continue_prompt):
501 m = _assign_magic_re.match(line)
502 if m is not None:
503 cmd = m.group('cmd')
504 lhs = m.group('lhs')
505 expr = make_quoted_expr(cmd)
506 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
507 return new_line
508 return line
509
510
511 #-----------------------------------------------------------------------------
512 # Prefilter checkers
513 #-----------------------------------------------------------------------------
514
515
516 class PrefilterChecker(Component):
517 """Inspect an input line and return a handler for that line."""
518
519 priority = Int(100, config=True)
520 shell = Any
521 prefilter_manager = Any
522 enabled = Bool(True, config=True)
523
524 def __init__(self, parent, config=None):
525 super(PrefilterChecker, self).__init__(parent, config=config)
526 self.prefilter_manager.register_checker(self)
527
528 @auto_attr
529 def shell(self):
530 return Component.get_instances(
531 root=self.root,
532 klass='IPython.core.iplib.InteractiveShell')[0]
533
534 @auto_attr
535 def prefilter_manager(self):
536 return PrefilterManager.get_instances(root=self.root)[0]
537
538 def check(self, line_info):
539 """Inspect line_info and return a handler instance or None."""
288 return None
540 return None
541
542 def __repr__(self):
543 return "<%s(priority=%r, enabled=%r)>" % (
544 self.__class__.__name__, self.priority, self.enabled)
545
546
547 class EmacsChecker(PrefilterChecker):
548
549 priority = Int(100, config=True)
550 enabled = Bool(False, config=True)
551
552 def check(self, line_info):
553 "Emacs ipython-mode tags certain input lines."
554 if line_info.line.endswith('# PYTHON-MODE'):
555 return self.prefilter_manager.get_handler_by_name('emacs')
556 else:
557 return None
558
559
560 class ShellEscapeChecker(PrefilterChecker):
561
562 priority = Int(200, config=True)
563
564 def check(self, line_info):
565 if line_info.line.lstrip().startswith(ESC_SHELL):
566 return self.prefilter_manager.get_handler_by_name('shell')
567
568
569 class IPyAutocallChecker(PrefilterChecker):
570
571 priority = Int(300, config=True)
572
573 def check(self, line_info):
574 "Instances of IPyAutocall in user_ns get autocalled immediately"
575 obj = self.shell.user_ns.get(line_info.ifun, None)
576 if isinstance(obj, IPyAutocall):
577 obj.set_ip(self.shell)
578 return self.prefilter_manager.get_handler_by_name('auto')
579 else:
580 return None
581
582
583 class MultiLineMagicChecker(PrefilterChecker):
584
585 priority = Int(400, config=True)
586
587 def check(self, line_info):
588 "Allow ! and !! in multi-line statements if multi_line_specials is on"
589 # Note that this one of the only places we check the first character of
590 # ifun and *not* the pre_char. Also note that the below test matches
591 # both ! and !!.
592 if line_info.continue_prompt \
593 and self.prefilter_manager.multi_line_specials:
594 if line_info.ifun.startswith(ESC_MAGIC):
595 return self.prefilter_manager.get_handler_by_name('magic')
596 else:
597 return None
598
599
600 class EscCharsChecker(PrefilterChecker):
601
602 priority = Int(500, config=True)
603
604 def check(self, line_info):
605 """Check for escape character and return either a handler to handle it,
606 or None if there is no escape char."""
607 if line_info.line[-1] == ESC_HELP \
608 and line_info.pre_char != ESC_SHELL \
609 and line_info.pre_char != ESC_SH_CAP:
610 # the ? can be at the end, but *not* for either kind of shell escape,
611 # because a ? can be a vaild final char in a shell cmd
612 return self.prefilter_manager.get_handler_by_name('help')
613 else:
614 # This returns None like it should if no handler exists
615 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
616
617
618 class AssignmentChecker(PrefilterChecker):
619
620 priority = Int(600, config=True)
621
622 def check(self, line_info):
623 """Check to see if user is assigning to a var for the first time, in
624 which case we want to avoid any sort of automagic / autocall games.
289
625
290 # RegExp to identify potential function names
626 This allows users to assign to either alias or magic names true python
291 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
627 variables (the magic/alias systems always take second seat to true
628 python code). E.g. ls='hi', or ls,that=1,2"""
629 if line_info.the_rest:
630 if line_info.the_rest[0] in '=,':
631 return self.prefilter_manager.get_handler_by_name('normal')
632 else:
633 return None
292
634
293 # RegExp to exclude strings with this start from autocalling. In
294 # particular, all binary operators should be excluded, so that if foo is
295 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
296 # characters '!=()' don't need to be checked for, as the checkPythonChars
297 # routine explicitely does so, to catch direct calls and rebindings of
298 # existing names.
299
635
300 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
636 class AutoMagicChecker(PrefilterChecker):
301 # it affects the rest of the group in square brackets.
302 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
303 r'|^is |^not |^in |^and |^or ')
304
637
305 # try to catch also methods for stuff in lists/tuples/dicts: off
638 priority = Int(700, config=True)
306 # (experimental). For this to work, the line_split regexp would need
307 # to be modified so it wouldn't break things at '['. That line is
308 # nasty enough that I shouldn't change it until I can test it _well_.
309 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
310
639
311 # Handler Check Utilities
640 def check(self, line_info):
312 def isShadowed(identifier,ip):
641 """If the ifun is magic, and automagic is on, run it. Note: normal,
313 """Is the given identifier defined in one of the namespaces which shadow
642 non-auto magic would already have been triggered via '%' in
314 the alias and magic namespaces? Note that an identifier is different
643 check_esc_chars. This just checks for automagic. Also, before
315 than iFun, because it can not contain a '.' character."""
644 triggering the magic handler, make sure that there is nothing in the
316 # This is much safer than calling ofind, which can change state
645 user namespace which could shadow it."""
317 return (identifier in ip.user_ns \
646 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
318 or identifier in ip.internal_ns \
647 return None
319 or identifier in ip.ns_table['builtin'])
648
649 # We have a likely magic method. Make sure we should actually call it.
650 if line_info.continue_prompt and not self.shell.multi_line_specials:
651 return None
652
653 head = line_info.ifun.split('.',1)[0]
654 if is_shadowed(head, self.shell):
655 return None
656
657 return self.prefilter_manager.get_handler_by_name('magic')
658
659
660 class AliasChecker(PrefilterChecker):
661
662 priority = Int(800, config=True)
663
664 @auto_attr
665 def alias_manager(self):
666 return AliasManager.get_instances(root=self.root)[0]
667
668 def check(self, line_info):
669 "Check if the initital identifier on the line is an alias."
670 # Note: aliases can not contain '.'
671 head = line_info.ifun.split('.',1)[0]
672 if line_info.ifun not in self.alias_manager \
673 or head not in self.alias_manager \
674 or is_shadowed(head, self.shell):
675 return None
676
677 return self.prefilter_manager.get_handler_by_name('alias')
678
679
680 class PythonOpsChecker(PrefilterChecker):
681
682 priority = Int(900, config=True)
683
684 def check(self, line_info):
685 """If the 'rest' of the line begins with a function call or pretty much
686 any python operator, we should simply execute the line (regardless of
687 whether or not there's a possible autocall expansion). This avoids
688 spurious (and very confusing) geattr() accesses."""
689 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
690 return self.prefilter_manager.get_handler_by_name('normal')
691 else:
692 return None
693
694
695 class AutocallChecker(PrefilterChecker):
696
697 priority = Int(1000, config=True)
698
699 def check(self, line_info):
700 "Check if the initial word/function is callable and autocall is on."
701 if not self.shell.autocall:
702 return None
703
704 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
705 if not oinfo['found']:
706 return None
707
708 if callable(oinfo['obj']) \
709 and (not re_exclude_auto.match(line_info.the_rest)) \
710 and re_fun_name.match(line_info.ifun):
711 return self.prefilter_manager.get_handler_by_name('auto')
712 else:
713 return None
714
715
716 #-----------------------------------------------------------------------------
717 # Prefilter handlers
718 #-----------------------------------------------------------------------------
719
720
721 class PrefilterHandler(Component):
722
723 handler_name = Str('normal')
724 esc_strings = List([])
725 shell = Any
726 prefilter_manager = Any
727
728 def __init__(self, parent, config=None):
729 super(PrefilterHandler, self).__init__(parent, config=config)
730 self.prefilter_manager.register_handler(
731 self.handler_name,
732 self,
733 self.esc_strings
734 )
735
736 @auto_attr
737 def shell(self):
738 return Component.get_instances(
739 root=self.root,
740 klass='IPython.core.iplib.InteractiveShell')[0]
741
742 @auto_attr
743 def prefilter_manager(self):
744 return PrefilterManager.get_instances(root=self.root)[0]
745
746 def handle(self, line_info):
747 # print "normal: ", line_info
748 """Handle normal input lines. Use as a template for handlers."""
749
750 # With autoindent on, we need some way to exit the input loop, and I
751 # don't want to force the user to have to backspace all the way to
752 # clear the line. The rule will be in this case, that either two
753 # lines of pure whitespace in a row, or a line of pure whitespace but
754 # of a size different to the indent level, will exit the input loop.
755 line = line_info.line
756 continue_prompt = line_info.continue_prompt
757
758 if (continue_prompt and self.shell.autoindent and line.isspace() and
759 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
760 (self.shell.buffer[-1]).isspace() )):
761 line = ''
762
763 self.shell.log(line, line, continue_prompt)
764 return line
765
766 def __str__(self):
767 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
768
769
770 class AliasHandler(PrefilterHandler):
771
772 handler_name = Str('alias')
773
774 @auto_attr
775 def alias_manager(self):
776 return AliasManager.get_instances(root=self.root)[0]
777
778 def handle(self, line_info):
779 """Handle alias input lines. """
780 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
781 # pre is needed, because it carries the leading whitespace. Otherwise
782 # aliases won't work in indented sections.
783 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
784 make_quoted_expr(transformed))
785
786 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
787 return line_out
788
789
790 class ShellEscapeHandler(PrefilterHandler):
791
792 handler_name = Str('shell')
793 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
794
795 def handle(self, line_info):
796 """Execute the line in a shell, empty return value"""
797 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
798
799 line = line_info.line
800 if line.lstrip().startswith(ESC_SH_CAP):
801 # rewrite LineInfo's line, ifun and the_rest to properly hold the
802 # call to %sx and the actual command to be executed, so
803 # handle_magic can work correctly. Note that this works even if
804 # the line is indented, so it handles multi_line_specials
805 # properly.
806 new_rest = line.lstrip()[2:]
807 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
808 line_info.ifun = 'sx'
809 line_info.the_rest = new_rest
810 return magic_handler.handle(line_info)
811 else:
812 cmd = line.lstrip().lstrip(ESC_SHELL)
813 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
814 make_quoted_expr(cmd))
815 # update cache/log and return
816 self.shell.log(line, line_out, line_info.continue_prompt)
817 return line_out
818
819
820 class MagicHandler(PrefilterHandler):
821
822 handler_name = Str('magic')
823 esc_strings = List([ESC_MAGIC])
824
825 def handle(self, line_info):
826 """Execute magic functions."""
827 ifun = line_info.ifun
828 the_rest = line_info.the_rest
829 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
830 make_quoted_expr(ifun + " " + the_rest))
831 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
832 return cmd
833
834
835 class AutoHandler(PrefilterHandler):
836
837 handler_name = Str('auto')
838 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
839
840 def handle(self, line_info):
841 """Hande lines which can be auto-executed, quoting if requested."""
842 line = line_info.line
843 ifun = line_info.ifun
844 the_rest = line_info.the_rest
845 pre = line_info.pre
846 continue_prompt = line_info.continue_prompt
847 obj = line_info.ofind(self)['obj']
848
849 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
850
851 # This should only be active for single-line input!
852 if continue_prompt:
853 self.log(line,line,continue_prompt)
854 return line
855
856 force_auto = isinstance(obj, IPyAutocall)
857 auto_rewrite = True
858
859 if pre == ESC_QUOTE:
860 # Auto-quote splitting on whitespace
861 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
862 elif pre == ESC_QUOTE2:
863 # Auto-quote whole string
864 newcmd = '%s("%s")' % (ifun,the_rest)
865 elif pre == ESC_PAREN:
866 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
867 else:
868 # Auto-paren.
869 # We only apply it to argument-less calls if the autocall
870 # parameter is set to 2. We only need to check that autocall is <
871 # 2, since this function isn't called unless it's at least 1.
872 if not the_rest and (self.shell.autocall < 2) and not force_auto:
873 newcmd = '%s %s' % (ifun,the_rest)
874 auto_rewrite = False
875 else:
876 if not force_auto and the_rest.startswith('['):
877 if hasattr(obj,'__getitem__'):
878 # Don't autocall in this case: item access for an object
879 # which is BOTH callable and implements __getitem__.
880 newcmd = '%s %s' % (ifun,the_rest)
881 auto_rewrite = False
882 else:
883 # if the object doesn't support [] access, go ahead and
884 # autocall
885 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
886 elif the_rest.endswith(';'):
887 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
888 else:
889 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
890
891 if auto_rewrite:
892 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
893
894 try:
895 # plain ascii works better w/ pyreadline, on some machines, so
896 # we use it and only print uncolored rewrite if we have unicode
897 rw = str(rw)
898 print >>Term.cout, rw
899 except UnicodeEncodeError:
900 print "-------------->" + newcmd
901
902 # log what is now valid Python, not the actual user input (without the
903 # final newline)
904 self.shell.log(line,newcmd,continue_prompt)
905 return newcmd
906
907
908 class HelpHandler(PrefilterHandler):
909
910 handler_name = Str('help')
911 esc_strings = List([ESC_HELP])
912
913 def handle(self, line_info):
914 """Try to get some help for the object.
915
916 obj? or ?obj -> basic information.
917 obj?? or ??obj -> more details.
918 """
919 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
920 line = line_info.line
921 # We need to make sure that we don't process lines which would be
922 # otherwise valid python, such as "x=1 # what?"
923 try:
924 codeop.compile_command(line)
925 except SyntaxError:
926 # We should only handle as help stuff which is NOT valid syntax
927 if line[0]==ESC_HELP:
928 line = line[1:]
929 elif line[-1]==ESC_HELP:
930 line = line[:-1]
931 self.shell.log(line, '#?'+line, line_info.continue_prompt)
932 if line:
933 #print 'line:<%r>' % line # dbg
934 self.shell.magic_pinfo(line)
935 else:
936 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
937 return '' # Empty string is needed here!
938 except:
939 raise
940 # Pass any other exceptions through to the normal handler
941 return normal_handler.handle(line_info)
942 else:
943 raise
944 # If the code compiles ok, we should handle it normally
945 return normal_handler.handle(line_info)
946
947
948 class EmacsHandler(PrefilterHandler):
949
950 handler_name = Str('emacs')
951 esc_strings = List([])
952
953 def handle(self, line_info):
954 """Handle input lines marked by python-mode."""
955
956 # Currently, nothing is done. Later more functionality can be added
957 # here if needed.
958
959 # The input cache shouldn't be updated
960 return line_info.line
961
962
963 #-----------------------------------------------------------------------------
964 # Defaults
965 #-----------------------------------------------------------------------------
966
967
968 _default_transformers = [
969 AssignSystemTransformer,
970 AssignMagicTransformer
971 ]
972
973 _default_checkers = [
974 EmacsChecker,
975 ShellEscapeChecker,
976 IPyAutocallChecker,
977 MultiLineMagicChecker,
978 EscCharsChecker,
979 AssignmentChecker,
980 AutoMagicChecker,
981 AliasChecker,
982 PythonOpsChecker,
983 AutocallChecker
984 ]
985
986 _default_handlers = [
987 PrefilterHandler,
988 AliasHandler,
989 ShellEscapeHandler,
990 MagicHandler,
991 AutoHandler,
992 HelpHandler,
993 EmacsHandler
994 ]
320
995
@@ -23,7 +23,7 b' import time'
23 from IPython.utils import coloransi
23 from IPython.utils import coloransi
24 from IPython.core import release
24 from IPython.core import release
25 from IPython.external.Itpl import ItplNS
25 from IPython.external.Itpl import ItplNS
26 from IPython.core.ipapi import TryNext
26 from IPython.core.error import TryNext
27 from IPython.utils.ipstruct import Struct
27 from IPython.utils.ipstruct import Struct
28 from IPython.core.macro import Macro
28 from IPython.core.macro import Macro
29 import IPython.utils.generics
29 import IPython.utils.generics
@@ -546,8 +546,11 b' class CachedOutput:'
546 # don't use print, puts an extra space
546 # don't use print, puts an extra space
547 cout_write(self.output_sep)
547 cout_write(self.output_sep)
548 outprompt = self.shell.hooks.generate_output_prompt()
548 outprompt = self.shell.hooks.generate_output_prompt()
549 # print "Got prompt: ", outprompt
549 if self.do_full_cache:
550 if self.do_full_cache:
550 cout_write(outprompt)
551 cout_write(outprompt)
552 else:
553 print "self.do_full_cache = False"
551
554
552 # and now call a possibly user-defined print mechanism
555 # and now call a possibly user-defined print mechanism
553 manipulated_val = self.display(arg)
556 manipulated_val = self.display(arg)
@@ -31,4 +31,5 b' class A(object):'
31 a = A()
31 a = A()
32
32
33 # Now, we force an exit, the caller will check that the del printout was given
33 # Now, we force an exit, the caller will check that the del printout was given
34 _ip.IP.ask_exit()
34 _ip = get_ipython()
35 _ip.ask_exit()
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/PhysicalQInput.py to IPython/deathrow/PhysicalQInput.py
NO CONTENT: file renamed from IPython/extensions/PhysicalQInput.py to IPython/deathrow/PhysicalQInput.py
1 NO CONTENT: file renamed from IPython/extensions/PhysicalQInteractive.py to IPython/deathrow/PhysicalQInteractive.py
NO CONTENT: file renamed from IPython/extensions/PhysicalQInteractive.py to IPython/deathrow/PhysicalQInteractive.py
1 NO CONTENT: file renamed from IPython/extensions/astyle.py to IPython/deathrow/astyle.py
NO CONTENT: file renamed from IPython/extensions/astyle.py to IPython/deathrow/astyle.py
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ibrowse.py to IPython/deathrow/ibrowse.py
NO CONTENT: file renamed from IPython/extensions/ibrowse.py to IPython/deathrow/ibrowse.py
1 NO CONTENT: file renamed from IPython/extensions/igrid.py to IPython/deathrow/igrid.py
NO CONTENT: file renamed from IPython/extensions/igrid.py to IPython/deathrow/igrid.py
1 NO CONTENT: file renamed from IPython/extensions/igrid_help.css to IPython/deathrow/igrid_help.css
NO CONTENT: file renamed from IPython/extensions/igrid_help.css to IPython/deathrow/igrid_help.css
1 NO CONTENT: file renamed from IPython/extensions/igrid_help.html to IPython/deathrow/igrid_help.html
NO CONTENT: file renamed from IPython/extensions/igrid_help.html to IPython/deathrow/igrid_help.html
1 NO CONTENT: file renamed from IPython/extensions/ipipe.py to IPython/deathrow/ipipe.py
NO CONTENT: file renamed from IPython/extensions/ipipe.py to IPython/deathrow/ipipe.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_constants.py to IPython/deathrow/ipy_constants.py
NO CONTENT: file renamed from IPython/extensions/ipy_constants.py to IPython/deathrow/ipy_constants.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_defaults.py to IPython/deathrow/ipy_defaults.py
NO CONTENT: file renamed from IPython/extensions/ipy_defaults.py to IPython/deathrow/ipy_defaults.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_kitcfg.py to IPython/deathrow/ipy_kitcfg.py
NO CONTENT: file renamed from IPython/extensions/ipy_kitcfg.py to IPython/deathrow/ipy_kitcfg.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_legacy.py to IPython/deathrow/ipy_legacy.py
NO CONTENT: file renamed from IPython/extensions/ipy_legacy.py to IPython/deathrow/ipy_legacy.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_p4.py to IPython/deathrow/ipy_p4.py
NO CONTENT: file renamed from IPython/extensions/ipy_p4.py to IPython/deathrow/ipy_p4.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_none.py to IPython/deathrow/ipy_profile_none.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_none.py to IPython/deathrow/ipy_profile_none.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_numpy.py to IPython/deathrow/ipy_profile_numpy.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_numpy.py to IPython/deathrow/ipy_profile_numpy.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_scipy.py to IPython/deathrow/ipy_profile_scipy.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_scipy.py to IPython/deathrow/ipy_profile_scipy.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_sh.py to IPython/deathrow/ipy_profile_sh.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_sh.py to IPython/deathrow/ipy_profile_sh.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_zope.py to IPython/deathrow/ipy_profile_zope.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_zope.py to IPython/deathrow/ipy_profile_zope.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_traits_completer.py to IPython/deathrow/ipy_traits_completer.py
NO CONTENT: file renamed from IPython/extensions/ipy_traits_completer.py to IPython/deathrow/ipy_traits_completer.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_vimserver.py to IPython/deathrow/ipy_vimserver.py
NO CONTENT: file renamed from IPython/extensions/ipy_vimserver.py to IPython/deathrow/ipy_vimserver.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/numeric_formats.py to IPython/deathrow/numeric_formats.py
NO CONTENT: file renamed from IPython/extensions/numeric_formats.py to IPython/deathrow/numeric_formats.py
1 NO CONTENT: file renamed from IPython/extensions/scitedirector.py to IPython/deathrow/scitedirector.py
NO CONTENT: file renamed from IPython/extensions/scitedirector.py to IPython/deathrow/scitedirector.py
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/InterpreterExec.py to IPython/quarantine/InterpreterExec.py
NO CONTENT: file renamed from IPython/extensions/InterpreterExec.py to IPython/quarantine/InterpreterExec.py
1 NO CONTENT: file renamed from IPython/extensions/InterpreterPasteInput.py to IPython/quarantine/InterpreterPasteInput.py
NO CONTENT: file renamed from IPython/extensions/InterpreterPasteInput.py to IPython/quarantine/InterpreterPasteInput.py
1 NO CONTENT: file renamed from IPython/extensions/clearcmd.py to IPython/quarantine/clearcmd.py
NO CONTENT: file renamed from IPython/extensions/clearcmd.py to IPython/quarantine/clearcmd.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/envpersist.py to IPython/quarantine/envpersist.py
NO CONTENT: file renamed from IPython/extensions/envpersist.py to IPython/quarantine/envpersist.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ext_rescapture.py to IPython/quarantine/ext_rescapture.py
NO CONTENT: file renamed from IPython/extensions/ext_rescapture.py to IPython/quarantine/ext_rescapture.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_app_completers.py to IPython/quarantine/ipy_app_completers.py
NO CONTENT: file renamed from IPython/extensions/ipy_app_completers.py to IPython/quarantine/ipy_app_completers.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_autoreload.py to IPython/quarantine/ipy_autoreload.py
NO CONTENT: file renamed from IPython/extensions/ipy_autoreload.py to IPython/quarantine/ipy_autoreload.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_bzr.py to IPython/quarantine/ipy_bzr.py
NO CONTENT: file renamed from IPython/extensions/ipy_bzr.py to IPython/quarantine/ipy_bzr.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_completers.py to IPython/quarantine/ipy_completers.py
NO CONTENT: file renamed from IPython/extensions/ipy_completers.py to IPython/quarantine/ipy_completers.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_editors.py to IPython/quarantine/ipy_editors.py
NO CONTENT: file renamed from IPython/extensions/ipy_editors.py to IPython/quarantine/ipy_editors.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_exportdb.py to IPython/quarantine/ipy_exportdb.py
NO CONTENT: file renamed from IPython/extensions/ipy_exportdb.py to IPython/quarantine/ipy_exportdb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_extutil.py to IPython/quarantine/ipy_extutil.py
NO CONTENT: file renamed from IPython/extensions/ipy_extutil.py to IPython/quarantine/ipy_extutil.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_fsops.py to IPython/quarantine/ipy_fsops.py
NO CONTENT: file renamed from IPython/extensions/ipy_fsops.py to IPython/quarantine/ipy_fsops.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_gnuglobal.py to IPython/quarantine/ipy_gnuglobal.py
NO CONTENT: file renamed from IPython/extensions/ipy_gnuglobal.py to IPython/quarantine/ipy_gnuglobal.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_greedycompleter.py to IPython/quarantine/ipy_greedycompleter.py
NO CONTENT: file renamed from IPython/extensions/ipy_greedycompleter.py to IPython/quarantine/ipy_greedycompleter.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_jot.py to IPython/quarantine/ipy_jot.py
NO CONTENT: file renamed from IPython/extensions/ipy_jot.py to IPython/quarantine/ipy_jot.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_lookfor.py to IPython/quarantine/ipy_lookfor.py
NO CONTENT: file renamed from IPython/extensions/ipy_lookfor.py to IPython/quarantine/ipy_lookfor.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_pretty.py to IPython/quarantine/ipy_pretty.py
NO CONTENT: file renamed from IPython/extensions/ipy_pretty.py to IPython/quarantine/ipy_pretty.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_profile_doctest.py to IPython/quarantine/ipy_profile_doctest.py
NO CONTENT: file renamed from IPython/extensions/ipy_profile_doctest.py to IPython/quarantine/ipy_profile_doctest.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_pydb.py to IPython/quarantine/ipy_pydb.py
NO CONTENT: file renamed from IPython/extensions/ipy_pydb.py to IPython/quarantine/ipy_pydb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_rehashdir.py to IPython/quarantine/ipy_rehashdir.py
NO CONTENT: file renamed from IPython/extensions/ipy_rehashdir.py to IPython/quarantine/ipy_rehashdir.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_render.py to IPython/quarantine/ipy_render.py
NO CONTENT: file renamed from IPython/extensions/ipy_render.py to IPython/quarantine/ipy_render.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_server.py to IPython/quarantine/ipy_server.py
NO CONTENT: file renamed from IPython/extensions/ipy_server.py to IPython/quarantine/ipy_server.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_signals.py to IPython/quarantine/ipy_signals.py
NO CONTENT: file renamed from IPython/extensions/ipy_signals.py to IPython/quarantine/ipy_signals.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_stock_completers.py to IPython/quarantine/ipy_stock_completers.py
NO CONTENT: file renamed from IPython/extensions/ipy_stock_completers.py to IPython/quarantine/ipy_stock_completers.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_synchronize_with.py to IPython/quarantine/ipy_synchronize_with.py
NO CONTENT: file renamed from IPython/extensions/ipy_synchronize_with.py to IPython/quarantine/ipy_synchronize_with.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_system_conf.py to IPython/quarantine/ipy_system_conf.py
NO CONTENT: file renamed from IPython/extensions/ipy_system_conf.py to IPython/quarantine/ipy_system_conf.py
1 NO CONTENT: file renamed from IPython/extensions/ipy_which.py to IPython/quarantine/ipy_which.py
NO CONTENT: file renamed from IPython/extensions/ipy_which.py to IPython/quarantine/ipy_which.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_winpdb.py to IPython/quarantine/ipy_winpdb.py
NO CONTENT: file renamed from IPython/extensions/ipy_winpdb.py to IPython/quarantine/ipy_winpdb.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ipy_workdir.py to IPython/quarantine/ipy_workdir.py
NO CONTENT: file renamed from IPython/extensions/ipy_workdir.py to IPython/quarantine/ipy_workdir.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/jobctrl.py to IPython/quarantine/jobctrl.py
NO CONTENT: file renamed from IPython/extensions/jobctrl.py to IPython/quarantine/jobctrl.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/ledit.py to IPython/quarantine/ledit.py
NO CONTENT: file renamed from IPython/extensions/ledit.py to IPython/quarantine/ledit.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/pspersistence.py to IPython/quarantine/pspersistence.py
NO CONTENT: file renamed from IPython/extensions/pspersistence.py to IPython/quarantine/pspersistence.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/win32clip.py to IPython/quarantine/win32clip.py
NO CONTENT: file renamed from IPython/extensions/win32clip.py to IPython/quarantine/win32clip.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/extensions/pickleshare.py to IPython/utils/pickleshare.py
NO CONTENT: file renamed from IPython/extensions/pickleshare.py to IPython/utils/pickleshare.py
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/history.txt to docs/source/about/history.txt
NO CONTENT: file renamed from docs/source/history.txt to docs/source/about/history.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/license_and_copyright.txt to docs/source/about/license_and_copyright.txt
NO CONTENT: file renamed from docs/source/license_and_copyright.txt to docs/source/about/license_and_copyright.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from docs/source/config/initial_config.txt to docs/source/config/old.txt
NO CONTENT: file renamed from docs/source/config/initial_config.txt to docs/source/config/old.txt
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (631 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (790 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now