##// END OF EJS Templates
Merging Dav's traitlets rename branch.
Dav Clark -
r2537:535d8779 merge
parent child Browse files
Show More
@@ -1,67 +1,66 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 IPython.
4 IPython.
5
5
6 IPython is a set of tools for interactive and exploratory computing in Python.
6 IPython is a set of tools for interactive and exploratory computing in Python.
7 """
7 """
8
9 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
11 #
10 #
12 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
15
14
16 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
17 # Imports
16 # Imports
18 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
19 from __future__ import absolute_import
18 from __future__ import absolute_import
20
19
21 import os
20 import os
22 import sys
21 import sys
23
22
24 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
25 # Setup everything
24 # Setup everything
26 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
27
26
28 if sys.version[0:3] < '2.5':
27 if sys.version[0:3] < '2.5':
29 raise ImportError('Python Version 2.5 or above is required for IPython.')
28 raise ImportError('Python Version 2.5 or above is required for IPython.')
30
29
31
30
32 # Make it easy to import extensions - they are always directly on pythonpath.
31 # Make it easy to import extensions - they are always directly on pythonpath.
33 # Therefore, non-IPython modules can be added to extensions directory.
32 # Therefore, non-IPython modules can be added to extensions directory.
34 # This should probably be in ipapp.py.
33 # This should probably be in ipapp.py.
35 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
34 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
36
35
37 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
38 # Setup the top level names
37 # Setup the top level names
39 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
40
39
41 from .config.loader import Config
40 from .config.loader import Config
42 from .core import release
41 from .core import release
43 from .core.application import Application
42 from .core.application import Application
44 from .core.ipapp import IPythonApp
43 from .core.ipapp import IPythonApp
45 from .core.embed import embed
44 from .core.embed import embed
46 from .core.error import TryNext
45 from .core.error import TryNext
47 from .core.iplib import InteractiveShell
46 from .core.iplib import InteractiveShell
48 from .testing import test
47 from .testing import test
49
48
50 from .lib import (
49 from .lib import (
51 enable_wx, disable_wx,
50 enable_wx, disable_wx,
52 enable_gtk, disable_gtk,
51 enable_gtk, disable_gtk,
53 enable_qt4, disable_qt4,
52 enable_qt4, disable_qt4,
54 enable_tk, disable_tk,
53 enable_tk, disable_tk,
55 set_inputhook, clear_inputhook,
54 set_inputhook, clear_inputhook,
56 current_gui, spin,
55 current_gui, spin,
57 appstart_qt4, appstart_wx,
56 appstart_qt4, appstart_wx,
58 appstart_gtk, appstart_tk
57 appstart_gtk, appstart_tk
59 )
58 )
60
59
61 # Release data
60 # Release data
62 __author__ = ''
61 __author__ = ''
63 for author, email in release.authors.values():
62 for author, email in release.authors.values():
64 __author__ += author + ' <' + email + '>\n'
63 __author__ += author + ' <' + email + '>\n'
65 __license__ = release.license
64 __license__ = release.license
66 __version__ = release.version
65 __version__ = release.version
67 __revision__ = release.revision
66 __revision__ = release.revision
@@ -1,453 +1,453 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for IPython.
3 An application for IPython.
4
4
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating componenets.
6 handling configuration and creating componenets.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the components, passing the config to them.
9 object and then create the components, passing the config to them.
10
10
11 Authors:
11 Authors:
12
12
13 * Brian Granger
13 * Brian Granger
14 * Fernando Perez
14 * Fernando Perez
15
15
16 Notes
16 Notes
17 -----
17 -----
18 """
18 """
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Copyright (C) 2008-2009 The IPython Development Team
21 # Copyright (C) 2008-2009 The IPython Development Team
22 #
22 #
23 # Distributed under the terms of the BSD License. The full license is in
23 # Distributed under the terms of the BSD License. The full license is in
24 # the file COPYING, distributed as part of this software.
24 # the file COPYING, distributed as part of this software.
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Imports
28 # Imports
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 import logging
31 import logging
32 import os
32 import os
33 import sys
33 import sys
34
34
35 from IPython.core import release, crashhandler
35 from IPython.core import release, crashhandler
36 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
36 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
37 from IPython.config.loader import (
37 from IPython.config.loader import (
38 PyFileConfigLoader,
38 PyFileConfigLoader,
39 ArgParseConfigLoader,
39 ArgParseConfigLoader,
40 Config,
40 Config,
41 )
41 )
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Classes and functions
44 # Classes and functions
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 class ApplicationError(Exception):
47 class ApplicationError(Exception):
48 pass
48 pass
49
49
50
50
51 class BaseAppConfigLoader(ArgParseConfigLoader):
51 class BaseAppConfigLoader(ArgParseConfigLoader):
52 """Default command line options for IPython based applications."""
52 """Default command line options for IPython based applications."""
53
53
54 def _add_ipython_dir(self, parser):
54 def _add_ipython_dir(self, parser):
55 """Add the --ipython-dir option to the parser."""
55 """Add the --ipython-dir option to the parser."""
56 paa = parser.add_argument
56 paa = parser.add_argument
57 paa('--ipython-dir',
57 paa('--ipython-dir',
58 dest='Global.ipython_dir',type=unicode,
58 dest='Global.ipython_dir',type=unicode,
59 help=
59 help=
60 """Set to override default location of the IPython directory
60 """Set to override default location of the IPython directory
61 IPYTHON_DIR, stored as Global.ipython_dir. This can also be
61 IPYTHON_DIR, stored as Global.ipython_dir. This can also be
62 specified through the environment variable IPYTHON_DIR.""",
62 specified through the environment variable IPYTHON_DIR.""",
63 metavar='Global.ipython_dir')
63 metavar='Global.ipython_dir')
64
64
65 def _add_log_level(self, parser):
65 def _add_log_level(self, parser):
66 """Add the --log-level option to the parser."""
66 """Add the --log-level option to the parser."""
67 paa = parser.add_argument
67 paa = parser.add_argument
68 paa('--log-level',
68 paa('--log-level',
69 dest="Global.log_level",type=int,
69 dest="Global.log_level",type=int,
70 help='Set the log level (0,10,20,30,40,50). Default is 30.',
70 help='Set the log level (0,10,20,30,40,50). Default is 30.',
71 metavar='Global.log_level')
71 metavar='Global.log_level')
72
72
73 def _add_arguments(self):
73 def _add_arguments(self):
74 self._add_ipython_dir(self.parser)
74 self._add_ipython_dir(self.parser)
75 self._add_log_level(self.parser)
75 self._add_log_level(self.parser)
76
76
77
77
78 class Application(object):
78 class Application(object):
79 """Load a config, construct components and set them running.
79 """Load a config, construct components and set them running.
80
80
81 The configuration of an application can be done via three different Config
81 The configuration of an application can be done via three different Config
82 objects, which are loaded and ultimately merged into a single one used
82 objects, which are loaded and ultimately merged into a single one used
83 from that point on by the app. These are:
83 from that point on by the app. These are:
84
84
85 1. default_config: internal defaults, implemented in code.
85 1. default_config: internal defaults, implemented in code.
86 2. file_config: read from the filesystem.
86 2. file_config: read from the filesystem.
87 3. command_line_config: read from the system's command line flags.
87 3. command_line_config: read from the system's command line flags.
88
88
89 During initialization, 3 is actually read before 2, since at the
89 During initialization, 3 is actually read before 2, since at the
90 command-line one may override the location of the file to be read. But the
90 command-line one may override the location of the file to be read. But the
91 above is the order in which the merge is made.
91 above is the order in which the merge is made.
92 """
92 """
93
93
94 name = u'ipython'
94 name = u'ipython'
95 description = 'IPython: an enhanced interactive Python shell.'
95 description = 'IPython: an enhanced interactive Python shell.'
96 #: Usage message printed by argparse. If None, auto-generate
96 #: Usage message printed by argparse. If None, auto-generate
97 usage = None
97 usage = None
98 #: The command line config loader. Subclass of ArgParseConfigLoader.
98 #: The command line config loader. Subclass of ArgParseConfigLoader.
99 command_line_loader = BaseAppConfigLoader
99 command_line_loader = BaseAppConfigLoader
100 #: The name of the config file to load, determined at runtime
100 #: The name of the config file to load, determined at runtime
101 config_file_name = None
101 config_file_name = None
102 #: The name of the default config file. Track separately from the actual
102 #: The name of the default config file. Track separately from the actual
103 #: name because some logic happens only if we aren't using the default.
103 #: name because some logic happens only if we aren't using the default.
104 default_config_file_name = u'ipython_config.py'
104 default_config_file_name = u'ipython_config.py'
105 default_log_level = logging.WARN
105 default_log_level = logging.WARN
106 #: Set by --profile option
106 #: Set by --profile option
107 profile_name = None
107 profile_name = None
108 #: User's ipython directory, typically ~/.ipython/
108 #: User's ipython directory, typically ~/.ipython/
109 ipython_dir = None
109 ipython_dir = None
110 #: Internal defaults, implemented in code.
110 #: Internal defaults, implemented in code.
111 default_config = None
111 default_config = None
112 #: Read from the filesystem.
112 #: Read from the filesystem.
113 file_config = None
113 file_config = None
114 #: Read from the system's command line flags.
114 #: Read from the system's command line flags.
115 command_line_config = None
115 command_line_config = None
116 #: The final config that will be passed to the component.
116 #: The final config that will be passed to the component.
117 master_config = None
117 master_config = None
118 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
118 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
119 argv = None
119 argv = None
120 #: extra arguments computed by the command-line loader
120 #: extra arguments computed by the command-line loader
121 extra_args = None
121 extra_args = None
122 #: The class to use as the crash handler.
122 #: The class to use as the crash handler.
123 crash_handler_class = crashhandler.CrashHandler
123 crash_handler_class = crashhandler.CrashHandler
124
124
125 # Private attributes
125 # Private attributes
126 _exiting = False
126 _exiting = False
127 _initialized = False
127 _initialized = False
128
128
129 def __init__(self, argv=None):
129 def __init__(self, argv=None):
130 self.argv = sys.argv[1:] if argv is None else argv
130 self.argv = sys.argv[1:] if argv is None else argv
131 self.init_logger()
131 self.init_logger()
132
132
133 def init_logger(self):
133 def init_logger(self):
134 self.log = logging.getLogger(self.__class__.__name__)
134 self.log = logging.getLogger(self.__class__.__name__)
135 # This is used as the default until the command line arguments are read.
135 # This is used as the default until the command line arguments are read.
136 self.log.setLevel(self.default_log_level)
136 self.log.setLevel(self.default_log_level)
137 self._log_handler = logging.StreamHandler()
137 self._log_handler = logging.StreamHandler()
138 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
138 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
139 self._log_handler.setFormatter(self._log_formatter)
139 self._log_handler.setFormatter(self._log_formatter)
140 self.log.addHandler(self._log_handler)
140 self.log.addHandler(self._log_handler)
141
141
142 def _set_log_level(self, level):
142 def _set_log_level(self, level):
143 self.log.setLevel(level)
143 self.log.setLevel(level)
144
144
145 def _get_log_level(self):
145 def _get_log_level(self):
146 return self.log.level
146 return self.log.level
147
147
148 log_level = property(_get_log_level, _set_log_level)
148 log_level = property(_get_log_level, _set_log_level)
149
149
150 def initialize(self):
150 def initialize(self):
151 """Initialize the application.
151 """Initialize the application.
152
152
153 Loads all configuration information and sets all application state, but
153 Loads all configuration information and sets all application state, but
154 does not start any relevant processing (typically some kind of event
154 does not start any relevant processing (typically some kind of event
155 loop).
155 loop).
156
156
157 Once this method has been called, the application is flagged as
157 Once this method has been called, the application is flagged as
158 initialized and the method becomes a no-op."""
158 initialized and the method becomes a no-op."""
159
159
160 if self._initialized:
160 if self._initialized:
161 return
161 return
162
162
163 # The first part is protected with an 'attempt' wrapper, that will log
163 # The first part is protected with an 'attempt' wrapper, that will log
164 # failures with the basic system traceback machinery. Once our crash
164 # failures with the basic system traceback machinery. Once our crash
165 # handler is in place, we can let any subsequent exception propagate,
165 # handler is in place, we can let any subsequent exception propagate,
166 # as our handler will log it with much better detail than the default.
166 # as our handler will log it with much better detail than the default.
167 self.attempt(self.create_crash_handler)
167 self.attempt(self.create_crash_handler)
168
168
169 # Configuration phase
169 # Configuration phase
170 # Default config (internally hardwired in application code)
170 # Default config (internally hardwired in application code)
171 self.create_default_config()
171 self.create_default_config()
172 self.log_default_config()
172 self.log_default_config()
173 self.set_default_config_log_level()
173 self.set_default_config_log_level()
174
174
175 # Command-line config
175 # Command-line config
176 self.pre_load_command_line_config()
176 self.pre_load_command_line_config()
177 self.load_command_line_config()
177 self.load_command_line_config()
178 self.set_command_line_config_log_level()
178 self.set_command_line_config_log_level()
179 self.post_load_command_line_config()
179 self.post_load_command_line_config()
180 self.log_command_line_config()
180 self.log_command_line_config()
181
181
182 # Find resources needed for filesystem access, using information from
182 # Find resources needed for filesystem access, using information from
183 # the above two
183 # the above two
184 self.find_ipython_dir()
184 self.find_ipython_dir()
185 self.find_resources()
185 self.find_resources()
186 self.find_config_file_name()
186 self.find_config_file_name()
187 self.find_config_file_paths()
187 self.find_config_file_paths()
188
188
189 # File-based config
189 # File-based config
190 self.pre_load_file_config()
190 self.pre_load_file_config()
191 self.load_file_config()
191 self.load_file_config()
192 self.set_file_config_log_level()
192 self.set_file_config_log_level()
193 self.post_load_file_config()
193 self.post_load_file_config()
194 self.log_file_config()
194 self.log_file_config()
195
195
196 # Merge all config objects into a single one the app can then use
196 # Merge all config objects into a single one the app can then use
197 self.merge_configs()
197 self.merge_configs()
198 self.log_master_config()
198 self.log_master_config()
199
199
200 # Construction phase
200 # Construction phase
201 self.pre_construct()
201 self.pre_construct()
202 self.construct()
202 self.construct()
203 self.post_construct()
203 self.post_construct()
204
204
205 # Done, flag as such and
205 # Done, flag as such and
206 self._initialized = True
206 self._initialized = True
207
207
208 def start(self):
208 def start(self):
209 """Start the application."""
209 """Start the application."""
210 self.initialize()
210 self.initialize()
211 self.start_app()
211 self.start_app()
212
212
213 #-------------------------------------------------------------------------
213 #-------------------------------------------------------------------------
214 # Various stages of Application creation
214 # Various stages of Application creation
215 #-------------------------------------------------------------------------
215 #-------------------------------------------------------------------------
216
216
217 def create_crash_handler(self):
217 def create_crash_handler(self):
218 """Create a crash handler, typically setting sys.excepthook to it."""
218 """Create a crash handler, typically setting sys.excepthook to it."""
219 self.crash_handler = self.crash_handler_class(self)
219 self.crash_handler = self.crash_handler_class(self)
220 sys.excepthook = self.crash_handler
220 sys.excepthook = self.crash_handler
221
221
222 def create_default_config(self):
222 def create_default_config(self):
223 """Create defaults that can't be set elsewhere.
223 """Create defaults that can't be set elsewhere.
224
224
225 For the most part, we try to set default in the class attributes
225 For the most part, we try to set default in the class attributes
226 of Components. But, defaults the top-level Application (which is
226 of Components. But, defaults the top-level Application (which is
227 not a HasTraitlets or Component) are not set in this way. Instead
227 not a HasTraits or Component) are not set in this way. Instead
228 we set them here. The Global section is for variables like this that
228 we set them here. The Global section is for variables like this that
229 don't belong to a particular component.
229 don't belong to a particular component.
230 """
230 """
231 c = Config()
231 c = Config()
232 c.Global.ipython_dir = get_ipython_dir()
232 c.Global.ipython_dir = get_ipython_dir()
233 c.Global.log_level = self.log_level
233 c.Global.log_level = self.log_level
234 self.default_config = c
234 self.default_config = c
235
235
236 def log_default_config(self):
236 def log_default_config(self):
237 self.log.debug('Default config loaded:')
237 self.log.debug('Default config loaded:')
238 self.log.debug(repr(self.default_config))
238 self.log.debug(repr(self.default_config))
239
239
240 def set_default_config_log_level(self):
240 def set_default_config_log_level(self):
241 try:
241 try:
242 self.log_level = self.default_config.Global.log_level
242 self.log_level = self.default_config.Global.log_level
243 except AttributeError:
243 except AttributeError:
244 # Fallback to the default_log_level class attribute
244 # Fallback to the default_log_level class attribute
245 pass
245 pass
246
246
247 def create_command_line_config(self):
247 def create_command_line_config(self):
248 """Create and return a command line config loader."""
248 """Create and return a command line config loader."""
249 return self.command_line_loader(
249 return self.command_line_loader(
250 self.argv,
250 self.argv,
251 description=self.description,
251 description=self.description,
252 version=release.version,
252 version=release.version,
253 usage=self.usage
253 usage=self.usage
254 )
254 )
255
255
256 def pre_load_command_line_config(self):
256 def pre_load_command_line_config(self):
257 """Do actions just before loading the command line config."""
257 """Do actions just before loading the command line config."""
258 pass
258 pass
259
259
260 def load_command_line_config(self):
260 def load_command_line_config(self):
261 """Load the command line config."""
261 """Load the command line config."""
262 loader = self.create_command_line_config()
262 loader = self.create_command_line_config()
263 self.command_line_config = loader.load_config()
263 self.command_line_config = loader.load_config()
264 self.extra_args = loader.get_extra_args()
264 self.extra_args = loader.get_extra_args()
265
265
266 def set_command_line_config_log_level(self):
266 def set_command_line_config_log_level(self):
267 try:
267 try:
268 self.log_level = self.command_line_config.Global.log_level
268 self.log_level = self.command_line_config.Global.log_level
269 except AttributeError:
269 except AttributeError:
270 pass
270 pass
271
271
272 def post_load_command_line_config(self):
272 def post_load_command_line_config(self):
273 """Do actions just after loading the command line config."""
273 """Do actions just after loading the command line config."""
274 pass
274 pass
275
275
276 def log_command_line_config(self):
276 def log_command_line_config(self):
277 self.log.debug("Command line config loaded:")
277 self.log.debug("Command line config loaded:")
278 self.log.debug(repr(self.command_line_config))
278 self.log.debug(repr(self.command_line_config))
279
279
280 def find_ipython_dir(self):
280 def find_ipython_dir(self):
281 """Set the IPython directory.
281 """Set the IPython directory.
282
282
283 This sets ``self.ipython_dir``, but the actual value that is passed to
283 This sets ``self.ipython_dir``, but the actual value that is passed to
284 the application is kept in either ``self.default_config`` or
284 the application is kept in either ``self.default_config`` or
285 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
285 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
286 ``sys.path`` so config files there can be referenced by other config
286 ``sys.path`` so config files there can be referenced by other config
287 files.
287 files.
288 """
288 """
289
289
290 try:
290 try:
291 self.ipython_dir = self.command_line_config.Global.ipython_dir
291 self.ipython_dir = self.command_line_config.Global.ipython_dir
292 except AttributeError:
292 except AttributeError:
293 self.ipython_dir = self.default_config.Global.ipython_dir
293 self.ipython_dir = self.default_config.Global.ipython_dir
294 sys.path.append(os.path.abspath(self.ipython_dir))
294 sys.path.append(os.path.abspath(self.ipython_dir))
295 if not os.path.isdir(self.ipython_dir):
295 if not os.path.isdir(self.ipython_dir):
296 os.makedirs(self.ipython_dir, mode=0777)
296 os.makedirs(self.ipython_dir, mode=0777)
297 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
297 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
298
298
299 def find_resources(self):
299 def find_resources(self):
300 """Find other resources that need to be in place.
300 """Find other resources that need to be in place.
301
301
302 Things like cluster directories need to be in place to find the
302 Things like cluster directories need to be in place to find the
303 config file. These happen right after the IPython directory has
303 config file. These happen right after the IPython directory has
304 been set.
304 been set.
305 """
305 """
306 pass
306 pass
307
307
308 def find_config_file_name(self):
308 def find_config_file_name(self):
309 """Find the config file name for this application.
309 """Find the config file name for this application.
310
310
311 This must set ``self.config_file_name`` to the filename of the
311 This must set ``self.config_file_name`` to the filename of the
312 config file to use (just the filename). The search paths for the
312 config file to use (just the filename). The search paths for the
313 config file are set in :meth:`find_config_file_paths` and then passed
313 config file are set in :meth:`find_config_file_paths` and then passed
314 to the config file loader where they are resolved to an absolute path.
314 to the config file loader where they are resolved to an absolute path.
315
315
316 If a profile has been set at the command line, this will resolve it.
316 If a profile has been set at the command line, this will resolve it.
317 """
317 """
318 try:
318 try:
319 self.config_file_name = self.command_line_config.Global.config_file
319 self.config_file_name = self.command_line_config.Global.config_file
320 except AttributeError:
320 except AttributeError:
321 pass
321 pass
322 else:
322 else:
323 return
323 return
324
324
325 try:
325 try:
326 self.profile_name = self.command_line_config.Global.profile
326 self.profile_name = self.command_line_config.Global.profile
327 except AttributeError:
327 except AttributeError:
328 # Just use the default as there is no profile
328 # Just use the default as there is no profile
329 self.config_file_name = self.default_config_file_name
329 self.config_file_name = self.default_config_file_name
330 else:
330 else:
331 # Use the default config file name and profile name if set
331 # Use the default config file name and profile name if set
332 # to determine the used config file name.
332 # to determine the used config file name.
333 name_parts = self.default_config_file_name.split('.')
333 name_parts = self.default_config_file_name.split('.')
334 name_parts.insert(1, u'_' + self.profile_name + u'.')
334 name_parts.insert(1, u'_' + self.profile_name + u'.')
335 self.config_file_name = ''.join(name_parts)
335 self.config_file_name = ''.join(name_parts)
336
336
337 def find_config_file_paths(self):
337 def find_config_file_paths(self):
338 """Set the search paths for resolving the config file.
338 """Set the search paths for resolving the config file.
339
339
340 This must set ``self.config_file_paths`` to a sequence of search
340 This must set ``self.config_file_paths`` to a sequence of search
341 paths to pass to the config file loader.
341 paths to pass to the config file loader.
342 """
342 """
343 # Include our own profiles directory last, so that users can still find
343 # Include our own profiles directory last, so that users can still find
344 # our shipped copies of builtin profiles even if they don't have them
344 # our shipped copies of builtin profiles even if they don't have them
345 # in their local ipython directory.
345 # in their local ipython directory.
346 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
346 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
347 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
347 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
348
348
349 def pre_load_file_config(self):
349 def pre_load_file_config(self):
350 """Do actions before the config file is loaded."""
350 """Do actions before the config file is loaded."""
351 pass
351 pass
352
352
353 def load_file_config(self):
353 def load_file_config(self):
354 """Load the config file.
354 """Load the config file.
355
355
356 This tries to load the config file from disk. If successful, the
356 This tries to load the config file from disk. If successful, the
357 ``CONFIG_FILE`` config variable is set to the resolved config file
357 ``CONFIG_FILE`` config variable is set to the resolved config file
358 location. If not successful, an empty config is used.
358 location. If not successful, an empty config is used.
359 """
359 """
360 self.log.debug("Attempting to load config file: %s" %
360 self.log.debug("Attempting to load config file: %s" %
361 self.config_file_name)
361 self.config_file_name)
362 loader = PyFileConfigLoader(self.config_file_name,
362 loader = PyFileConfigLoader(self.config_file_name,
363 path=self.config_file_paths)
363 path=self.config_file_paths)
364 try:
364 try:
365 self.file_config = loader.load_config()
365 self.file_config = loader.load_config()
366 self.file_config.Global.config_file = loader.full_filename
366 self.file_config.Global.config_file = loader.full_filename
367 except IOError:
367 except IOError:
368 # Only warn if the default config file was NOT being used.
368 # Only warn if the default config file was NOT being used.
369 if not self.config_file_name==self.default_config_file_name:
369 if not self.config_file_name==self.default_config_file_name:
370 self.log.warn("Config file not found, skipping: %s" %
370 self.log.warn("Config file not found, skipping: %s" %
371 self.config_file_name, exc_info=True)
371 self.config_file_name, exc_info=True)
372 self.file_config = Config()
372 self.file_config = Config()
373 except:
373 except:
374 self.log.warn("Error loading config file: %s" %
374 self.log.warn("Error loading config file: %s" %
375 self.config_file_name, exc_info=True)
375 self.config_file_name, exc_info=True)
376 self.file_config = Config()
376 self.file_config = Config()
377
377
378 def set_file_config_log_level(self):
378 def set_file_config_log_level(self):
379 # We need to keeep self.log_level updated. But we only use the value
379 # We need to keeep self.log_level updated. But we only use the value
380 # of the file_config if a value was not specified at the command
380 # of the file_config if a value was not specified at the command
381 # line, because the command line overrides everything.
381 # line, because the command line overrides everything.
382 if not hasattr(self.command_line_config.Global, 'log_level'):
382 if not hasattr(self.command_line_config.Global, 'log_level'):
383 try:
383 try:
384 self.log_level = self.file_config.Global.log_level
384 self.log_level = self.file_config.Global.log_level
385 except AttributeError:
385 except AttributeError:
386 pass # Use existing value
386 pass # Use existing value
387
387
388 def post_load_file_config(self):
388 def post_load_file_config(self):
389 """Do actions after the config file is loaded."""
389 """Do actions after the config file is loaded."""
390 pass
390 pass
391
391
392 def log_file_config(self):
392 def log_file_config(self):
393 if hasattr(self.file_config.Global, 'config_file'):
393 if hasattr(self.file_config.Global, 'config_file'):
394 self.log.debug("Config file loaded: %s" %
394 self.log.debug("Config file loaded: %s" %
395 self.file_config.Global.config_file)
395 self.file_config.Global.config_file)
396 self.log.debug(repr(self.file_config))
396 self.log.debug(repr(self.file_config))
397
397
398 def merge_configs(self):
398 def merge_configs(self):
399 """Merge the default, command line and file config objects."""
399 """Merge the default, command line and file config objects."""
400 config = Config()
400 config = Config()
401 config._merge(self.default_config)
401 config._merge(self.default_config)
402 config._merge(self.file_config)
402 config._merge(self.file_config)
403 config._merge(self.command_line_config)
403 config._merge(self.command_line_config)
404
404
405 # XXX fperez - propose to Brian we rename master_config to simply
405 # XXX fperez - propose to Brian we rename master_config to simply
406 # config, I think this is going to be heavily used in examples and
406 # config, I think this is going to be heavily used in examples and
407 # application code and the name is shorter/easier to find/remember.
407 # application code and the name is shorter/easier to find/remember.
408 # For now, just alias it...
408 # For now, just alias it...
409 self.master_config = config
409 self.master_config = config
410 self.config = config
410 self.config = config
411
411
412 def log_master_config(self):
412 def log_master_config(self):
413 self.log.debug("Master config created:")
413 self.log.debug("Master config created:")
414 self.log.debug(repr(self.master_config))
414 self.log.debug(repr(self.master_config))
415
415
416 def pre_construct(self):
416 def pre_construct(self):
417 """Do actions after the config has been built, but before construct."""
417 """Do actions after the config has been built, but before construct."""
418 pass
418 pass
419
419
420 def construct(self):
420 def construct(self):
421 """Construct the main components that make up this app."""
421 """Construct the main components that make up this app."""
422 self.log.debug("Constructing components for application")
422 self.log.debug("Constructing components for application")
423
423
424 def post_construct(self):
424 def post_construct(self):
425 """Do actions after construct, but before starting the app."""
425 """Do actions after construct, but before starting the app."""
426 pass
426 pass
427
427
428 def start_app(self):
428 def start_app(self):
429 """Actually start the app."""
429 """Actually start the app."""
430 self.log.debug("Starting application")
430 self.log.debug("Starting application")
431
431
432 #-------------------------------------------------------------------------
432 #-------------------------------------------------------------------------
433 # Utility methods
433 # Utility methods
434 #-------------------------------------------------------------------------
434 #-------------------------------------------------------------------------
435
435
436 def exit(self, exit_status=0):
436 def exit(self, exit_status=0):
437 if self._exiting:
437 if self._exiting:
438 pass
438 pass
439 else:
439 else:
440 self.log.debug("Exiting application: %s" % self.name)
440 self.log.debug("Exiting application: %s" % self.name)
441 self._exiting = True
441 self._exiting = True
442 sys.exit(exit_status)
442 sys.exit(exit_status)
443
443
444 def attempt(self, func):
444 def attempt(self, func):
445 try:
445 try:
446 func()
446 func()
447 except SystemExit:
447 except SystemExit:
448 raise
448 raise
449 except:
449 except:
450 self.log.critical("Aborting application: %s" % self.name,
450 self.log.critical("Aborting application: %s" % self.name,
451 exc_info=True)
451 exc_info=True)
452 self.exit(0)
452 self.exit(0)
453
453
@@ -1,346 +1,346 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight component system for IPython.
4 A lightweight component system for IPython.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from copy import deepcopy
23 from copy import deepcopy
24 import datetime
24 import datetime
25 from weakref import WeakValueDictionary
25 from weakref import WeakValueDictionary
26
26
27 from IPython.utils.importstring import import_item
27 from IPython.utils.importstring import import_item
28 from IPython.config.loader import Config
28 from IPython.config.loader import Config
29 from IPython.utils.traitlets import (
29 from IPython.utils.traitlets import (
30 HasTraitlets, MetaHasTraitlets, Instance, This
30 HasTraits, MetaHasTraits, Instance, This
31 )
31 )
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Helper classes for Components
35 # Helper classes for Components
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 class ComponentError(Exception):
39 class ComponentError(Exception):
40 pass
40 pass
41
41
42 class MetaComponentTracker(type):
42 class MetaComponentTracker(type):
43 """A metaclass that tracks instances of Components and its subclasses."""
43 """A metaclass that tracks instances of Components and its subclasses."""
44
44
45 def __init__(cls, name, bases, d):
45 def __init__(cls, name, bases, d):
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
47 cls.__instance_refs = WeakValueDictionary()
47 cls.__instance_refs = WeakValueDictionary()
48 cls.__numcreated = 0
48 cls.__numcreated = 0
49
49
50 def __call__(cls, *args, **kw):
50 def __call__(cls, *args, **kw):
51 """Called when a class is called (instantiated)!!!
51 """Called when a class is called (instantiated)!!!
52
52
53 When a Component or subclass is instantiated, this is called and
53 When a Component or subclass is instantiated, this is called and
54 the instance is saved in a WeakValueDictionary for tracking.
54 the instance is saved in a WeakValueDictionary for tracking.
55 """
55 """
56 instance = cls.__new__(cls, *args, **kw)
56 instance = cls.__new__(cls, *args, **kw)
57
57
58 # Register the instance before __init__ is called so get_instances
58 # Register the instance before __init__ is called so get_instances
59 # works inside __init__ methods!
59 # works inside __init__ methods!
60 indices = cls.register_instance(instance)
60 indices = cls.register_instance(instance)
61
61
62 # This is in a try/except because of the __init__ method fails, the
62 # This is in a try/except because of the __init__ method fails, the
63 # instance is discarded and shouldn't be tracked.
63 # instance is discarded and shouldn't be tracked.
64 try:
64 try:
65 if isinstance(instance, cls):
65 if isinstance(instance, cls):
66 cls.__init__(instance, *args, **kw)
66 cls.__init__(instance, *args, **kw)
67 except:
67 except:
68 # Unregister the instance because __init__ failed!
68 # Unregister the instance because __init__ failed!
69 cls.unregister_instances(indices)
69 cls.unregister_instances(indices)
70 raise
70 raise
71 else:
71 else:
72 return instance
72 return instance
73
73
74 def register_instance(cls, instance):
74 def register_instance(cls, instance):
75 """Register instance with cls and its subclasses."""
75 """Register instance with cls and its subclasses."""
76 # indices is a list of the keys used to register the instance
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.
77 # with. This list is needed if the instance needs to be unregistered.
78 indices = []
78 indices = []
79 for c in cls.__mro__:
79 for c in cls.__mro__:
80 if issubclass(cls, c) and issubclass(c, Component):
80 if issubclass(cls, c) and issubclass(c, Component):
81 c.__numcreated += 1
81 c.__numcreated += 1
82 indices.append(c.__numcreated)
82 indices.append(c.__numcreated)
83 c.__instance_refs[c.__numcreated] = instance
83 c.__instance_refs[c.__numcreated] = instance
84 else:
84 else:
85 break
85 break
86 return indices
86 return indices
87
87
88 def unregister_instances(cls, indices):
88 def unregister_instances(cls, indices):
89 """Unregister instance with cls and its subclasses."""
89 """Unregister instance with cls and its subclasses."""
90 for c, index in zip(cls.__mro__, indices):
90 for c, index in zip(cls.__mro__, indices):
91 try:
91 try:
92 del c.__instance_refs[index]
92 del c.__instance_refs[index]
93 except KeyError:
93 except KeyError:
94 pass
94 pass
95
95
96 def clear_instances(cls):
96 def clear_instances(cls):
97 """Clear all instances tracked by cls."""
97 """Clear all instances tracked by cls."""
98 cls.__instance_refs.clear()
98 cls.__instance_refs.clear()
99 cls.__numcreated = 0
99 cls.__numcreated = 0
100
100
101 def get_instances(cls, name=None, root=None, klass=None):
101 def get_instances(cls, name=None, root=None, klass=None):
102 """Get all instances of cls and its subclasses.
102 """Get all instances of cls and its subclasses.
103
103
104 Parameters
104 Parameters
105 ----------
105 ----------
106 name : str
106 name : str
107 Limit to components with this name.
107 Limit to components with this name.
108 root : Component or subclass
108 root : Component or subclass
109 Limit to components having this root.
109 Limit to components having this root.
110 klass : class or str
110 klass : class or str
111 Limits to instances of the class or its subclasses. If a 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
112 is given ut must be in the form 'foo.bar.MyClass'. The str
113 form of this argument is useful for forward declarations.
113 form of this argument is useful for forward declarations.
114 """
114 """
115 if klass is not None:
115 if klass is not None:
116 if isinstance(klass, basestring):
116 if isinstance(klass, basestring):
117 klass = import_item(klass)
117 klass = import_item(klass)
118 # Limit search to instances of klass for performance
118 # Limit search to instances of klass for performance
119 if issubclass(klass, Component):
119 if issubclass(klass, Component):
120 return klass.get_instances(name=name, root=root)
120 return klass.get_instances(name=name, root=root)
121 instances = cls.__instance_refs.values()
121 instances = cls.__instance_refs.values()
122 if name is not None:
122 if name is not None:
123 instances = [i for i in instances if i.name == name]
123 instances = [i for i in instances if i.name == name]
124 if klass is not None:
124 if klass is not None:
125 instances = [i for i in instances if isinstance(i, klass)]
125 instances = [i for i in instances if isinstance(i, klass)]
126 if root is not None:
126 if root is not None:
127 instances = [i for i in instances if i.root == root]
127 instances = [i for i in instances if i.root == root]
128 return instances
128 return instances
129
129
130 def get_instances_by_condition(cls, call, name=None, root=None,
130 def get_instances_by_condition(cls, call, name=None, root=None,
131 klass=None):
131 klass=None):
132 """Get all instances of cls, i such that call(i)==True.
132 """Get all instances of cls, i such that call(i)==True.
133
133
134 This also takes the ``name`` and ``root`` and ``classname``
134 This also takes the ``name`` and ``root`` and ``classname``
135 arguments of :meth:`get_instance`
135 arguments of :meth:`get_instance`
136 """
136 """
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
138
138
139
139
140 def masquerade_as(instance, cls):
140 def masquerade_as(instance, cls):
141 """Let instance masquerade as an instance of cls.
141 """Let instance masquerade as an instance of cls.
142
142
143 Sometimes, such as in testing code, it is useful to let a class
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
144 masquerade as another. Python, being duck typed, allows this by
145 default. But, instances of components are tracked by their class type.
145 default. But, instances of components are tracked by their class type.
146
146
147 After calling this, ``cls.get_instances()`` will return ``instance``. This
147 After calling this, ``cls.get_instances()`` will return ``instance``. This
148 does not, however, cause ``isinstance(instance, cls)`` to return ``True``.
148 does not, however, cause ``isinstance(instance, cls)`` to return ``True``.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 instance : an instance of a Component or Component subclass
152 instance : an instance of a Component or Component subclass
153 The instance that will pretend to be a cls.
153 The instance that will pretend to be a cls.
154 cls : subclass of Component
154 cls : subclass of Component
155 The Component subclass that instance will pretend to be.
155 The Component subclass that instance will pretend to be.
156 """
156 """
157 cls.register_instance(instance)
157 cls.register_instance(instance)
158
158
159
159
160 class __ComponentNameGenerator(object):
160 class __ComponentNameGenerator(object):
161 """A Singleton to generate unique component names."""
161 """A Singleton to generate unique component names."""
162
162
163 def __init__(self, prefix):
163 def __init__(self, prefix):
164 self.prefix = prefix
164 self.prefix = prefix
165 self.i = 0
165 self.i = 0
166
166
167 def __call__(self):
167 def __call__(self):
168 count = self.i
168 count = self.i
169 self.i += 1
169 self.i += 1
170 return "%s%s" % (self.prefix, count)
170 return "%s%s" % (self.prefix, count)
171
171
172
172
173 ComponentNameGenerator = __ComponentNameGenerator('ipython.component')
173 ComponentNameGenerator = __ComponentNameGenerator('ipython.component')
174
174
175
175
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
176 class MetaComponent(MetaHasTraits, MetaComponentTracker):
177 pass
177 pass
178
178
179
179
180 #-----------------------------------------------------------------------------
180 #-----------------------------------------------------------------------------
181 # Component implementation
181 # Component implementation
182 #-----------------------------------------------------------------------------
182 #-----------------------------------------------------------------------------
183
183
184
184
185 class Component(HasTraitlets):
185 class Component(HasTraits):
186
186
187 __metaclass__ = MetaComponent
187 __metaclass__ = MetaComponent
188
188
189 # Traitlets are fun!
189 # Traits are fun!
190 config = Instance(Config,(),{})
190 config = Instance(Config,(),{})
191 parent = This()
191 parent = This()
192 root = This()
192 root = This()
193 created = None
193 created = None
194
194
195 def __init__(self, parent, name=None, config=None):
195 def __init__(self, parent, name=None, config=None):
196 """Create a component given a parent and possibly and name and config.
196 """Create a component given a parent and possibly and name and config.
197
197
198 Parameters
198 Parameters
199 ----------
199 ----------
200 parent : Component subclass
200 parent : Component subclass
201 The parent in the component graph. The parent is used
201 The parent in the component graph. The parent is used
202 to get the root of the component graph.
202 to get the root of the component graph.
203 name : str
203 name : str
204 The unique name of the component. If empty, then a unique
204 The unique name of the component. If empty, then a unique
205 one will be autogenerated.
205 one will be autogenerated.
206 config : Config
206 config : Config
207 If this is empty, self.config = parent.config, otherwise
207 If this is empty, self.config = parent.config, otherwise
208 self.config = config and root.config is ignored. This argument
208 self.config = config and root.config is ignored. This argument
209 should only be used to *override* the automatic inheritance of
209 should only be used to *override* the automatic inheritance of
210 parent.config. If a caller wants to modify parent.config
210 parent.config. If a caller wants to modify parent.config
211 (not override), the caller should make a copy and change
211 (not override), the caller should make a copy and change
212 attributes and then pass the copy to this argument.
212 attributes and then pass the copy to this argument.
213
213
214 Notes
214 Notes
215 -----
215 -----
216 Subclasses of Component must call the :meth:`__init__` method of
216 Subclasses of Component must call the :meth:`__init__` method of
217 :class:`Component` *before* doing anything else and using
217 :class:`Component` *before* doing anything else and using
218 :func:`super`::
218 :func:`super`::
219
219
220 class MyComponent(Component):
220 class MyComponent(Component):
221 def __init__(self, parent, name=None, config=None):
221 def __init__(self, parent, name=None, config=None):
222 super(MyComponent, self).__init__(parent, name, config)
222 super(MyComponent, self).__init__(parent, name, config)
223 # Then any other code you need to finish initialization.
223 # Then any other code you need to finish initialization.
224
224
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
226 attributes are handled properly.
226 attributes are handled properly.
227 """
227 """
228 super(Component, self).__init__()
228 super(Component, self).__init__()
229 self._children = []
229 self._children = []
230 if name is None:
230 if name is None:
231 self.name = ComponentNameGenerator()
231 self.name = ComponentNameGenerator()
232 else:
232 else:
233 self.name = name
233 self.name = name
234 self.root = self # This is the default, it is set when parent is set
234 self.root = self # This is the default, it is set when parent is set
235 self.parent = parent
235 self.parent = parent
236 if config is not None:
236 if config is not None:
237 self.config = config
237 self.config = config
238 # We used to deepcopy, but for now we are trying to just save
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
239 # by reference. This *could* have side effects as all components
240 # will share config. In fact, I did find such a side effect in
240 # will share config. In fact, I did find such a side effect in
241 # _config_changed below. If a config attribute value was a mutable type
241 # _config_changed below. If a config attribute value was a mutable type
242 # all instances of a component were getting the same copy, effectively
242 # all instances of a component were getting the same copy, effectively
243 # making that a class attribute.
243 # making that a class attribute.
244 # self.config = deepcopy(config)
244 # self.config = deepcopy(config)
245 else:
245 else:
246 if self.parent is not None:
246 if self.parent is not None:
247 self.config = self.parent.config
247 self.config = self.parent.config
248 # We used to deepcopy, but for now we are trying to just save
248 # We used to deepcopy, but for now we are trying to just save
249 # by reference. This *could* have side effects as all components
249 # by reference. This *could* have side effects as all components
250 # will share config. In fact, I did find such a side effect in
250 # will share config. In fact, I did find such a side effect in
251 # _config_changed below. If a config attribute value was a mutable type
251 # _config_changed below. If a config attribute value was a mutable type
252 # all instances of a component were getting the same copy, effectively
252 # all instances of a component were getting the same copy, effectively
253 # making that a class attribute.
253 # making that a class attribute.
254 # self.config = deepcopy(self.parent.config)
254 # self.config = deepcopy(self.parent.config)
255
255
256 self.created = datetime.datetime.now()
256 self.created = datetime.datetime.now()
257
257
258 #-------------------------------------------------------------------------
258 #-------------------------------------------------------------------------
259 # Static traitlet notifiations
259 # Static trait notifiations
260 #-------------------------------------------------------------------------
260 #-------------------------------------------------------------------------
261
261
262 def _parent_changed(self, name, old, new):
262 def _parent_changed(self, name, old, new):
263 if old is not None:
263 if old is not None:
264 old._remove_child(self)
264 old._remove_child(self)
265 if new is not None:
265 if new is not None:
266 new._add_child(self)
266 new._add_child(self)
267
267
268 if new is None:
268 if new is None:
269 self.root = self
269 self.root = self
270 else:
270 else:
271 self.root = new.root
271 self.root = new.root
272
272
273 def _root_changed(self, name, old, new):
273 def _root_changed(self, name, old, new):
274 if self.parent is None:
274 if self.parent is None:
275 if not (new is self):
275 if not (new is self):
276 raise ComponentError("Root not self, but parent is None.")
276 raise ComponentError("Root not self, but parent is None.")
277 else:
277 else:
278 if not self.parent.root is new:
278 if not self.parent.root is new:
279 raise ComponentError("Error in setting the root attribute: "
279 raise ComponentError("Error in setting the root attribute: "
280 "root != parent.root")
280 "root != parent.root")
281
281
282 def _config_changed(self, name, old, new):
282 def _config_changed(self, name, old, new):
283 """Update all the class traits having ``config=True`` as metadata.
283 """Update all the class traits having ``config=True`` as metadata.
284
284
285 For any class traitlet with a ``config`` metadata attribute that is
285 For any class trait with a ``config`` metadata attribute that is
286 ``True``, we update the traitlet with the value of the corresponding
286 ``True``, we update the trait with the value of the corresponding
287 config entry.
287 config entry.
288 """
288 """
289 # Get all traitlets with a config metadata entry that is True
289 # Get all traits with a config metadata entry that is True
290 traitlets = self.traitlets(config=True)
290 traits = self.traits(config=True)
291
291
292 # We auto-load config section for this class as well as any parent
292 # We auto-load config section for this class as well as any parent
293 # classes that are Component subclasses. This starts with Component
293 # classes that are Component subclasses. This starts with Component
294 # and works down the mro loading the config for each section.
294 # and works down the mro loading the config for each section.
295 section_names = [cls.__name__ for cls in \
295 section_names = [cls.__name__ for cls in \
296 reversed(self.__class__.__mro__) if
296 reversed(self.__class__.__mro__) if
297 issubclass(cls, Component) and issubclass(self.__class__, cls)]
297 issubclass(cls, Component) and issubclass(self.__class__, cls)]
298
298
299 for sname in section_names:
299 for sname in section_names:
300 # Don't do a blind getattr as that would cause the config to
300 # Don't do a blind getattr as that would cause the config to
301 # dynamically create the section with name self.__class__.__name__.
301 # dynamically create the section with name self.__class__.__name__.
302 if new._has_section(sname):
302 if new._has_section(sname):
303 my_config = new[sname]
303 my_config = new[sname]
304 for k, v in traitlets.items():
304 for k, v in traits.items():
305 # Don't allow traitlets with config=True to start with
305 # Don't allow traitlets with config=True to start with
306 # uppercase. Otherwise, they are confused with Config
306 # uppercase. Otherwise, they are confused with Config
307 # subsections. But, developers shouldn't have uppercase
307 # subsections. But, developers shouldn't have uppercase
308 # attributes anyways! (PEP 6)
308 # attributes anyways! (PEP 6)
309 if k[0].upper()==k[0] and not k.startswith('_'):
309 if k[0].upper()==k[0] and not k.startswith('_'):
310 raise ComponentError('Component traitlets with '
310 raise ComponentError('Component traitlets with '
311 'config=True must start with a lowercase so they are '
311 'config=True must start with a lowercase so they are '
312 'not confused with Config subsections: %s.%s' % \
312 'not confused with Config subsections: %s.%s' % \
313 (self.__class__.__name__, k))
313 (self.__class__.__name__, k))
314 try:
314 try:
315 # Here we grab the value from the config
315 # Here we grab the value from the config
316 # If k has the naming convention of a config
316 # If k has the naming convention of a config
317 # section, it will be auto created.
317 # section, it will be auto created.
318 config_value = my_config[k]
318 config_value = my_config[k]
319 except KeyError:
319 except KeyError:
320 pass
320 pass
321 else:
321 else:
322 # print "Setting %s.%s from %s.%s=%r" % \
322 # print "Setting %s.%s from %s.%s=%r" % \
323 # (self.__class__.__name__,k,sname,k,config_value)
323 # (self.__class__.__name__,k,sname,k,config_value)
324 # We have to do a deepcopy here if we don't deepcopy the entire
324 # We have to do a deepcopy here if we don't deepcopy the entire
325 # config object. If we don't, a mutable config_value will be
325 # config object. If we don't, a mutable config_value will be
326 # shared by all instances, effectively making it a class attribute.
326 # shared by all instances, effectively making it a class attribute.
327 setattr(self, k, deepcopy(config_value))
327 setattr(self, k, deepcopy(config_value))
328
328
329 @property
329 @property
330 def children(self):
330 def children(self):
331 """A list of all my child components."""
331 """A list of all my child components."""
332 return self._children
332 return self._children
333
333
334 def _remove_child(self, child):
334 def _remove_child(self, child):
335 """A private method for removing children components."""
335 """A private method for removing children components."""
336 if child in self._children:
336 if child in self._children:
337 index = self._children.index(child)
337 index = self._children.index(child)
338 del self._children[index]
338 del self._children[index]
339
339
340 def _add_child(self, child):
340 def _add_child(self, child):
341 """A private method for adding children components."""
341 """A private method for adding children components."""
342 if child not in self._children:
342 if child not in self._children:
343 self._children.append(child)
343 self._children.append(child)
344
344
345 def __repr__(self):
345 def __repr__(self):
346 return "<%s('%s')>" % (self.__class__.__name__, self.name)
346 return "<%s('%s')>" % (self.__class__.__name__, self.name)
@@ -1,2561 +1,2561 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Main IPython Component
3 Main IPython Component
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from __future__ import with_statement
19 from __future__ import with_statement
20 from __future__ import absolute_import
20 from __future__ import absolute_import
21
21
22 import __builtin__
22 import __builtin__
23 import bdb
23 import bdb
24 import codeop
24 import codeop
25 import exceptions
25 import exceptions
26 import new
26 import new
27 import os
27 import os
28 import re
28 import re
29 import string
29 import string
30 import sys
30 import sys
31 import tempfile
31 import tempfile
32 from contextlib import nested
32 from contextlib import nested
33
33
34 from IPython.core import debugger, oinspect
34 from IPython.core import debugger, oinspect
35 from IPython.core import history as ipcorehist
35 from IPython.core import history as ipcorehist
36 from IPython.core import prefilter
36 from IPython.core import prefilter
37 from IPython.core import shadowns
37 from IPython.core import shadowns
38 from IPython.core import ultratb
38 from IPython.core import ultratb
39 from IPython.core.alias import AliasManager
39 from IPython.core.alias import AliasManager
40 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.component import Component
41 from IPython.core.component import Component
42 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.display_trap import DisplayTrap
43 from IPython.core.error import TryNext, UsageError
43 from IPython.core.error import TryNext, UsageError
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.logger import Logger
45 from IPython.core.logger import Logger
46 from IPython.core.magic import Magic
46 from IPython.core.magic import Magic
47 from IPython.core.prefilter import PrefilterManager
47 from IPython.core.prefilter import PrefilterManager
48 from IPython.core.prompts import CachedOutput
48 from IPython.core.prompts import CachedOutput
49 from IPython.core.usage import interactive_usage, default_banner
49 from IPython.core.usage import interactive_usage, default_banner
50 import IPython.core.hooks
50 import IPython.core.hooks
51 from IPython.external.Itpl import ItplNS
51 from IPython.external.Itpl import ItplNS
52 from IPython.lib.inputhook import enable_gui
52 from IPython.lib.inputhook import enable_gui
53 from IPython.lib.backgroundjobs import BackgroundJobManager
53 from IPython.lib.backgroundjobs import BackgroundJobManager
54 from IPython.lib.pylabtools import pylab_activate
54 from IPython.lib.pylabtools import pylab_activate
55 from IPython.utils import PyColorize
55 from IPython.utils import PyColorize
56 from IPython.utils import pickleshare
56 from IPython.utils import pickleshare
57 from IPython.utils.doctestreload import doctest_reload
57 from IPython.utils.doctestreload import doctest_reload
58 from IPython.utils.ipstruct import Struct
58 from IPython.utils.ipstruct import Struct
59 from IPython.utils.io import Term, ask_yes_no
59 from IPython.utils.io import Term, ask_yes_no
60 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
60 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
61 from IPython.utils.process import (
61 from IPython.utils.process import (
62 abbrev_cwd,
62 abbrev_cwd,
63 getoutput,
63 getoutput,
64 getoutputerror
64 getoutputerror
65 )
65 )
66 # import IPython.utils.rlineimpl as readline
66 # import IPython.utils.rlineimpl as readline
67 from IPython.utils.strdispatch import StrDispatch
67 from IPython.utils.strdispatch import StrDispatch
68 from IPython.utils.syspathcontext import prepended_to_syspath
68 from IPython.utils.syspathcontext import prepended_to_syspath
69 from IPython.utils.terminal import toggle_set_term_title, set_term_title
69 from IPython.utils.terminal import toggle_set_term_title, set_term_title
70 from IPython.utils.warn import warn, error, fatal
70 from IPython.utils.warn import warn, error, fatal
71 from IPython.utils.traitlets import (
71 from IPython.utils.traitlets import (
72 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
72 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
73 )
73 )
74
74
75 # from IPython.utils import growl
75 # from IPython.utils import growl
76 # growl.start("IPython")
76 # growl.start("IPython")
77
77
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79 # Globals
79 # Globals
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81
81
82 # store the builtin raw_input globally, and use this always, in case user code
82 # store the builtin raw_input globally, and use this always, in case user code
83 # overwrites it (like wx.py.PyShell does)
83 # overwrites it (like wx.py.PyShell does)
84 raw_input_original = raw_input
84 raw_input_original = raw_input
85
85
86 # compiled regexps for autoindent management
86 # compiled regexps for autoindent management
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88
88
89 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
90 # Utilities
90 # Utilities
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92
92
93 ini_spaces_re = re.compile(r'^(\s+)')
93 ini_spaces_re = re.compile(r'^(\s+)')
94
94
95
95
96 def num_ini_spaces(strng):
96 def num_ini_spaces(strng):
97 """Return the number of initial spaces in a string"""
97 """Return the number of initial spaces in a string"""
98
98
99 ini_spaces = ini_spaces_re.match(strng)
99 ini_spaces = ini_spaces_re.match(strng)
100 if ini_spaces:
100 if ini_spaces:
101 return ini_spaces.end()
101 return ini_spaces.end()
102 else:
102 else:
103 return 0
103 return 0
104
104
105
105
106 def softspace(file, newvalue):
106 def softspace(file, newvalue):
107 """Copied from code.py, to remove the dependency"""
107 """Copied from code.py, to remove the dependency"""
108
108
109 oldvalue = 0
109 oldvalue = 0
110 try:
110 try:
111 oldvalue = file.softspace
111 oldvalue = file.softspace
112 except AttributeError:
112 except AttributeError:
113 pass
113 pass
114 try:
114 try:
115 file.softspace = newvalue
115 file.softspace = newvalue
116 except (AttributeError, TypeError):
116 except (AttributeError, TypeError):
117 # "attribute-less object" or "read-only attributes"
117 # "attribute-less object" or "read-only attributes"
118 pass
118 pass
119 return oldvalue
119 return oldvalue
120
120
121
121
122 def no_op(*a, **kw): pass
122 def no_op(*a, **kw): pass
123
123
124 class SpaceInInput(exceptions.Exception): pass
124 class SpaceInInput(exceptions.Exception): pass
125
125
126 class Bunch: pass
126 class Bunch: pass
127
127
128 class InputList(list):
128 class InputList(list):
129 """Class to store user input.
129 """Class to store user input.
130
130
131 It's basically a list, but slices return a string instead of a list, thus
131 It's basically a list, but slices return a string instead of a list, thus
132 allowing things like (assuming 'In' is an instance):
132 allowing things like (assuming 'In' is an instance):
133
133
134 exec In[4:7]
134 exec In[4:7]
135
135
136 or
136 or
137
137
138 exec In[5:9] + In[14] + In[21:25]"""
138 exec In[5:9] + In[14] + In[21:25]"""
139
139
140 def __getslice__(self,i,j):
140 def __getslice__(self,i,j):
141 return ''.join(list.__getslice__(self,i,j))
141 return ''.join(list.__getslice__(self,i,j))
142
142
143
143
144 class SyntaxTB(ultratb.ListTB):
144 class SyntaxTB(ultratb.ListTB):
145 """Extension which holds some state: the last exception value"""
145 """Extension which holds some state: the last exception value"""
146
146
147 def __init__(self,color_scheme = 'NoColor'):
147 def __init__(self,color_scheme = 'NoColor'):
148 ultratb.ListTB.__init__(self,color_scheme)
148 ultratb.ListTB.__init__(self,color_scheme)
149 self.last_syntax_error = None
149 self.last_syntax_error = None
150
150
151 def __call__(self, etype, value, elist):
151 def __call__(self, etype, value, elist):
152 self.last_syntax_error = value
152 self.last_syntax_error = value
153 ultratb.ListTB.__call__(self,etype,value,elist)
153 ultratb.ListTB.__call__(self,etype,value,elist)
154
154
155 def clear_err_state(self):
155 def clear_err_state(self):
156 """Return the current error state and clear it"""
156 """Return the current error state and clear it"""
157 e = self.last_syntax_error
157 e = self.last_syntax_error
158 self.last_syntax_error = None
158 self.last_syntax_error = None
159 return e
159 return e
160
160
161
161
162 def get_default_editor():
162 def get_default_editor():
163 try:
163 try:
164 ed = os.environ['EDITOR']
164 ed = os.environ['EDITOR']
165 except KeyError:
165 except KeyError:
166 if os.name == 'posix':
166 if os.name == 'posix':
167 ed = 'vi' # the only one guaranteed to be there!
167 ed = 'vi' # the only one guaranteed to be there!
168 else:
168 else:
169 ed = 'notepad' # same in Windows!
169 ed = 'notepad' # same in Windows!
170 return ed
170 return ed
171
171
172
172
173 def get_default_colors():
173 def get_default_colors():
174 if sys.platform=='darwin':
174 if sys.platform=='darwin':
175 return "LightBG"
175 return "LightBG"
176 elif os.name=='nt':
176 elif os.name=='nt':
177 return 'Linux'
177 return 'Linux'
178 else:
178 else:
179 return 'Linux'
179 return 'Linux'
180
180
181
181
182 class SeparateStr(Str):
182 class SeparateStr(Str):
183 """A Str subclass to validate separate_in, separate_out, etc.
183 """A Str subclass to validate separate_in, separate_out, etc.
184
184
185 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
185 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
186 """
186 """
187
187
188 def validate(self, obj, value):
188 def validate(self, obj, value):
189 if value == '0': value = ''
189 if value == '0': value = ''
190 value = value.replace('\\n','\n')
190 value = value.replace('\\n','\n')
191 return super(SeparateStr, self).validate(obj, value)
191 return super(SeparateStr, self).validate(obj, value)
192
192
193
193
194 #-----------------------------------------------------------------------------
194 #-----------------------------------------------------------------------------
195 # Main IPython class
195 # Main IPython class
196 #-----------------------------------------------------------------------------
196 #-----------------------------------------------------------------------------
197
197
198
198
199 class InteractiveShell(Component, Magic):
199 class InteractiveShell(Component, Magic):
200 """An enhanced, interactive shell for Python."""
200 """An enhanced, interactive shell for Python."""
201
201
202 autocall = Enum((0,1,2), default_value=1, config=True)
202 autocall = Enum((0,1,2), default_value=1, config=True)
203 autoedit_syntax = CBool(False, config=True)
203 autoedit_syntax = CBool(False, config=True)
204 autoindent = CBool(True, config=True)
204 autoindent = CBool(True, config=True)
205 automagic = CBool(True, config=True)
205 automagic = CBool(True, config=True)
206 banner = Str('')
206 banner = Str('')
207 banner1 = Str(default_banner, config=True)
207 banner1 = Str(default_banner, config=True)
208 banner2 = Str('', config=True)
208 banner2 = Str('', config=True)
209 cache_size = Int(1000, config=True)
209 cache_size = Int(1000, config=True)
210 color_info = CBool(True, config=True)
210 color_info = CBool(True, config=True)
211 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
211 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
212 default_value=get_default_colors(), config=True)
212 default_value=get_default_colors(), config=True)
213 confirm_exit = CBool(True, config=True)
213 confirm_exit = CBool(True, config=True)
214 debug = CBool(False, config=True)
214 debug = CBool(False, config=True)
215 deep_reload = CBool(False, config=True)
215 deep_reload = CBool(False, config=True)
216 # This display_banner only controls whether or not self.show_banner()
216 # This display_banner only controls whether or not self.show_banner()
217 # is called when mainloop/interact are called. The default is False
217 # is called when mainloop/interact are called. The default is False
218 # because for the terminal based application, the banner behavior
218 # because for the terminal based application, the banner behavior
219 # is controlled by Global.display_banner, which IPythonApp looks at
219 # is controlled by Global.display_banner, which IPythonApp looks at
220 # to determine if *it* should call show_banner() by hand or not.
220 # to determine if *it* should call show_banner() by hand or not.
221 display_banner = CBool(False) # This isn't configurable!
221 display_banner = CBool(False) # This isn't configurable!
222 embedded = CBool(False)
222 embedded = CBool(False)
223 embedded_active = CBool(False)
223 embedded_active = CBool(False)
224 editor = Str(get_default_editor(), config=True)
224 editor = Str(get_default_editor(), config=True)
225 filename = Str("<ipython console>")
225 filename = Str("<ipython console>")
226 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
226 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
227 logstart = CBool(False, config=True)
227 logstart = CBool(False, config=True)
228 logfile = Str('', config=True)
228 logfile = Str('', config=True)
229 logappend = Str('', config=True)
229 logappend = Str('', config=True)
230 object_info_string_level = Enum((0,1,2), default_value=0,
230 object_info_string_level = Enum((0,1,2), default_value=0,
231 config=True)
231 config=True)
232 pager = Str('less', config=True)
232 pager = Str('less', config=True)
233 pdb = CBool(False, config=True)
233 pdb = CBool(False, config=True)
234 pprint = CBool(True, config=True)
234 pprint = CBool(True, config=True)
235 profile = Str('', config=True)
235 profile = Str('', config=True)
236 prompt_in1 = Str('In [\\#]: ', config=True)
236 prompt_in1 = Str('In [\\#]: ', config=True)
237 prompt_in2 = Str(' .\\D.: ', config=True)
237 prompt_in2 = Str(' .\\D.: ', config=True)
238 prompt_out = Str('Out[\\#]: ', config=True)
238 prompt_out = Str('Out[\\#]: ', config=True)
239 prompts_pad_left = CBool(True, config=True)
239 prompts_pad_left = CBool(True, config=True)
240 quiet = CBool(False, config=True)
240 quiet = CBool(False, config=True)
241
241
242 readline_use = CBool(True, config=True)
242 readline_use = CBool(True, config=True)
243 readline_merge_completions = CBool(True, config=True)
243 readline_merge_completions = CBool(True, config=True)
244 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
244 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
245 readline_remove_delims = Str('-/~', config=True)
245 readline_remove_delims = Str('-/~', config=True)
246 readline_parse_and_bind = List([
246 readline_parse_and_bind = List([
247 'tab: complete',
247 'tab: complete',
248 '"\C-l": possible-completions',
248 '"\C-l": possible-completions',
249 'set show-all-if-ambiguous on',
249 'set show-all-if-ambiguous on',
250 '"\C-o": tab-insert',
250 '"\C-o": tab-insert',
251 '"\M-i": " "',
251 '"\M-i": " "',
252 '"\M-o": "\d\d\d\d"',
252 '"\M-o": "\d\d\d\d"',
253 '"\M-I": "\d\d\d\d"',
253 '"\M-I": "\d\d\d\d"',
254 '"\C-r": reverse-search-history',
254 '"\C-r": reverse-search-history',
255 '"\C-s": forward-search-history',
255 '"\C-s": forward-search-history',
256 '"\C-p": history-search-backward',
256 '"\C-p": history-search-backward',
257 '"\C-n": history-search-forward',
257 '"\C-n": history-search-forward',
258 '"\e[A": history-search-backward',
258 '"\e[A": history-search-backward',
259 '"\e[B": history-search-forward',
259 '"\e[B": history-search-forward',
260 '"\C-k": kill-line',
260 '"\C-k": kill-line',
261 '"\C-u": unix-line-discard',
261 '"\C-u": unix-line-discard',
262 ], allow_none=False, config=True)
262 ], allow_none=False, config=True)
263
263
264 screen_length = Int(0, config=True)
264 screen_length = Int(0, config=True)
265
265
266 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
266 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
267 separate_in = SeparateStr('\n', config=True)
267 separate_in = SeparateStr('\n', config=True)
268 separate_out = SeparateStr('', config=True)
268 separate_out = SeparateStr('', config=True)
269 separate_out2 = SeparateStr('', config=True)
269 separate_out2 = SeparateStr('', config=True)
270
270
271 system_header = Str('IPython system call: ', config=True)
271 system_header = Str('IPython system call: ', config=True)
272 system_verbose = CBool(False, config=True)
272 system_verbose = CBool(False, config=True)
273 term_title = CBool(False, config=True)
273 term_title = CBool(False, config=True)
274 wildcards_case_sensitive = CBool(True, config=True)
274 wildcards_case_sensitive = CBool(True, config=True)
275 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
275 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
276 default_value='Context', config=True)
276 default_value='Context', config=True)
277
277
278 autoexec = List(allow_none=False)
278 autoexec = List(allow_none=False)
279
279
280 # class attribute to indicate whether the class supports threads or not.
280 # class attribute to indicate whether the class supports threads or not.
281 # Subclasses with thread support should override this as needed.
281 # Subclasses with thread support should override this as needed.
282 isthreaded = False
282 isthreaded = False
283
283
284 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
284 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
285 user_ns=None, user_global_ns=None,
285 user_ns=None, user_global_ns=None,
286 banner1=None, banner2=None, display_banner=None,
286 banner1=None, banner2=None, display_banner=None,
287 custom_exceptions=((),None)):
287 custom_exceptions=((),None)):
288
288
289 # This is where traitlets with a config_key argument are updated
289 # This is where traits with a config_key argument are updated
290 # from the values on config.
290 # from the values on config.
291 super(InteractiveShell, self).__init__(parent, config=config)
291 super(InteractiveShell, self).__init__(parent, config=config)
292
292
293 # These are relatively independent and stateless
293 # These are relatively independent and stateless
294 self.init_ipython_dir(ipython_dir)
294 self.init_ipython_dir(ipython_dir)
295 self.init_instance_attrs()
295 self.init_instance_attrs()
296 self.init_term_title()
296 self.init_term_title()
297 self.init_usage(usage)
297 self.init_usage(usage)
298 self.init_banner(banner1, banner2, display_banner)
298 self.init_banner(banner1, banner2, display_banner)
299
299
300 # Create namespaces (user_ns, user_global_ns, etc.)
300 # Create namespaces (user_ns, user_global_ns, etc.)
301 self.init_create_namespaces(user_ns, user_global_ns)
301 self.init_create_namespaces(user_ns, user_global_ns)
302 # This has to be done after init_create_namespaces because it uses
302 # This has to be done after init_create_namespaces because it uses
303 # something in self.user_ns, but before init_sys_modules, which
303 # something in self.user_ns, but before init_sys_modules, which
304 # is the first thing to modify sys.
304 # is the first thing to modify sys.
305 self.save_sys_module_state()
305 self.save_sys_module_state()
306 self.init_sys_modules()
306 self.init_sys_modules()
307
307
308 self.init_history()
308 self.init_history()
309 self.init_encoding()
309 self.init_encoding()
310 self.init_prefilter()
310 self.init_prefilter()
311
311
312 Magic.__init__(self, self)
312 Magic.__init__(self, self)
313
313
314 self.init_syntax_highlighting()
314 self.init_syntax_highlighting()
315 self.init_hooks()
315 self.init_hooks()
316 self.init_pushd_popd_magic()
316 self.init_pushd_popd_magic()
317 self.init_traceback_handlers(custom_exceptions)
317 self.init_traceback_handlers(custom_exceptions)
318 self.init_user_ns()
318 self.init_user_ns()
319 self.init_logger()
319 self.init_logger()
320 self.init_alias()
320 self.init_alias()
321 self.init_builtins()
321 self.init_builtins()
322
322
323 # pre_config_initialization
323 # pre_config_initialization
324 self.init_shadow_hist()
324 self.init_shadow_hist()
325
325
326 # The next section should contain averything that was in ipmaker.
326 # The next section should contain averything that was in ipmaker.
327 self.init_logstart()
327 self.init_logstart()
328
328
329 # The following was in post_config_initialization
329 # The following was in post_config_initialization
330 self.init_inspector()
330 self.init_inspector()
331 self.init_readline()
331 self.init_readline()
332 self.init_prompts()
332 self.init_prompts()
333 self.init_displayhook()
333 self.init_displayhook()
334 self.init_reload_doctest()
334 self.init_reload_doctest()
335 self.init_magics()
335 self.init_magics()
336 self.init_pdb()
336 self.init_pdb()
337 self.hooks.late_startup_hook()
337 self.hooks.late_startup_hook()
338
338
339 def get_ipython(self):
339 def get_ipython(self):
340 """Return the currently running IPython instance."""
340 """Return the currently running IPython instance."""
341 return self
341 return self
342
342
343 #-------------------------------------------------------------------------
343 #-------------------------------------------------------------------------
344 # Traitlet changed handlers
344 # Trait changed handlers
345 #-------------------------------------------------------------------------
345 #-------------------------------------------------------------------------
346
346
347 def _banner1_changed(self):
347 def _banner1_changed(self):
348 self.compute_banner()
348 self.compute_banner()
349
349
350 def _banner2_changed(self):
350 def _banner2_changed(self):
351 self.compute_banner()
351 self.compute_banner()
352
352
353 def _ipython_dir_changed(self, name, new):
353 def _ipython_dir_changed(self, name, new):
354 if not os.path.isdir(new):
354 if not os.path.isdir(new):
355 os.makedirs(new, mode = 0777)
355 os.makedirs(new, mode = 0777)
356 if not os.path.isdir(self.ipython_extension_dir):
356 if not os.path.isdir(self.ipython_extension_dir):
357 os.makedirs(self.ipython_extension_dir, mode = 0777)
357 os.makedirs(self.ipython_extension_dir, mode = 0777)
358
358
359 @property
359 @property
360 def ipython_extension_dir(self):
360 def ipython_extension_dir(self):
361 return os.path.join(self.ipython_dir, 'extensions')
361 return os.path.join(self.ipython_dir, 'extensions')
362
362
363 @property
363 @property
364 def usable_screen_length(self):
364 def usable_screen_length(self):
365 if self.screen_length == 0:
365 if self.screen_length == 0:
366 return 0
366 return 0
367 else:
367 else:
368 num_lines_bot = self.separate_in.count('\n')+1
368 num_lines_bot = self.separate_in.count('\n')+1
369 return self.screen_length - num_lines_bot
369 return self.screen_length - num_lines_bot
370
370
371 def _term_title_changed(self, name, new_value):
371 def _term_title_changed(self, name, new_value):
372 self.init_term_title()
372 self.init_term_title()
373
373
374 def set_autoindent(self,value=None):
374 def set_autoindent(self,value=None):
375 """Set the autoindent flag, checking for readline support.
375 """Set the autoindent flag, checking for readline support.
376
376
377 If called with no arguments, it acts as a toggle."""
377 If called with no arguments, it acts as a toggle."""
378
378
379 if not self.has_readline:
379 if not self.has_readline:
380 if os.name == 'posix':
380 if os.name == 'posix':
381 warn("The auto-indent feature requires the readline library")
381 warn("The auto-indent feature requires the readline library")
382 self.autoindent = 0
382 self.autoindent = 0
383 return
383 return
384 if value is None:
384 if value is None:
385 self.autoindent = not self.autoindent
385 self.autoindent = not self.autoindent
386 else:
386 else:
387 self.autoindent = value
387 self.autoindent = value
388
388
389 #-------------------------------------------------------------------------
389 #-------------------------------------------------------------------------
390 # init_* methods called by __init__
390 # init_* methods called by __init__
391 #-------------------------------------------------------------------------
391 #-------------------------------------------------------------------------
392
392
393 def init_ipython_dir(self, ipython_dir):
393 def init_ipython_dir(self, ipython_dir):
394 if ipython_dir is not None:
394 if ipython_dir is not None:
395 self.ipython_dir = ipython_dir
395 self.ipython_dir = ipython_dir
396 self.config.Global.ipython_dir = self.ipython_dir
396 self.config.Global.ipython_dir = self.ipython_dir
397 return
397 return
398
398
399 if hasattr(self.config.Global, 'ipython_dir'):
399 if hasattr(self.config.Global, 'ipython_dir'):
400 self.ipython_dir = self.config.Global.ipython_dir
400 self.ipython_dir = self.config.Global.ipython_dir
401 else:
401 else:
402 self.ipython_dir = get_ipython_dir()
402 self.ipython_dir = get_ipython_dir()
403
403
404 # All children can just read this
404 # All children can just read this
405 self.config.Global.ipython_dir = self.ipython_dir
405 self.config.Global.ipython_dir = self.ipython_dir
406
406
407 def init_instance_attrs(self):
407 def init_instance_attrs(self):
408 self.jobs = BackgroundJobManager()
408 self.jobs = BackgroundJobManager()
409 self.more = False
409 self.more = False
410
410
411 # command compiler
411 # command compiler
412 self.compile = codeop.CommandCompiler()
412 self.compile = codeop.CommandCompiler()
413
413
414 # User input buffer
414 # User input buffer
415 self.buffer = []
415 self.buffer = []
416
416
417 # Make an empty namespace, which extension writers can rely on both
417 # Make an empty namespace, which extension writers can rely on both
418 # existing and NEVER being used by ipython itself. This gives them a
418 # existing and NEVER being used by ipython itself. This gives them a
419 # convenient location for storing additional information and state
419 # convenient location for storing additional information and state
420 # their extensions may require, without fear of collisions with other
420 # their extensions may require, without fear of collisions with other
421 # ipython names that may develop later.
421 # ipython names that may develop later.
422 self.meta = Struct()
422 self.meta = Struct()
423
423
424 # Object variable to store code object waiting execution. This is
424 # Object variable to store code object waiting execution. This is
425 # used mainly by the multithreaded shells, but it can come in handy in
425 # used mainly by the multithreaded shells, but it can come in handy in
426 # other situations. No need to use a Queue here, since it's a single
426 # other situations. No need to use a Queue here, since it's a single
427 # item which gets cleared once run.
427 # item which gets cleared once run.
428 self.code_to_run = None
428 self.code_to_run = None
429
429
430 # Flag to mark unconditional exit
430 # Flag to mark unconditional exit
431 self.exit_now = False
431 self.exit_now = False
432
432
433 # Temporary files used for various purposes. Deleted at exit.
433 # Temporary files used for various purposes. Deleted at exit.
434 self.tempfiles = []
434 self.tempfiles = []
435
435
436 # Keep track of readline usage (later set by init_readline)
436 # Keep track of readline usage (later set by init_readline)
437 self.has_readline = False
437 self.has_readline = False
438
438
439 # keep track of where we started running (mainly for crash post-mortem)
439 # keep track of where we started running (mainly for crash post-mortem)
440 # This is not being used anywhere currently.
440 # This is not being used anywhere currently.
441 self.starting_dir = os.getcwd()
441 self.starting_dir = os.getcwd()
442
442
443 # Indentation management
443 # Indentation management
444 self.indent_current_nsp = 0
444 self.indent_current_nsp = 0
445
445
446 def init_term_title(self):
446 def init_term_title(self):
447 # Enable or disable the terminal title.
447 # Enable or disable the terminal title.
448 if self.term_title:
448 if self.term_title:
449 toggle_set_term_title(True)
449 toggle_set_term_title(True)
450 set_term_title('IPython: ' + abbrev_cwd())
450 set_term_title('IPython: ' + abbrev_cwd())
451 else:
451 else:
452 toggle_set_term_title(False)
452 toggle_set_term_title(False)
453
453
454 def init_usage(self, usage=None):
454 def init_usage(self, usage=None):
455 if usage is None:
455 if usage is None:
456 self.usage = interactive_usage
456 self.usage = interactive_usage
457 else:
457 else:
458 self.usage = usage
458 self.usage = usage
459
459
460 def init_encoding(self):
460 def init_encoding(self):
461 # Get system encoding at startup time. Certain terminals (like Emacs
461 # Get system encoding at startup time. Certain terminals (like Emacs
462 # under Win32 have it set to None, and we need to have a known valid
462 # under Win32 have it set to None, and we need to have a known valid
463 # encoding to use in the raw_input() method
463 # encoding to use in the raw_input() method
464 try:
464 try:
465 self.stdin_encoding = sys.stdin.encoding or 'ascii'
465 self.stdin_encoding = sys.stdin.encoding or 'ascii'
466 except AttributeError:
466 except AttributeError:
467 self.stdin_encoding = 'ascii'
467 self.stdin_encoding = 'ascii'
468
468
469 def init_syntax_highlighting(self):
469 def init_syntax_highlighting(self):
470 # Python source parser/formatter for syntax highlighting
470 # Python source parser/formatter for syntax highlighting
471 pyformat = PyColorize.Parser().format
471 pyformat = PyColorize.Parser().format
472 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
472 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
473
473
474 def init_pushd_popd_magic(self):
474 def init_pushd_popd_magic(self):
475 # for pushd/popd management
475 # for pushd/popd management
476 try:
476 try:
477 self.home_dir = get_home_dir()
477 self.home_dir = get_home_dir()
478 except HomeDirError, msg:
478 except HomeDirError, msg:
479 fatal(msg)
479 fatal(msg)
480
480
481 self.dir_stack = []
481 self.dir_stack = []
482
482
483 def init_logger(self):
483 def init_logger(self):
484 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
484 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
485 # local shortcut, this is used a LOT
485 # local shortcut, this is used a LOT
486 self.log = self.logger.log
486 self.log = self.logger.log
487
487
488 def init_logstart(self):
488 def init_logstart(self):
489 if self.logappend:
489 if self.logappend:
490 self.magic_logstart(self.logappend + ' append')
490 self.magic_logstart(self.logappend + ' append')
491 elif self.logfile:
491 elif self.logfile:
492 self.magic_logstart(self.logfile)
492 self.magic_logstart(self.logfile)
493 elif self.logstart:
493 elif self.logstart:
494 self.magic_logstart()
494 self.magic_logstart()
495
495
496 def init_builtins(self):
496 def init_builtins(self):
497 self.builtin_trap = BuiltinTrap(self)
497 self.builtin_trap = BuiltinTrap(self)
498
498
499 def init_inspector(self):
499 def init_inspector(self):
500 # Object inspector
500 # Object inspector
501 self.inspector = oinspect.Inspector(oinspect.InspectColors,
501 self.inspector = oinspect.Inspector(oinspect.InspectColors,
502 PyColorize.ANSICodeColors,
502 PyColorize.ANSICodeColors,
503 'NoColor',
503 'NoColor',
504 self.object_info_string_level)
504 self.object_info_string_level)
505
505
506 def init_prompts(self):
506 def init_prompts(self):
507 # Initialize cache, set in/out prompts and printing system
507 # Initialize cache, set in/out prompts and printing system
508 self.outputcache = CachedOutput(self,
508 self.outputcache = CachedOutput(self,
509 self.cache_size,
509 self.cache_size,
510 self.pprint,
510 self.pprint,
511 input_sep = self.separate_in,
511 input_sep = self.separate_in,
512 output_sep = self.separate_out,
512 output_sep = self.separate_out,
513 output_sep2 = self.separate_out2,
513 output_sep2 = self.separate_out2,
514 ps1 = self.prompt_in1,
514 ps1 = self.prompt_in1,
515 ps2 = self.prompt_in2,
515 ps2 = self.prompt_in2,
516 ps_out = self.prompt_out,
516 ps_out = self.prompt_out,
517 pad_left = self.prompts_pad_left)
517 pad_left = self.prompts_pad_left)
518
518
519 # user may have over-ridden the default print hook:
519 # user may have over-ridden the default print hook:
520 try:
520 try:
521 self.outputcache.__class__.display = self.hooks.display
521 self.outputcache.__class__.display = self.hooks.display
522 except AttributeError:
522 except AttributeError:
523 pass
523 pass
524
524
525 def init_displayhook(self):
525 def init_displayhook(self):
526 self.display_trap = DisplayTrap(self, self.outputcache)
526 self.display_trap = DisplayTrap(self, self.outputcache)
527
527
528 def init_reload_doctest(self):
528 def init_reload_doctest(self):
529 # Do a proper resetting of doctest, including the necessary displayhook
529 # Do a proper resetting of doctest, including the necessary displayhook
530 # monkeypatching
530 # monkeypatching
531 try:
531 try:
532 doctest_reload()
532 doctest_reload()
533 except ImportError:
533 except ImportError:
534 warn("doctest module does not exist.")
534 warn("doctest module does not exist.")
535
535
536 #-------------------------------------------------------------------------
536 #-------------------------------------------------------------------------
537 # Things related to the banner
537 # Things related to the banner
538 #-------------------------------------------------------------------------
538 #-------------------------------------------------------------------------
539
539
540 def init_banner(self, banner1, banner2, display_banner):
540 def init_banner(self, banner1, banner2, display_banner):
541 if banner1 is not None:
541 if banner1 is not None:
542 self.banner1 = banner1
542 self.banner1 = banner1
543 if banner2 is not None:
543 if banner2 is not None:
544 self.banner2 = banner2
544 self.banner2 = banner2
545 if display_banner is not None:
545 if display_banner is not None:
546 self.display_banner = display_banner
546 self.display_banner = display_banner
547 self.compute_banner()
547 self.compute_banner()
548
548
549 def show_banner(self, banner=None):
549 def show_banner(self, banner=None):
550 if banner is None:
550 if banner is None:
551 banner = self.banner
551 banner = self.banner
552 self.write(banner)
552 self.write(banner)
553
553
554 def compute_banner(self):
554 def compute_banner(self):
555 self.banner = self.banner1 + '\n'
555 self.banner = self.banner1 + '\n'
556 if self.profile:
556 if self.profile:
557 self.banner += '\nIPython profile: %s\n' % self.profile
557 self.banner += '\nIPython profile: %s\n' % self.profile
558 if self.banner2:
558 if self.banner2:
559 self.banner += '\n' + self.banner2 + '\n'
559 self.banner += '\n' + self.banner2 + '\n'
560
560
561 #-------------------------------------------------------------------------
561 #-------------------------------------------------------------------------
562 # Things related to injections into the sys module
562 # Things related to injections into the sys module
563 #-------------------------------------------------------------------------
563 #-------------------------------------------------------------------------
564
564
565 def save_sys_module_state(self):
565 def save_sys_module_state(self):
566 """Save the state of hooks in the sys module.
566 """Save the state of hooks in the sys module.
567
567
568 This has to be called after self.user_ns is created.
568 This has to be called after self.user_ns is created.
569 """
569 """
570 self._orig_sys_module_state = {}
570 self._orig_sys_module_state = {}
571 self._orig_sys_module_state['stdin'] = sys.stdin
571 self._orig_sys_module_state['stdin'] = sys.stdin
572 self._orig_sys_module_state['stdout'] = sys.stdout
572 self._orig_sys_module_state['stdout'] = sys.stdout
573 self._orig_sys_module_state['stderr'] = sys.stderr
573 self._orig_sys_module_state['stderr'] = sys.stderr
574 self._orig_sys_module_state['excepthook'] = sys.excepthook
574 self._orig_sys_module_state['excepthook'] = sys.excepthook
575 try:
575 try:
576 self._orig_sys_modules_main_name = self.user_ns['__name__']
576 self._orig_sys_modules_main_name = self.user_ns['__name__']
577 except KeyError:
577 except KeyError:
578 pass
578 pass
579
579
580 def restore_sys_module_state(self):
580 def restore_sys_module_state(self):
581 """Restore the state of the sys module."""
581 """Restore the state of the sys module."""
582 try:
582 try:
583 for k, v in self._orig_sys_module_state.items():
583 for k, v in self._orig_sys_module_state.items():
584 setattr(sys, k, v)
584 setattr(sys, k, v)
585 except AttributeError:
585 except AttributeError:
586 pass
586 pass
587 try:
587 try:
588 delattr(sys, 'ipcompleter')
588 delattr(sys, 'ipcompleter')
589 except AttributeError:
589 except AttributeError:
590 pass
590 pass
591 # Reset what what done in self.init_sys_modules
591 # Reset what what done in self.init_sys_modules
592 try:
592 try:
593 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
593 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
594 except (AttributeError, KeyError):
594 except (AttributeError, KeyError):
595 pass
595 pass
596
596
597 #-------------------------------------------------------------------------
597 #-------------------------------------------------------------------------
598 # Things related to hooks
598 # Things related to hooks
599 #-------------------------------------------------------------------------
599 #-------------------------------------------------------------------------
600
600
601 def init_hooks(self):
601 def init_hooks(self):
602 # hooks holds pointers used for user-side customizations
602 # hooks holds pointers used for user-side customizations
603 self.hooks = Struct()
603 self.hooks = Struct()
604
604
605 self.strdispatchers = {}
605 self.strdispatchers = {}
606
606
607 # Set all default hooks, defined in the IPython.hooks module.
607 # Set all default hooks, defined in the IPython.hooks module.
608 hooks = IPython.core.hooks
608 hooks = IPython.core.hooks
609 for hook_name in hooks.__all__:
609 for hook_name in hooks.__all__:
610 # default hooks have priority 100, i.e. low; user hooks should have
610 # default hooks have priority 100, i.e. low; user hooks should have
611 # 0-100 priority
611 # 0-100 priority
612 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
612 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
613
613
614 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
614 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
615 """set_hook(name,hook) -> sets an internal IPython hook.
615 """set_hook(name,hook) -> sets an internal IPython hook.
616
616
617 IPython exposes some of its internal API as user-modifiable hooks. By
617 IPython exposes some of its internal API as user-modifiable hooks. By
618 adding your function to one of these hooks, you can modify IPython's
618 adding your function to one of these hooks, you can modify IPython's
619 behavior to call at runtime your own routines."""
619 behavior to call at runtime your own routines."""
620
620
621 # At some point in the future, this should validate the hook before it
621 # At some point in the future, this should validate the hook before it
622 # accepts it. Probably at least check that the hook takes the number
622 # accepts it. Probably at least check that the hook takes the number
623 # of args it's supposed to.
623 # of args it's supposed to.
624
624
625 f = new.instancemethod(hook,self,self.__class__)
625 f = new.instancemethod(hook,self,self.__class__)
626
626
627 # check if the hook is for strdispatcher first
627 # check if the hook is for strdispatcher first
628 if str_key is not None:
628 if str_key is not None:
629 sdp = self.strdispatchers.get(name, StrDispatch())
629 sdp = self.strdispatchers.get(name, StrDispatch())
630 sdp.add_s(str_key, f, priority )
630 sdp.add_s(str_key, f, priority )
631 self.strdispatchers[name] = sdp
631 self.strdispatchers[name] = sdp
632 return
632 return
633 if re_key is not None:
633 if re_key is not None:
634 sdp = self.strdispatchers.get(name, StrDispatch())
634 sdp = self.strdispatchers.get(name, StrDispatch())
635 sdp.add_re(re.compile(re_key), f, priority )
635 sdp.add_re(re.compile(re_key), f, priority )
636 self.strdispatchers[name] = sdp
636 self.strdispatchers[name] = sdp
637 return
637 return
638
638
639 dp = getattr(self.hooks, name, None)
639 dp = getattr(self.hooks, name, None)
640 if name not in IPython.core.hooks.__all__:
640 if name not in IPython.core.hooks.__all__:
641 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
641 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
642 if not dp:
642 if not dp:
643 dp = IPython.core.hooks.CommandChainDispatcher()
643 dp = IPython.core.hooks.CommandChainDispatcher()
644
644
645 try:
645 try:
646 dp.add(f,priority)
646 dp.add(f,priority)
647 except AttributeError:
647 except AttributeError:
648 # it was not commandchain, plain old func - replace
648 # it was not commandchain, plain old func - replace
649 dp = f
649 dp = f
650
650
651 setattr(self.hooks,name, dp)
651 setattr(self.hooks,name, dp)
652
652
653 #-------------------------------------------------------------------------
653 #-------------------------------------------------------------------------
654 # Things related to the "main" module
654 # Things related to the "main" module
655 #-------------------------------------------------------------------------
655 #-------------------------------------------------------------------------
656
656
657 def new_main_mod(self,ns=None):
657 def new_main_mod(self,ns=None):
658 """Return a new 'main' module object for user code execution.
658 """Return a new 'main' module object for user code execution.
659 """
659 """
660 main_mod = self._user_main_module
660 main_mod = self._user_main_module
661 init_fakemod_dict(main_mod,ns)
661 init_fakemod_dict(main_mod,ns)
662 return main_mod
662 return main_mod
663
663
664 def cache_main_mod(self,ns,fname):
664 def cache_main_mod(self,ns,fname):
665 """Cache a main module's namespace.
665 """Cache a main module's namespace.
666
666
667 When scripts are executed via %run, we must keep a reference to the
667 When scripts are executed via %run, we must keep a reference to the
668 namespace of their __main__ module (a FakeModule instance) around so
668 namespace of their __main__ module (a FakeModule instance) around so
669 that Python doesn't clear it, rendering objects defined therein
669 that Python doesn't clear it, rendering objects defined therein
670 useless.
670 useless.
671
671
672 This method keeps said reference in a private dict, keyed by the
672 This method keeps said reference in a private dict, keyed by the
673 absolute path of the module object (which corresponds to the script
673 absolute path of the module object (which corresponds to the script
674 path). This way, for multiple executions of the same script we only
674 path). This way, for multiple executions of the same script we only
675 keep one copy of the namespace (the last one), thus preventing memory
675 keep one copy of the namespace (the last one), thus preventing memory
676 leaks from old references while allowing the objects from the last
676 leaks from old references while allowing the objects from the last
677 execution to be accessible.
677 execution to be accessible.
678
678
679 Note: we can not allow the actual FakeModule instances to be deleted,
679 Note: we can not allow the actual FakeModule instances to be deleted,
680 because of how Python tears down modules (it hard-sets all their
680 because of how Python tears down modules (it hard-sets all their
681 references to None without regard for reference counts). This method
681 references to None without regard for reference counts). This method
682 must therefore make a *copy* of the given namespace, to allow the
682 must therefore make a *copy* of the given namespace, to allow the
683 original module's __dict__ to be cleared and reused.
683 original module's __dict__ to be cleared and reused.
684
684
685
685
686 Parameters
686 Parameters
687 ----------
687 ----------
688 ns : a namespace (a dict, typically)
688 ns : a namespace (a dict, typically)
689
689
690 fname : str
690 fname : str
691 Filename associated with the namespace.
691 Filename associated with the namespace.
692
692
693 Examples
693 Examples
694 --------
694 --------
695
695
696 In [10]: import IPython
696 In [10]: import IPython
697
697
698 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
698 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
699
699
700 In [12]: IPython.__file__ in _ip._main_ns_cache
700 In [12]: IPython.__file__ in _ip._main_ns_cache
701 Out[12]: True
701 Out[12]: True
702 """
702 """
703 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
703 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
704
704
705 def clear_main_mod_cache(self):
705 def clear_main_mod_cache(self):
706 """Clear the cache of main modules.
706 """Clear the cache of main modules.
707
707
708 Mainly for use by utilities like %reset.
708 Mainly for use by utilities like %reset.
709
709
710 Examples
710 Examples
711 --------
711 --------
712
712
713 In [15]: import IPython
713 In [15]: import IPython
714
714
715 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
715 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
716
716
717 In [17]: len(_ip._main_ns_cache) > 0
717 In [17]: len(_ip._main_ns_cache) > 0
718 Out[17]: True
718 Out[17]: True
719
719
720 In [18]: _ip.clear_main_mod_cache()
720 In [18]: _ip.clear_main_mod_cache()
721
721
722 In [19]: len(_ip._main_ns_cache) == 0
722 In [19]: len(_ip._main_ns_cache) == 0
723 Out[19]: True
723 Out[19]: True
724 """
724 """
725 self._main_ns_cache.clear()
725 self._main_ns_cache.clear()
726
726
727 #-------------------------------------------------------------------------
727 #-------------------------------------------------------------------------
728 # Things related to debugging
728 # Things related to debugging
729 #-------------------------------------------------------------------------
729 #-------------------------------------------------------------------------
730
730
731 def init_pdb(self):
731 def init_pdb(self):
732 # Set calling of pdb on exceptions
732 # Set calling of pdb on exceptions
733 # self.call_pdb is a property
733 # self.call_pdb is a property
734 self.call_pdb = self.pdb
734 self.call_pdb = self.pdb
735
735
736 def _get_call_pdb(self):
736 def _get_call_pdb(self):
737 return self._call_pdb
737 return self._call_pdb
738
738
739 def _set_call_pdb(self,val):
739 def _set_call_pdb(self,val):
740
740
741 if val not in (0,1,False,True):
741 if val not in (0,1,False,True):
742 raise ValueError,'new call_pdb value must be boolean'
742 raise ValueError,'new call_pdb value must be boolean'
743
743
744 # store value in instance
744 # store value in instance
745 self._call_pdb = val
745 self._call_pdb = val
746
746
747 # notify the actual exception handlers
747 # notify the actual exception handlers
748 self.InteractiveTB.call_pdb = val
748 self.InteractiveTB.call_pdb = val
749 if self.isthreaded:
749 if self.isthreaded:
750 try:
750 try:
751 self.sys_excepthook.call_pdb = val
751 self.sys_excepthook.call_pdb = val
752 except:
752 except:
753 warn('Failed to activate pdb for threaded exception handler')
753 warn('Failed to activate pdb for threaded exception handler')
754
754
755 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
755 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
756 'Control auto-activation of pdb at exceptions')
756 'Control auto-activation of pdb at exceptions')
757
757
758 def debugger(self,force=False):
758 def debugger(self,force=False):
759 """Call the pydb/pdb debugger.
759 """Call the pydb/pdb debugger.
760
760
761 Keywords:
761 Keywords:
762
762
763 - force(False): by default, this routine checks the instance call_pdb
763 - force(False): by default, this routine checks the instance call_pdb
764 flag and does not actually invoke the debugger if the flag is false.
764 flag and does not actually invoke the debugger if the flag is false.
765 The 'force' option forces the debugger to activate even if the flag
765 The 'force' option forces the debugger to activate even if the flag
766 is false.
766 is false.
767 """
767 """
768
768
769 if not (force or self.call_pdb):
769 if not (force or self.call_pdb):
770 return
770 return
771
771
772 if not hasattr(sys,'last_traceback'):
772 if not hasattr(sys,'last_traceback'):
773 error('No traceback has been produced, nothing to debug.')
773 error('No traceback has been produced, nothing to debug.')
774 return
774 return
775
775
776 # use pydb if available
776 # use pydb if available
777 if debugger.has_pydb:
777 if debugger.has_pydb:
778 from pydb import pm
778 from pydb import pm
779 else:
779 else:
780 # fallback to our internal debugger
780 # fallback to our internal debugger
781 pm = lambda : self.InteractiveTB.debugger(force=True)
781 pm = lambda : self.InteractiveTB.debugger(force=True)
782 self.history_saving_wrapper(pm)()
782 self.history_saving_wrapper(pm)()
783
783
784 #-------------------------------------------------------------------------
784 #-------------------------------------------------------------------------
785 # Things related to IPython's various namespaces
785 # Things related to IPython's various namespaces
786 #-------------------------------------------------------------------------
786 #-------------------------------------------------------------------------
787
787
788 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
788 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
789 # Create the namespace where the user will operate. user_ns is
789 # Create the namespace where the user will operate. user_ns is
790 # normally the only one used, and it is passed to the exec calls as
790 # normally the only one used, and it is passed to the exec calls as
791 # the locals argument. But we do carry a user_global_ns namespace
791 # the locals argument. But we do carry a user_global_ns namespace
792 # given as the exec 'globals' argument, This is useful in embedding
792 # given as the exec 'globals' argument, This is useful in embedding
793 # situations where the ipython shell opens in a context where the
793 # situations where the ipython shell opens in a context where the
794 # distinction between locals and globals is meaningful. For
794 # distinction between locals and globals is meaningful. For
795 # non-embedded contexts, it is just the same object as the user_ns dict.
795 # non-embedded contexts, it is just the same object as the user_ns dict.
796
796
797 # FIXME. For some strange reason, __builtins__ is showing up at user
797 # FIXME. For some strange reason, __builtins__ is showing up at user
798 # level as a dict instead of a module. This is a manual fix, but I
798 # level as a dict instead of a module. This is a manual fix, but I
799 # should really track down where the problem is coming from. Alex
799 # should really track down where the problem is coming from. Alex
800 # Schmolck reported this problem first.
800 # Schmolck reported this problem first.
801
801
802 # A useful post by Alex Martelli on this topic:
802 # A useful post by Alex Martelli on this topic:
803 # Re: inconsistent value from __builtins__
803 # Re: inconsistent value from __builtins__
804 # Von: Alex Martelli <aleaxit@yahoo.com>
804 # Von: Alex Martelli <aleaxit@yahoo.com>
805 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
805 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
806 # Gruppen: comp.lang.python
806 # Gruppen: comp.lang.python
807
807
808 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
808 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
809 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
809 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
810 # > <type 'dict'>
810 # > <type 'dict'>
811 # > >>> print type(__builtins__)
811 # > >>> print type(__builtins__)
812 # > <type 'module'>
812 # > <type 'module'>
813 # > Is this difference in return value intentional?
813 # > Is this difference in return value intentional?
814
814
815 # Well, it's documented that '__builtins__' can be either a dictionary
815 # Well, it's documented that '__builtins__' can be either a dictionary
816 # or a module, and it's been that way for a long time. Whether it's
816 # or a module, and it's been that way for a long time. Whether it's
817 # intentional (or sensible), I don't know. In any case, the idea is
817 # intentional (or sensible), I don't know. In any case, the idea is
818 # that if you need to access the built-in namespace directly, you
818 # that if you need to access the built-in namespace directly, you
819 # should start with "import __builtin__" (note, no 's') which will
819 # should start with "import __builtin__" (note, no 's') which will
820 # definitely give you a module. Yeah, it's somewhat confusing:-(.
820 # definitely give you a module. Yeah, it's somewhat confusing:-(.
821
821
822 # These routines return properly built dicts as needed by the rest of
822 # These routines return properly built dicts as needed by the rest of
823 # the code, and can also be used by extension writers to generate
823 # the code, and can also be used by extension writers to generate
824 # properly initialized namespaces.
824 # properly initialized namespaces.
825 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
825 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
826
826
827 # Assign namespaces
827 # Assign namespaces
828 # This is the namespace where all normal user variables live
828 # This is the namespace where all normal user variables live
829 self.user_ns = user_ns
829 self.user_ns = user_ns
830 self.user_global_ns = user_global_ns
830 self.user_global_ns = user_global_ns
831
831
832 # An auxiliary namespace that checks what parts of the user_ns were
832 # An auxiliary namespace that checks what parts of the user_ns were
833 # loaded at startup, so we can list later only variables defined in
833 # loaded at startup, so we can list later only variables defined in
834 # actual interactive use. Since it is always a subset of user_ns, it
834 # actual interactive use. Since it is always a subset of user_ns, it
835 # doesn't need to be separately tracked in the ns_table.
835 # doesn't need to be separately tracked in the ns_table.
836 self.user_ns_hidden = {}
836 self.user_ns_hidden = {}
837
837
838 # A namespace to keep track of internal data structures to prevent
838 # A namespace to keep track of internal data structures to prevent
839 # them from cluttering user-visible stuff. Will be updated later
839 # them from cluttering user-visible stuff. Will be updated later
840 self.internal_ns = {}
840 self.internal_ns = {}
841
841
842 # Now that FakeModule produces a real module, we've run into a nasty
842 # Now that FakeModule produces a real module, we've run into a nasty
843 # problem: after script execution (via %run), the module where the user
843 # problem: after script execution (via %run), the module where the user
844 # code ran is deleted. Now that this object is a true module (needed
844 # code ran is deleted. Now that this object is a true module (needed
845 # so docetst and other tools work correctly), the Python module
845 # so docetst and other tools work correctly), the Python module
846 # teardown mechanism runs over it, and sets to None every variable
846 # teardown mechanism runs over it, and sets to None every variable
847 # present in that module. Top-level references to objects from the
847 # present in that module. Top-level references to objects from the
848 # script survive, because the user_ns is updated with them. However,
848 # script survive, because the user_ns is updated with them. However,
849 # calling functions defined in the script that use other things from
849 # calling functions defined in the script that use other things from
850 # the script will fail, because the function's closure had references
850 # the script will fail, because the function's closure had references
851 # to the original objects, which are now all None. So we must protect
851 # to the original objects, which are now all None. So we must protect
852 # these modules from deletion by keeping a cache.
852 # these modules from deletion by keeping a cache.
853 #
853 #
854 # To avoid keeping stale modules around (we only need the one from the
854 # To avoid keeping stale modules around (we only need the one from the
855 # last run), we use a dict keyed with the full path to the script, so
855 # last run), we use a dict keyed with the full path to the script, so
856 # only the last version of the module is held in the cache. Note,
856 # only the last version of the module is held in the cache. Note,
857 # however, that we must cache the module *namespace contents* (their
857 # however, that we must cache the module *namespace contents* (their
858 # __dict__). Because if we try to cache the actual modules, old ones
858 # __dict__). Because if we try to cache the actual modules, old ones
859 # (uncached) could be destroyed while still holding references (such as
859 # (uncached) could be destroyed while still holding references (such as
860 # those held by GUI objects that tend to be long-lived)>
860 # those held by GUI objects that tend to be long-lived)>
861 #
861 #
862 # The %reset command will flush this cache. See the cache_main_mod()
862 # The %reset command will flush this cache. See the cache_main_mod()
863 # and clear_main_mod_cache() methods for details on use.
863 # and clear_main_mod_cache() methods for details on use.
864
864
865 # This is the cache used for 'main' namespaces
865 # This is the cache used for 'main' namespaces
866 self._main_ns_cache = {}
866 self._main_ns_cache = {}
867 # And this is the single instance of FakeModule whose __dict__ we keep
867 # And this is the single instance of FakeModule whose __dict__ we keep
868 # copying and clearing for reuse on each %run
868 # copying and clearing for reuse on each %run
869 self._user_main_module = FakeModule()
869 self._user_main_module = FakeModule()
870
870
871 # A table holding all the namespaces IPython deals with, so that
871 # A table holding all the namespaces IPython deals with, so that
872 # introspection facilities can search easily.
872 # introspection facilities can search easily.
873 self.ns_table = {'user':user_ns,
873 self.ns_table = {'user':user_ns,
874 'user_global':user_global_ns,
874 'user_global':user_global_ns,
875 'internal':self.internal_ns,
875 'internal':self.internal_ns,
876 'builtin':__builtin__.__dict__
876 'builtin':__builtin__.__dict__
877 }
877 }
878
878
879 # Similarly, track all namespaces where references can be held and that
879 # Similarly, track all namespaces where references can be held and that
880 # we can safely clear (so it can NOT include builtin). This one can be
880 # we can safely clear (so it can NOT include builtin). This one can be
881 # a simple list.
881 # a simple list.
882 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
882 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
883 self.internal_ns, self._main_ns_cache ]
883 self.internal_ns, self._main_ns_cache ]
884
884
885 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
885 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
886 """Return a valid local and global user interactive namespaces.
886 """Return a valid local and global user interactive namespaces.
887
887
888 This builds a dict with the minimal information needed to operate as a
888 This builds a dict with the minimal information needed to operate as a
889 valid IPython user namespace, which you can pass to the various
889 valid IPython user namespace, which you can pass to the various
890 embedding classes in ipython. The default implementation returns the
890 embedding classes in ipython. The default implementation returns the
891 same dict for both the locals and the globals to allow functions to
891 same dict for both the locals and the globals to allow functions to
892 refer to variables in the namespace. Customized implementations can
892 refer to variables in the namespace. Customized implementations can
893 return different dicts. The locals dictionary can actually be anything
893 return different dicts. The locals dictionary can actually be anything
894 following the basic mapping protocol of a dict, but the globals dict
894 following the basic mapping protocol of a dict, but the globals dict
895 must be a true dict, not even a subclass. It is recommended that any
895 must be a true dict, not even a subclass. It is recommended that any
896 custom object for the locals namespace synchronize with the globals
896 custom object for the locals namespace synchronize with the globals
897 dict somehow.
897 dict somehow.
898
898
899 Raises TypeError if the provided globals namespace is not a true dict.
899 Raises TypeError if the provided globals namespace is not a true dict.
900
900
901 Parameters
901 Parameters
902 ----------
902 ----------
903 user_ns : dict-like, optional
903 user_ns : dict-like, optional
904 The current user namespace. The items in this namespace should
904 The current user namespace. The items in this namespace should
905 be included in the output. If None, an appropriate blank
905 be included in the output. If None, an appropriate blank
906 namespace should be created.
906 namespace should be created.
907 user_global_ns : dict, optional
907 user_global_ns : dict, optional
908 The current user global namespace. The items in this namespace
908 The current user global namespace. The items in this namespace
909 should be included in the output. If None, an appropriate
909 should be included in the output. If None, an appropriate
910 blank namespace should be created.
910 blank namespace should be created.
911
911
912 Returns
912 Returns
913 -------
913 -------
914 A pair of dictionary-like object to be used as the local namespace
914 A pair of dictionary-like object to be used as the local namespace
915 of the interpreter and a dict to be used as the global namespace.
915 of the interpreter and a dict to be used as the global namespace.
916 """
916 """
917
917
918
918
919 # We must ensure that __builtin__ (without the final 's') is always
919 # We must ensure that __builtin__ (without the final 's') is always
920 # available and pointing to the __builtin__ *module*. For more details:
920 # available and pointing to the __builtin__ *module*. For more details:
921 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
921 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
922
922
923 if user_ns is None:
923 if user_ns is None:
924 # Set __name__ to __main__ to better match the behavior of the
924 # Set __name__ to __main__ to better match the behavior of the
925 # normal interpreter.
925 # normal interpreter.
926 user_ns = {'__name__' :'__main__',
926 user_ns = {'__name__' :'__main__',
927 '__builtin__' : __builtin__,
927 '__builtin__' : __builtin__,
928 '__builtins__' : __builtin__,
928 '__builtins__' : __builtin__,
929 }
929 }
930 else:
930 else:
931 user_ns.setdefault('__name__','__main__')
931 user_ns.setdefault('__name__','__main__')
932 user_ns.setdefault('__builtin__',__builtin__)
932 user_ns.setdefault('__builtin__',__builtin__)
933 user_ns.setdefault('__builtins__',__builtin__)
933 user_ns.setdefault('__builtins__',__builtin__)
934
934
935 if user_global_ns is None:
935 if user_global_ns is None:
936 user_global_ns = user_ns
936 user_global_ns = user_ns
937 if type(user_global_ns) is not dict:
937 if type(user_global_ns) is not dict:
938 raise TypeError("user_global_ns must be a true dict; got %r"
938 raise TypeError("user_global_ns must be a true dict; got %r"
939 % type(user_global_ns))
939 % type(user_global_ns))
940
940
941 return user_ns, user_global_ns
941 return user_ns, user_global_ns
942
942
943 def init_sys_modules(self):
943 def init_sys_modules(self):
944 # We need to insert into sys.modules something that looks like a
944 # We need to insert into sys.modules something that looks like a
945 # module but which accesses the IPython namespace, for shelve and
945 # module but which accesses the IPython namespace, for shelve and
946 # pickle to work interactively. Normally they rely on getting
946 # pickle to work interactively. Normally they rely on getting
947 # everything out of __main__, but for embedding purposes each IPython
947 # everything out of __main__, but for embedding purposes each IPython
948 # instance has its own private namespace, so we can't go shoving
948 # instance has its own private namespace, so we can't go shoving
949 # everything into __main__.
949 # everything into __main__.
950
950
951 # note, however, that we should only do this for non-embedded
951 # note, however, that we should only do this for non-embedded
952 # ipythons, which really mimic the __main__.__dict__ with their own
952 # ipythons, which really mimic the __main__.__dict__ with their own
953 # namespace. Embedded instances, on the other hand, should not do
953 # namespace. Embedded instances, on the other hand, should not do
954 # this because they need to manage the user local/global namespaces
954 # this because they need to manage the user local/global namespaces
955 # only, but they live within a 'normal' __main__ (meaning, they
955 # only, but they live within a 'normal' __main__ (meaning, they
956 # shouldn't overtake the execution environment of the script they're
956 # shouldn't overtake the execution environment of the script they're
957 # embedded in).
957 # embedded in).
958
958
959 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
959 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
960
960
961 try:
961 try:
962 main_name = self.user_ns['__name__']
962 main_name = self.user_ns['__name__']
963 except KeyError:
963 except KeyError:
964 raise KeyError('user_ns dictionary MUST have a "__name__" key')
964 raise KeyError('user_ns dictionary MUST have a "__name__" key')
965 else:
965 else:
966 sys.modules[main_name] = FakeModule(self.user_ns)
966 sys.modules[main_name] = FakeModule(self.user_ns)
967
967
968 def init_user_ns(self):
968 def init_user_ns(self):
969 """Initialize all user-visible namespaces to their minimum defaults.
969 """Initialize all user-visible namespaces to their minimum defaults.
970
970
971 Certain history lists are also initialized here, as they effectively
971 Certain history lists are also initialized here, as they effectively
972 act as user namespaces.
972 act as user namespaces.
973
973
974 Notes
974 Notes
975 -----
975 -----
976 All data structures here are only filled in, they are NOT reset by this
976 All data structures here are only filled in, they are NOT reset by this
977 method. If they were not empty before, data will simply be added to
977 method. If they were not empty before, data will simply be added to
978 therm.
978 therm.
979 """
979 """
980 # This function works in two parts: first we put a few things in
980 # This function works in two parts: first we put a few things in
981 # user_ns, and we sync that contents into user_ns_hidden so that these
981 # user_ns, and we sync that contents into user_ns_hidden so that these
982 # initial variables aren't shown by %who. After the sync, we add the
982 # initial variables aren't shown by %who. After the sync, we add the
983 # rest of what we *do* want the user to see with %who even on a new
983 # rest of what we *do* want the user to see with %who even on a new
984 # session (probably nothing, so theye really only see their own stuff)
984 # session (probably nothing, so theye really only see their own stuff)
985
985
986 # The user dict must *always* have a __builtin__ reference to the
986 # The user dict must *always* have a __builtin__ reference to the
987 # Python standard __builtin__ namespace, which must be imported.
987 # Python standard __builtin__ namespace, which must be imported.
988 # This is so that certain operations in prompt evaluation can be
988 # This is so that certain operations in prompt evaluation can be
989 # reliably executed with builtins. Note that we can NOT use
989 # reliably executed with builtins. Note that we can NOT use
990 # __builtins__ (note the 's'), because that can either be a dict or a
990 # __builtins__ (note the 's'), because that can either be a dict or a
991 # module, and can even mutate at runtime, depending on the context
991 # module, and can even mutate at runtime, depending on the context
992 # (Python makes no guarantees on it). In contrast, __builtin__ is
992 # (Python makes no guarantees on it). In contrast, __builtin__ is
993 # always a module object, though it must be explicitly imported.
993 # always a module object, though it must be explicitly imported.
994
994
995 # For more details:
995 # For more details:
996 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
996 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
997 ns = dict(__builtin__ = __builtin__)
997 ns = dict(__builtin__ = __builtin__)
998
998
999 # Put 'help' in the user namespace
999 # Put 'help' in the user namespace
1000 try:
1000 try:
1001 from site import _Helper
1001 from site import _Helper
1002 ns['help'] = _Helper()
1002 ns['help'] = _Helper()
1003 except ImportError:
1003 except ImportError:
1004 warn('help() not available - check site.py')
1004 warn('help() not available - check site.py')
1005
1005
1006 # make global variables for user access to the histories
1006 # make global variables for user access to the histories
1007 ns['_ih'] = self.input_hist
1007 ns['_ih'] = self.input_hist
1008 ns['_oh'] = self.output_hist
1008 ns['_oh'] = self.output_hist
1009 ns['_dh'] = self.dir_hist
1009 ns['_dh'] = self.dir_hist
1010
1010
1011 ns['_sh'] = shadowns
1011 ns['_sh'] = shadowns
1012
1012
1013 # user aliases to input and output histories. These shouldn't show up
1013 # user aliases to input and output histories. These shouldn't show up
1014 # in %who, as they can have very large reprs.
1014 # in %who, as they can have very large reprs.
1015 ns['In'] = self.input_hist
1015 ns['In'] = self.input_hist
1016 ns['Out'] = self.output_hist
1016 ns['Out'] = self.output_hist
1017
1017
1018 # Store myself as the public api!!!
1018 # Store myself as the public api!!!
1019 ns['get_ipython'] = self.get_ipython
1019 ns['get_ipython'] = self.get_ipython
1020
1020
1021 # Sync what we've added so far to user_ns_hidden so these aren't seen
1021 # Sync what we've added so far to user_ns_hidden so these aren't seen
1022 # by %who
1022 # by %who
1023 self.user_ns_hidden.update(ns)
1023 self.user_ns_hidden.update(ns)
1024
1024
1025 # Anything put into ns now would show up in %who. Think twice before
1025 # Anything put into ns now would show up in %who. Think twice before
1026 # putting anything here, as we really want %who to show the user their
1026 # putting anything here, as we really want %who to show the user their
1027 # stuff, not our variables.
1027 # stuff, not our variables.
1028
1028
1029 # Finally, update the real user's namespace
1029 # Finally, update the real user's namespace
1030 self.user_ns.update(ns)
1030 self.user_ns.update(ns)
1031
1031
1032
1032
1033 def reset(self):
1033 def reset(self):
1034 """Clear all internal namespaces.
1034 """Clear all internal namespaces.
1035
1035
1036 Note that this is much more aggressive than %reset, since it clears
1036 Note that this is much more aggressive than %reset, since it clears
1037 fully all namespaces, as well as all input/output lists.
1037 fully all namespaces, as well as all input/output lists.
1038 """
1038 """
1039 for ns in self.ns_refs_table:
1039 for ns in self.ns_refs_table:
1040 ns.clear()
1040 ns.clear()
1041
1041
1042 self.alias_manager.clear_aliases()
1042 self.alias_manager.clear_aliases()
1043
1043
1044 # Clear input and output histories
1044 # Clear input and output histories
1045 self.input_hist[:] = []
1045 self.input_hist[:] = []
1046 self.input_hist_raw[:] = []
1046 self.input_hist_raw[:] = []
1047 self.output_hist.clear()
1047 self.output_hist.clear()
1048
1048
1049 # Restore the user namespaces to minimal usability
1049 # Restore the user namespaces to minimal usability
1050 self.init_user_ns()
1050 self.init_user_ns()
1051
1051
1052 # Restore the default and user aliases
1052 # Restore the default and user aliases
1053 self.alias_manager.init_aliases()
1053 self.alias_manager.init_aliases()
1054
1054
1055 def push(self, variables, interactive=True):
1055 def push(self, variables, interactive=True):
1056 """Inject a group of variables into the IPython user namespace.
1056 """Inject a group of variables into the IPython user namespace.
1057
1057
1058 Parameters
1058 Parameters
1059 ----------
1059 ----------
1060 variables : dict, str or list/tuple of str
1060 variables : dict, str or list/tuple of str
1061 The variables to inject into the user's namespace. If a dict,
1061 The variables to inject into the user's namespace. If a dict,
1062 a simple update is done. If a str, the string is assumed to
1062 a simple update is done. If a str, the string is assumed to
1063 have variable names separated by spaces. A list/tuple of str
1063 have variable names separated by spaces. A list/tuple of str
1064 can also be used to give the variable names. If just the variable
1064 can also be used to give the variable names. If just the variable
1065 names are give (list/tuple/str) then the variable values looked
1065 names are give (list/tuple/str) then the variable values looked
1066 up in the callers frame.
1066 up in the callers frame.
1067 interactive : bool
1067 interactive : bool
1068 If True (default), the variables will be listed with the ``who``
1068 If True (default), the variables will be listed with the ``who``
1069 magic.
1069 magic.
1070 """
1070 """
1071 vdict = None
1071 vdict = None
1072
1072
1073 # We need a dict of name/value pairs to do namespace updates.
1073 # We need a dict of name/value pairs to do namespace updates.
1074 if isinstance(variables, dict):
1074 if isinstance(variables, dict):
1075 vdict = variables
1075 vdict = variables
1076 elif isinstance(variables, (basestring, list, tuple)):
1076 elif isinstance(variables, (basestring, list, tuple)):
1077 if isinstance(variables, basestring):
1077 if isinstance(variables, basestring):
1078 vlist = variables.split()
1078 vlist = variables.split()
1079 else:
1079 else:
1080 vlist = variables
1080 vlist = variables
1081 vdict = {}
1081 vdict = {}
1082 cf = sys._getframe(1)
1082 cf = sys._getframe(1)
1083 for name in vlist:
1083 for name in vlist:
1084 try:
1084 try:
1085 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1085 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1086 except:
1086 except:
1087 print ('Could not get variable %s from %s' %
1087 print ('Could not get variable %s from %s' %
1088 (name,cf.f_code.co_name))
1088 (name,cf.f_code.co_name))
1089 else:
1089 else:
1090 raise ValueError('variables must be a dict/str/list/tuple')
1090 raise ValueError('variables must be a dict/str/list/tuple')
1091
1091
1092 # Propagate variables to user namespace
1092 # Propagate variables to user namespace
1093 self.user_ns.update(vdict)
1093 self.user_ns.update(vdict)
1094
1094
1095 # And configure interactive visibility
1095 # And configure interactive visibility
1096 config_ns = self.user_ns_hidden
1096 config_ns = self.user_ns_hidden
1097 if interactive:
1097 if interactive:
1098 for name, val in vdict.iteritems():
1098 for name, val in vdict.iteritems():
1099 config_ns.pop(name, None)
1099 config_ns.pop(name, None)
1100 else:
1100 else:
1101 for name,val in vdict.iteritems():
1101 for name,val in vdict.iteritems():
1102 config_ns[name] = val
1102 config_ns[name] = val
1103
1103
1104 #-------------------------------------------------------------------------
1104 #-------------------------------------------------------------------------
1105 # Things related to history management
1105 # Things related to history management
1106 #-------------------------------------------------------------------------
1106 #-------------------------------------------------------------------------
1107
1107
1108 def init_history(self):
1108 def init_history(self):
1109 # List of input with multi-line handling.
1109 # List of input with multi-line handling.
1110 self.input_hist = InputList()
1110 self.input_hist = InputList()
1111 # This one will hold the 'raw' input history, without any
1111 # This one will hold the 'raw' input history, without any
1112 # pre-processing. This will allow users to retrieve the input just as
1112 # pre-processing. This will allow users to retrieve the input just as
1113 # it was exactly typed in by the user, with %hist -r.
1113 # it was exactly typed in by the user, with %hist -r.
1114 self.input_hist_raw = InputList()
1114 self.input_hist_raw = InputList()
1115
1115
1116 # list of visited directories
1116 # list of visited directories
1117 try:
1117 try:
1118 self.dir_hist = [os.getcwd()]
1118 self.dir_hist = [os.getcwd()]
1119 except OSError:
1119 except OSError:
1120 self.dir_hist = []
1120 self.dir_hist = []
1121
1121
1122 # dict of output history
1122 # dict of output history
1123 self.output_hist = {}
1123 self.output_hist = {}
1124
1124
1125 # Now the history file
1125 # Now the history file
1126 if self.profile:
1126 if self.profile:
1127 histfname = 'history-%s' % self.profile
1127 histfname = 'history-%s' % self.profile
1128 else:
1128 else:
1129 histfname = 'history'
1129 histfname = 'history'
1130 self.histfile = os.path.join(self.ipython_dir, histfname)
1130 self.histfile = os.path.join(self.ipython_dir, histfname)
1131
1131
1132 # Fill the history zero entry, user counter starts at 1
1132 # Fill the history zero entry, user counter starts at 1
1133 self.input_hist.append('\n')
1133 self.input_hist.append('\n')
1134 self.input_hist_raw.append('\n')
1134 self.input_hist_raw.append('\n')
1135
1135
1136 def init_shadow_hist(self):
1136 def init_shadow_hist(self):
1137 try:
1137 try:
1138 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1138 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1139 except exceptions.UnicodeDecodeError:
1139 except exceptions.UnicodeDecodeError:
1140 print "Your ipython_dir can't be decoded to unicode!"
1140 print "Your ipython_dir can't be decoded to unicode!"
1141 print "Please set HOME environment variable to something that"
1141 print "Please set HOME environment variable to something that"
1142 print r"only has ASCII characters, e.g. c:\home"
1142 print r"only has ASCII characters, e.g. c:\home"
1143 print "Now it is", self.ipython_dir
1143 print "Now it is", self.ipython_dir
1144 sys.exit()
1144 sys.exit()
1145 self.shadowhist = ipcorehist.ShadowHist(self.db)
1145 self.shadowhist = ipcorehist.ShadowHist(self.db)
1146
1146
1147 def savehist(self):
1147 def savehist(self):
1148 """Save input history to a file (via readline library)."""
1148 """Save input history to a file (via readline library)."""
1149
1149
1150 try:
1150 try:
1151 self.readline.write_history_file(self.histfile)
1151 self.readline.write_history_file(self.histfile)
1152 except:
1152 except:
1153 print 'Unable to save IPython command history to file: ' + \
1153 print 'Unable to save IPython command history to file: ' + \
1154 `self.histfile`
1154 `self.histfile`
1155
1155
1156 def reloadhist(self):
1156 def reloadhist(self):
1157 """Reload the input history from disk file."""
1157 """Reload the input history from disk file."""
1158
1158
1159 try:
1159 try:
1160 self.readline.clear_history()
1160 self.readline.clear_history()
1161 self.readline.read_history_file(self.shell.histfile)
1161 self.readline.read_history_file(self.shell.histfile)
1162 except AttributeError:
1162 except AttributeError:
1163 pass
1163 pass
1164
1164
1165 def history_saving_wrapper(self, func):
1165 def history_saving_wrapper(self, func):
1166 """ Wrap func for readline history saving
1166 """ Wrap func for readline history saving
1167
1167
1168 Convert func into callable that saves & restores
1168 Convert func into callable that saves & restores
1169 history around the call """
1169 history around the call """
1170
1170
1171 if self.has_readline:
1171 if self.has_readline:
1172 from IPython.utils import rlineimpl as readline
1172 from IPython.utils import rlineimpl as readline
1173 else:
1173 else:
1174 return func
1174 return func
1175
1175
1176 def wrapper():
1176 def wrapper():
1177 self.savehist()
1177 self.savehist()
1178 try:
1178 try:
1179 func()
1179 func()
1180 finally:
1180 finally:
1181 readline.read_history_file(self.histfile)
1181 readline.read_history_file(self.histfile)
1182 return wrapper
1182 return wrapper
1183
1183
1184 #-------------------------------------------------------------------------
1184 #-------------------------------------------------------------------------
1185 # Things related to exception handling and tracebacks (not debugging)
1185 # Things related to exception handling and tracebacks (not debugging)
1186 #-------------------------------------------------------------------------
1186 #-------------------------------------------------------------------------
1187
1187
1188 def init_traceback_handlers(self, custom_exceptions):
1188 def init_traceback_handlers(self, custom_exceptions):
1189 # Syntax error handler.
1189 # Syntax error handler.
1190 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1190 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1191
1191
1192 # The interactive one is initialized with an offset, meaning we always
1192 # The interactive one is initialized with an offset, meaning we always
1193 # want to remove the topmost item in the traceback, which is our own
1193 # want to remove the topmost item in the traceback, which is our own
1194 # internal code. Valid modes: ['Plain','Context','Verbose']
1194 # internal code. Valid modes: ['Plain','Context','Verbose']
1195 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1195 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1196 color_scheme='NoColor',
1196 color_scheme='NoColor',
1197 tb_offset = 1)
1197 tb_offset = 1)
1198
1198
1199 # The instance will store a pointer to the system-wide exception hook,
1199 # The instance will store a pointer to the system-wide exception hook,
1200 # so that runtime code (such as magics) can access it. This is because
1200 # so that runtime code (such as magics) can access it. This is because
1201 # during the read-eval loop, it may get temporarily overwritten.
1201 # during the read-eval loop, it may get temporarily overwritten.
1202 self.sys_excepthook = sys.excepthook
1202 self.sys_excepthook = sys.excepthook
1203
1203
1204 # and add any custom exception handlers the user may have specified
1204 # and add any custom exception handlers the user may have specified
1205 self.set_custom_exc(*custom_exceptions)
1205 self.set_custom_exc(*custom_exceptions)
1206
1206
1207 # Set the exception mode
1207 # Set the exception mode
1208 self.InteractiveTB.set_mode(mode=self.xmode)
1208 self.InteractiveTB.set_mode(mode=self.xmode)
1209
1209
1210 def set_custom_exc(self,exc_tuple,handler):
1210 def set_custom_exc(self,exc_tuple,handler):
1211 """set_custom_exc(exc_tuple,handler)
1211 """set_custom_exc(exc_tuple,handler)
1212
1212
1213 Set a custom exception handler, which will be called if any of the
1213 Set a custom exception handler, which will be called if any of the
1214 exceptions in exc_tuple occur in the mainloop (specifically, in the
1214 exceptions in exc_tuple occur in the mainloop (specifically, in the
1215 runcode() method.
1215 runcode() method.
1216
1216
1217 Inputs:
1217 Inputs:
1218
1218
1219 - exc_tuple: a *tuple* of valid exceptions to call the defined
1219 - exc_tuple: a *tuple* of valid exceptions to call the defined
1220 handler for. It is very important that you use a tuple, and NOT A
1220 handler for. It is very important that you use a tuple, and NOT A
1221 LIST here, because of the way Python's except statement works. If
1221 LIST here, because of the way Python's except statement works. If
1222 you only want to trap a single exception, use a singleton tuple:
1222 you only want to trap a single exception, use a singleton tuple:
1223
1223
1224 exc_tuple == (MyCustomException,)
1224 exc_tuple == (MyCustomException,)
1225
1225
1226 - handler: this must be defined as a function with the following
1226 - handler: this must be defined as a function with the following
1227 basic interface: def my_handler(self,etype,value,tb).
1227 basic interface: def my_handler(self,etype,value,tb).
1228
1228
1229 This will be made into an instance method (via new.instancemethod)
1229 This will be made into an instance method (via new.instancemethod)
1230 of IPython itself, and it will be called if any of the exceptions
1230 of IPython itself, and it will be called if any of the exceptions
1231 listed in the exc_tuple are caught. If the handler is None, an
1231 listed in the exc_tuple are caught. If the handler is None, an
1232 internal basic one is used, which just prints basic info.
1232 internal basic one is used, which just prints basic info.
1233
1233
1234 WARNING: by putting in your own exception handler into IPython's main
1234 WARNING: by putting in your own exception handler into IPython's main
1235 execution loop, you run a very good chance of nasty crashes. This
1235 execution loop, you run a very good chance of nasty crashes. This
1236 facility should only be used if you really know what you are doing."""
1236 facility should only be used if you really know what you are doing."""
1237
1237
1238 assert type(exc_tuple)==type(()) , \
1238 assert type(exc_tuple)==type(()) , \
1239 "The custom exceptions must be given AS A TUPLE."
1239 "The custom exceptions must be given AS A TUPLE."
1240
1240
1241 def dummy_handler(self,etype,value,tb):
1241 def dummy_handler(self,etype,value,tb):
1242 print '*** Simple custom exception handler ***'
1242 print '*** Simple custom exception handler ***'
1243 print 'Exception type :',etype
1243 print 'Exception type :',etype
1244 print 'Exception value:',value
1244 print 'Exception value:',value
1245 print 'Traceback :',tb
1245 print 'Traceback :',tb
1246 print 'Source code :','\n'.join(self.buffer)
1246 print 'Source code :','\n'.join(self.buffer)
1247
1247
1248 if handler is None: handler = dummy_handler
1248 if handler is None: handler = dummy_handler
1249
1249
1250 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1250 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1251 self.custom_exceptions = exc_tuple
1251 self.custom_exceptions = exc_tuple
1252
1252
1253 def excepthook(self, etype, value, tb):
1253 def excepthook(self, etype, value, tb):
1254 """One more defense for GUI apps that call sys.excepthook.
1254 """One more defense for GUI apps that call sys.excepthook.
1255
1255
1256 GUI frameworks like wxPython trap exceptions and call
1256 GUI frameworks like wxPython trap exceptions and call
1257 sys.excepthook themselves. I guess this is a feature that
1257 sys.excepthook themselves. I guess this is a feature that
1258 enables them to keep running after exceptions that would
1258 enables them to keep running after exceptions that would
1259 otherwise kill their mainloop. This is a bother for IPython
1259 otherwise kill their mainloop. This is a bother for IPython
1260 which excepts to catch all of the program exceptions with a try:
1260 which excepts to catch all of the program exceptions with a try:
1261 except: statement.
1261 except: statement.
1262
1262
1263 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1263 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1264 any app directly invokes sys.excepthook, it will look to the user like
1264 any app directly invokes sys.excepthook, it will look to the user like
1265 IPython crashed. In order to work around this, we can disable the
1265 IPython crashed. In order to work around this, we can disable the
1266 CrashHandler and replace it with this excepthook instead, which prints a
1266 CrashHandler and replace it with this excepthook instead, which prints a
1267 regular traceback using our InteractiveTB. In this fashion, apps which
1267 regular traceback using our InteractiveTB. In this fashion, apps which
1268 call sys.excepthook will generate a regular-looking exception from
1268 call sys.excepthook will generate a regular-looking exception from
1269 IPython, and the CrashHandler will only be triggered by real IPython
1269 IPython, and the CrashHandler will only be triggered by real IPython
1270 crashes.
1270 crashes.
1271
1271
1272 This hook should be used sparingly, only in places which are not likely
1272 This hook should be used sparingly, only in places which are not likely
1273 to be true IPython errors.
1273 to be true IPython errors.
1274 """
1274 """
1275 self.showtraceback((etype,value,tb),tb_offset=0)
1275 self.showtraceback((etype,value,tb),tb_offset=0)
1276
1276
1277 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1277 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1278 exception_only=False):
1278 exception_only=False):
1279 """Display the exception that just occurred.
1279 """Display the exception that just occurred.
1280
1280
1281 If nothing is known about the exception, this is the method which
1281 If nothing is known about the exception, this is the method which
1282 should be used throughout the code for presenting user tracebacks,
1282 should be used throughout the code for presenting user tracebacks,
1283 rather than directly invoking the InteractiveTB object.
1283 rather than directly invoking the InteractiveTB object.
1284
1284
1285 A specific showsyntaxerror() also exists, but this method can take
1285 A specific showsyntaxerror() also exists, but this method can take
1286 care of calling it if needed, so unless you are explicitly catching a
1286 care of calling it if needed, so unless you are explicitly catching a
1287 SyntaxError exception, don't try to analyze the stack manually and
1287 SyntaxError exception, don't try to analyze the stack manually and
1288 simply call this method."""
1288 simply call this method."""
1289
1289
1290 try:
1290 try:
1291 if exc_tuple is None:
1291 if exc_tuple is None:
1292 etype, value, tb = sys.exc_info()
1292 etype, value, tb = sys.exc_info()
1293 else:
1293 else:
1294 etype, value, tb = exc_tuple
1294 etype, value, tb = exc_tuple
1295
1295
1296 if etype is None:
1296 if etype is None:
1297 if hasattr(sys, 'last_type'):
1297 if hasattr(sys, 'last_type'):
1298 etype, value, tb = sys.last_type, sys.last_value, \
1298 etype, value, tb = sys.last_type, sys.last_value, \
1299 sys.last_traceback
1299 sys.last_traceback
1300 else:
1300 else:
1301 self.write('No traceback available to show.\n')
1301 self.write('No traceback available to show.\n')
1302 return
1302 return
1303
1303
1304 if etype is SyntaxError:
1304 if etype is SyntaxError:
1305 # Though this won't be called by syntax errors in the input
1305 # Though this won't be called by syntax errors in the input
1306 # line, there may be SyntaxError cases whith imported code.
1306 # line, there may be SyntaxError cases whith imported code.
1307 self.showsyntaxerror(filename)
1307 self.showsyntaxerror(filename)
1308 elif etype is UsageError:
1308 elif etype is UsageError:
1309 print "UsageError:", value
1309 print "UsageError:", value
1310 else:
1310 else:
1311 # WARNING: these variables are somewhat deprecated and not
1311 # WARNING: these variables are somewhat deprecated and not
1312 # necessarily safe to use in a threaded environment, but tools
1312 # necessarily safe to use in a threaded environment, but tools
1313 # like pdb depend on their existence, so let's set them. If we
1313 # like pdb depend on their existence, so let's set them. If we
1314 # find problems in the field, we'll need to revisit their use.
1314 # find problems in the field, we'll need to revisit their use.
1315 sys.last_type = etype
1315 sys.last_type = etype
1316 sys.last_value = value
1316 sys.last_value = value
1317 sys.last_traceback = tb
1317 sys.last_traceback = tb
1318
1318
1319 if etype in self.custom_exceptions:
1319 if etype in self.custom_exceptions:
1320 self.CustomTB(etype,value,tb)
1320 self.CustomTB(etype,value,tb)
1321 else:
1321 else:
1322 if exception_only:
1322 if exception_only:
1323 m = ('An exception has occurred, use %tb to see the '
1323 m = ('An exception has occurred, use %tb to see the '
1324 'full traceback.')
1324 'full traceback.')
1325 print m
1325 print m
1326 self.InteractiveTB.show_exception_only(etype, value)
1326 self.InteractiveTB.show_exception_only(etype, value)
1327 else:
1327 else:
1328 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1328 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1329 if self.InteractiveTB.call_pdb:
1329 if self.InteractiveTB.call_pdb:
1330 # pdb mucks up readline, fix it back
1330 # pdb mucks up readline, fix it back
1331 self.set_completer()
1331 self.set_completer()
1332
1332
1333 except KeyboardInterrupt:
1333 except KeyboardInterrupt:
1334 self.write("\nKeyboardInterrupt\n")
1334 self.write("\nKeyboardInterrupt\n")
1335
1335
1336
1336
1337 def showsyntaxerror(self, filename=None):
1337 def showsyntaxerror(self, filename=None):
1338 """Display the syntax error that just occurred.
1338 """Display the syntax error that just occurred.
1339
1339
1340 This doesn't display a stack trace because there isn't one.
1340 This doesn't display a stack trace because there isn't one.
1341
1341
1342 If a filename is given, it is stuffed in the exception instead
1342 If a filename is given, it is stuffed in the exception instead
1343 of what was there before (because Python's parser always uses
1343 of what was there before (because Python's parser always uses
1344 "<string>" when reading from a string).
1344 "<string>" when reading from a string).
1345 """
1345 """
1346 etype, value, last_traceback = sys.exc_info()
1346 etype, value, last_traceback = sys.exc_info()
1347
1347
1348 # See note about these variables in showtraceback() above
1348 # See note about these variables in showtraceback() above
1349 sys.last_type = etype
1349 sys.last_type = etype
1350 sys.last_value = value
1350 sys.last_value = value
1351 sys.last_traceback = last_traceback
1351 sys.last_traceback = last_traceback
1352
1352
1353 if filename and etype is SyntaxError:
1353 if filename and etype is SyntaxError:
1354 # Work hard to stuff the correct filename in the exception
1354 # Work hard to stuff the correct filename in the exception
1355 try:
1355 try:
1356 msg, (dummy_filename, lineno, offset, line) = value
1356 msg, (dummy_filename, lineno, offset, line) = value
1357 except:
1357 except:
1358 # Not the format we expect; leave it alone
1358 # Not the format we expect; leave it alone
1359 pass
1359 pass
1360 else:
1360 else:
1361 # Stuff in the right filename
1361 # Stuff in the right filename
1362 try:
1362 try:
1363 # Assume SyntaxError is a class exception
1363 # Assume SyntaxError is a class exception
1364 value = SyntaxError(msg, (filename, lineno, offset, line))
1364 value = SyntaxError(msg, (filename, lineno, offset, line))
1365 except:
1365 except:
1366 # If that failed, assume SyntaxError is a string
1366 # If that failed, assume SyntaxError is a string
1367 value = msg, (filename, lineno, offset, line)
1367 value = msg, (filename, lineno, offset, line)
1368 self.SyntaxTB(etype,value,[])
1368 self.SyntaxTB(etype,value,[])
1369
1369
1370 def edit_syntax_error(self):
1370 def edit_syntax_error(self):
1371 """The bottom half of the syntax error handler called in the main loop.
1371 """The bottom half of the syntax error handler called in the main loop.
1372
1372
1373 Loop until syntax error is fixed or user cancels.
1373 Loop until syntax error is fixed or user cancels.
1374 """
1374 """
1375
1375
1376 while self.SyntaxTB.last_syntax_error:
1376 while self.SyntaxTB.last_syntax_error:
1377 # copy and clear last_syntax_error
1377 # copy and clear last_syntax_error
1378 err = self.SyntaxTB.clear_err_state()
1378 err = self.SyntaxTB.clear_err_state()
1379 if not self._should_recompile(err):
1379 if not self._should_recompile(err):
1380 return
1380 return
1381 try:
1381 try:
1382 # may set last_syntax_error again if a SyntaxError is raised
1382 # may set last_syntax_error again if a SyntaxError is raised
1383 self.safe_execfile(err.filename,self.user_ns)
1383 self.safe_execfile(err.filename,self.user_ns)
1384 except:
1384 except:
1385 self.showtraceback()
1385 self.showtraceback()
1386 else:
1386 else:
1387 try:
1387 try:
1388 f = file(err.filename)
1388 f = file(err.filename)
1389 try:
1389 try:
1390 # This should be inside a display_trap block and I
1390 # This should be inside a display_trap block and I
1391 # think it is.
1391 # think it is.
1392 sys.displayhook(f.read())
1392 sys.displayhook(f.read())
1393 finally:
1393 finally:
1394 f.close()
1394 f.close()
1395 except:
1395 except:
1396 self.showtraceback()
1396 self.showtraceback()
1397
1397
1398 def _should_recompile(self,e):
1398 def _should_recompile(self,e):
1399 """Utility routine for edit_syntax_error"""
1399 """Utility routine for edit_syntax_error"""
1400
1400
1401 if e.filename in ('<ipython console>','<input>','<string>',
1401 if e.filename in ('<ipython console>','<input>','<string>',
1402 '<console>','<BackgroundJob compilation>',
1402 '<console>','<BackgroundJob compilation>',
1403 None):
1403 None):
1404
1404
1405 return False
1405 return False
1406 try:
1406 try:
1407 if (self.autoedit_syntax and
1407 if (self.autoedit_syntax and
1408 not self.ask_yes_no('Return to editor to correct syntax error? '
1408 not self.ask_yes_no('Return to editor to correct syntax error? '
1409 '[Y/n] ','y')):
1409 '[Y/n] ','y')):
1410 return False
1410 return False
1411 except EOFError:
1411 except EOFError:
1412 return False
1412 return False
1413
1413
1414 def int0(x):
1414 def int0(x):
1415 try:
1415 try:
1416 return int(x)
1416 return int(x)
1417 except TypeError:
1417 except TypeError:
1418 return 0
1418 return 0
1419 # always pass integer line and offset values to editor hook
1419 # always pass integer line and offset values to editor hook
1420 try:
1420 try:
1421 self.hooks.fix_error_editor(e.filename,
1421 self.hooks.fix_error_editor(e.filename,
1422 int0(e.lineno),int0(e.offset),e.msg)
1422 int0(e.lineno),int0(e.offset),e.msg)
1423 except TryNext:
1423 except TryNext:
1424 warn('Could not open editor')
1424 warn('Could not open editor')
1425 return False
1425 return False
1426 return True
1426 return True
1427
1427
1428 #-------------------------------------------------------------------------
1428 #-------------------------------------------------------------------------
1429 # Things related to tab completion
1429 # Things related to tab completion
1430 #-------------------------------------------------------------------------
1430 #-------------------------------------------------------------------------
1431
1431
1432 def complete(self, text):
1432 def complete(self, text):
1433 """Return a sorted list of all possible completions on text.
1433 """Return a sorted list of all possible completions on text.
1434
1434
1435 Inputs:
1435 Inputs:
1436
1436
1437 - text: a string of text to be completed on.
1437 - text: a string of text to be completed on.
1438
1438
1439 This is a wrapper around the completion mechanism, similar to what
1439 This is a wrapper around the completion mechanism, similar to what
1440 readline does at the command line when the TAB key is hit. By
1440 readline does at the command line when the TAB key is hit. By
1441 exposing it as a method, it can be used by other non-readline
1441 exposing it as a method, it can be used by other non-readline
1442 environments (such as GUIs) for text completion.
1442 environments (such as GUIs) for text completion.
1443
1443
1444 Simple usage example:
1444 Simple usage example:
1445
1445
1446 In [7]: x = 'hello'
1446 In [7]: x = 'hello'
1447
1447
1448 In [8]: x
1448 In [8]: x
1449 Out[8]: 'hello'
1449 Out[8]: 'hello'
1450
1450
1451 In [9]: print x
1451 In [9]: print x
1452 hello
1452 hello
1453
1453
1454 In [10]: _ip.complete('x.l')
1454 In [10]: _ip.complete('x.l')
1455 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1455 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1456 """
1456 """
1457
1457
1458 # Inject names into __builtin__ so we can complete on the added names.
1458 # Inject names into __builtin__ so we can complete on the added names.
1459 with self.builtin_trap:
1459 with self.builtin_trap:
1460 complete = self.Completer.complete
1460 complete = self.Completer.complete
1461 state = 0
1461 state = 0
1462 # use a dict so we get unique keys, since ipyhton's multiple
1462 # use a dict so we get unique keys, since ipyhton's multiple
1463 # completers can return duplicates. When we make 2.4 a requirement,
1463 # completers can return duplicates. When we make 2.4 a requirement,
1464 # start using sets instead, which are faster.
1464 # start using sets instead, which are faster.
1465 comps = {}
1465 comps = {}
1466 while True:
1466 while True:
1467 newcomp = complete(text,state,line_buffer=text)
1467 newcomp = complete(text,state,line_buffer=text)
1468 if newcomp is None:
1468 if newcomp is None:
1469 break
1469 break
1470 comps[newcomp] = 1
1470 comps[newcomp] = 1
1471 state += 1
1471 state += 1
1472 outcomps = comps.keys()
1472 outcomps = comps.keys()
1473 outcomps.sort()
1473 outcomps.sort()
1474 #print "T:",text,"OC:",outcomps # dbg
1474 #print "T:",text,"OC:",outcomps # dbg
1475 #print "vars:",self.user_ns.keys()
1475 #print "vars:",self.user_ns.keys()
1476 return outcomps
1476 return outcomps
1477
1477
1478 def set_custom_completer(self,completer,pos=0):
1478 def set_custom_completer(self,completer,pos=0):
1479 """Adds a new custom completer function.
1479 """Adds a new custom completer function.
1480
1480
1481 The position argument (defaults to 0) is the index in the completers
1481 The position argument (defaults to 0) is the index in the completers
1482 list where you want the completer to be inserted."""
1482 list where you want the completer to be inserted."""
1483
1483
1484 newcomp = new.instancemethod(completer,self.Completer,
1484 newcomp = new.instancemethod(completer,self.Completer,
1485 self.Completer.__class__)
1485 self.Completer.__class__)
1486 self.Completer.matchers.insert(pos,newcomp)
1486 self.Completer.matchers.insert(pos,newcomp)
1487
1487
1488 def set_completer(self):
1488 def set_completer(self):
1489 """Reset readline's completer to be our own."""
1489 """Reset readline's completer to be our own."""
1490 self.readline.set_completer(self.Completer.complete)
1490 self.readline.set_completer(self.Completer.complete)
1491
1491
1492 def set_completer_frame(self, frame=None):
1492 def set_completer_frame(self, frame=None):
1493 """Set the frame of the completer."""
1493 """Set the frame of the completer."""
1494 if frame:
1494 if frame:
1495 self.Completer.namespace = frame.f_locals
1495 self.Completer.namespace = frame.f_locals
1496 self.Completer.global_namespace = frame.f_globals
1496 self.Completer.global_namespace = frame.f_globals
1497 else:
1497 else:
1498 self.Completer.namespace = self.user_ns
1498 self.Completer.namespace = self.user_ns
1499 self.Completer.global_namespace = self.user_global_ns
1499 self.Completer.global_namespace = self.user_global_ns
1500
1500
1501 #-------------------------------------------------------------------------
1501 #-------------------------------------------------------------------------
1502 # Things related to readline
1502 # Things related to readline
1503 #-------------------------------------------------------------------------
1503 #-------------------------------------------------------------------------
1504
1504
1505 def init_readline(self):
1505 def init_readline(self):
1506 """Command history completion/saving/reloading."""
1506 """Command history completion/saving/reloading."""
1507
1507
1508 if self.readline_use:
1508 if self.readline_use:
1509 import IPython.utils.rlineimpl as readline
1509 import IPython.utils.rlineimpl as readline
1510
1510
1511 self.rl_next_input = None
1511 self.rl_next_input = None
1512 self.rl_do_indent = False
1512 self.rl_do_indent = False
1513
1513
1514 if not self.readline_use or not readline.have_readline:
1514 if not self.readline_use or not readline.have_readline:
1515 self.has_readline = False
1515 self.has_readline = False
1516 self.readline = None
1516 self.readline = None
1517 # Set a number of methods that depend on readline to be no-op
1517 # Set a number of methods that depend on readline to be no-op
1518 self.savehist = no_op
1518 self.savehist = no_op
1519 self.reloadhist = no_op
1519 self.reloadhist = no_op
1520 self.set_completer = no_op
1520 self.set_completer = no_op
1521 self.set_custom_completer = no_op
1521 self.set_custom_completer = no_op
1522 self.set_completer_frame = no_op
1522 self.set_completer_frame = no_op
1523 warn('Readline services not available or not loaded.')
1523 warn('Readline services not available or not loaded.')
1524 else:
1524 else:
1525 self.has_readline = True
1525 self.has_readline = True
1526 self.readline = readline
1526 self.readline = readline
1527 sys.modules['readline'] = readline
1527 sys.modules['readline'] = readline
1528 import atexit
1528 import atexit
1529 from IPython.core.completer import IPCompleter
1529 from IPython.core.completer import IPCompleter
1530 self.Completer = IPCompleter(self,
1530 self.Completer = IPCompleter(self,
1531 self.user_ns,
1531 self.user_ns,
1532 self.user_global_ns,
1532 self.user_global_ns,
1533 self.readline_omit__names,
1533 self.readline_omit__names,
1534 self.alias_manager.alias_table)
1534 self.alias_manager.alias_table)
1535 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1535 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1536 self.strdispatchers['complete_command'] = sdisp
1536 self.strdispatchers['complete_command'] = sdisp
1537 self.Completer.custom_completers = sdisp
1537 self.Completer.custom_completers = sdisp
1538 # Platform-specific configuration
1538 # Platform-specific configuration
1539 if os.name == 'nt':
1539 if os.name == 'nt':
1540 self.readline_startup_hook = readline.set_pre_input_hook
1540 self.readline_startup_hook = readline.set_pre_input_hook
1541 else:
1541 else:
1542 self.readline_startup_hook = readline.set_startup_hook
1542 self.readline_startup_hook = readline.set_startup_hook
1543
1543
1544 # Load user's initrc file (readline config)
1544 # Load user's initrc file (readline config)
1545 # Or if libedit is used, load editrc.
1545 # Or if libedit is used, load editrc.
1546 inputrc_name = os.environ.get('INPUTRC')
1546 inputrc_name = os.environ.get('INPUTRC')
1547 if inputrc_name is None:
1547 if inputrc_name is None:
1548 home_dir = get_home_dir()
1548 home_dir = get_home_dir()
1549 if home_dir is not None:
1549 if home_dir is not None:
1550 inputrc_name = '.inputrc'
1550 inputrc_name = '.inputrc'
1551 if readline.uses_libedit:
1551 if readline.uses_libedit:
1552 inputrc_name = '.editrc'
1552 inputrc_name = '.editrc'
1553 inputrc_name = os.path.join(home_dir, inputrc_name)
1553 inputrc_name = os.path.join(home_dir, inputrc_name)
1554 if os.path.isfile(inputrc_name):
1554 if os.path.isfile(inputrc_name):
1555 try:
1555 try:
1556 readline.read_init_file(inputrc_name)
1556 readline.read_init_file(inputrc_name)
1557 except:
1557 except:
1558 warn('Problems reading readline initialization file <%s>'
1558 warn('Problems reading readline initialization file <%s>'
1559 % inputrc_name)
1559 % inputrc_name)
1560
1560
1561 # save this in sys so embedded copies can restore it properly
1561 # save this in sys so embedded copies can restore it properly
1562 sys.ipcompleter = self.Completer.complete
1562 sys.ipcompleter = self.Completer.complete
1563 self.set_completer()
1563 self.set_completer()
1564
1564
1565 # Configure readline according to user's prefs
1565 # Configure readline according to user's prefs
1566 # This is only done if GNU readline is being used. If libedit
1566 # This is only done if GNU readline is being used. If libedit
1567 # is being used (as on Leopard) the readline config is
1567 # is being used (as on Leopard) the readline config is
1568 # not run as the syntax for libedit is different.
1568 # not run as the syntax for libedit is different.
1569 if not readline.uses_libedit:
1569 if not readline.uses_libedit:
1570 for rlcommand in self.readline_parse_and_bind:
1570 for rlcommand in self.readline_parse_and_bind:
1571 #print "loading rl:",rlcommand # dbg
1571 #print "loading rl:",rlcommand # dbg
1572 readline.parse_and_bind(rlcommand)
1572 readline.parse_and_bind(rlcommand)
1573
1573
1574 # Remove some chars from the delimiters list. If we encounter
1574 # Remove some chars from the delimiters list. If we encounter
1575 # unicode chars, discard them.
1575 # unicode chars, discard them.
1576 delims = readline.get_completer_delims().encode("ascii", "ignore")
1576 delims = readline.get_completer_delims().encode("ascii", "ignore")
1577 delims = delims.translate(string._idmap,
1577 delims = delims.translate(string._idmap,
1578 self.readline_remove_delims)
1578 self.readline_remove_delims)
1579 readline.set_completer_delims(delims)
1579 readline.set_completer_delims(delims)
1580 # otherwise we end up with a monster history after a while:
1580 # otherwise we end up with a monster history after a while:
1581 readline.set_history_length(1000)
1581 readline.set_history_length(1000)
1582 try:
1582 try:
1583 #print '*** Reading readline history' # dbg
1583 #print '*** Reading readline history' # dbg
1584 readline.read_history_file(self.histfile)
1584 readline.read_history_file(self.histfile)
1585 except IOError:
1585 except IOError:
1586 pass # It doesn't exist yet.
1586 pass # It doesn't exist yet.
1587
1587
1588 atexit.register(self.atexit_operations)
1588 atexit.register(self.atexit_operations)
1589 del atexit
1589 del atexit
1590
1590
1591 # Configure auto-indent for all platforms
1591 # Configure auto-indent for all platforms
1592 self.set_autoindent(self.autoindent)
1592 self.set_autoindent(self.autoindent)
1593
1593
1594 def set_next_input(self, s):
1594 def set_next_input(self, s):
1595 """ Sets the 'default' input string for the next command line.
1595 """ Sets the 'default' input string for the next command line.
1596
1596
1597 Requires readline.
1597 Requires readline.
1598
1598
1599 Example:
1599 Example:
1600
1600
1601 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1601 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1602 [D:\ipython]|2> Hello Word_ # cursor is here
1602 [D:\ipython]|2> Hello Word_ # cursor is here
1603 """
1603 """
1604
1604
1605 self.rl_next_input = s
1605 self.rl_next_input = s
1606
1606
1607 def pre_readline(self):
1607 def pre_readline(self):
1608 """readline hook to be used at the start of each line.
1608 """readline hook to be used at the start of each line.
1609
1609
1610 Currently it handles auto-indent only."""
1610 Currently it handles auto-indent only."""
1611
1611
1612 #debugx('self.indent_current_nsp','pre_readline:')
1612 #debugx('self.indent_current_nsp','pre_readline:')
1613
1613
1614 if self.rl_do_indent:
1614 if self.rl_do_indent:
1615 self.readline.insert_text(self._indent_current_str())
1615 self.readline.insert_text(self._indent_current_str())
1616 if self.rl_next_input is not None:
1616 if self.rl_next_input is not None:
1617 self.readline.insert_text(self.rl_next_input)
1617 self.readline.insert_text(self.rl_next_input)
1618 self.rl_next_input = None
1618 self.rl_next_input = None
1619
1619
1620 def _indent_current_str(self):
1620 def _indent_current_str(self):
1621 """return the current level of indentation as a string"""
1621 """return the current level of indentation as a string"""
1622 return self.indent_current_nsp * ' '
1622 return self.indent_current_nsp * ' '
1623
1623
1624 #-------------------------------------------------------------------------
1624 #-------------------------------------------------------------------------
1625 # Things related to magics
1625 # Things related to magics
1626 #-------------------------------------------------------------------------
1626 #-------------------------------------------------------------------------
1627
1627
1628 def init_magics(self):
1628 def init_magics(self):
1629 # Set user colors (don't do it in the constructor above so that it
1629 # Set user colors (don't do it in the constructor above so that it
1630 # doesn't crash if colors option is invalid)
1630 # doesn't crash if colors option is invalid)
1631 self.magic_colors(self.colors)
1631 self.magic_colors(self.colors)
1632 # History was moved to a separate module
1632 # History was moved to a separate module
1633 from . import history
1633 from . import history
1634 history.init_ipython(self)
1634 history.init_ipython(self)
1635
1635
1636 def magic(self,arg_s):
1636 def magic(self,arg_s):
1637 """Call a magic function by name.
1637 """Call a magic function by name.
1638
1638
1639 Input: a string containing the name of the magic function to call and any
1639 Input: a string containing the name of the magic function to call and any
1640 additional arguments to be passed to the magic.
1640 additional arguments to be passed to the magic.
1641
1641
1642 magic('name -opt foo bar') is equivalent to typing at the ipython
1642 magic('name -opt foo bar') is equivalent to typing at the ipython
1643 prompt:
1643 prompt:
1644
1644
1645 In[1]: %name -opt foo bar
1645 In[1]: %name -opt foo bar
1646
1646
1647 To call a magic without arguments, simply use magic('name').
1647 To call a magic without arguments, simply use magic('name').
1648
1648
1649 This provides a proper Python function to call IPython's magics in any
1649 This provides a proper Python function to call IPython's magics in any
1650 valid Python code you can type at the interpreter, including loops and
1650 valid Python code you can type at the interpreter, including loops and
1651 compound statements.
1651 compound statements.
1652 """
1652 """
1653 args = arg_s.split(' ',1)
1653 args = arg_s.split(' ',1)
1654 magic_name = args[0]
1654 magic_name = args[0]
1655 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1655 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1656
1656
1657 try:
1657 try:
1658 magic_args = args[1]
1658 magic_args = args[1]
1659 except IndexError:
1659 except IndexError:
1660 magic_args = ''
1660 magic_args = ''
1661 fn = getattr(self,'magic_'+magic_name,None)
1661 fn = getattr(self,'magic_'+magic_name,None)
1662 if fn is None:
1662 if fn is None:
1663 error("Magic function `%s` not found." % magic_name)
1663 error("Magic function `%s` not found." % magic_name)
1664 else:
1664 else:
1665 magic_args = self.var_expand(magic_args,1)
1665 magic_args = self.var_expand(magic_args,1)
1666 with nested(self.builtin_trap,):
1666 with nested(self.builtin_trap,):
1667 result = fn(magic_args)
1667 result = fn(magic_args)
1668 return result
1668 return result
1669
1669
1670 def define_magic(self, magicname, func):
1670 def define_magic(self, magicname, func):
1671 """Expose own function as magic function for ipython
1671 """Expose own function as magic function for ipython
1672
1672
1673 def foo_impl(self,parameter_s=''):
1673 def foo_impl(self,parameter_s=''):
1674 'My very own magic!. (Use docstrings, IPython reads them).'
1674 'My very own magic!. (Use docstrings, IPython reads them).'
1675 print 'Magic function. Passed parameter is between < >:'
1675 print 'Magic function. Passed parameter is between < >:'
1676 print '<%s>' % parameter_s
1676 print '<%s>' % parameter_s
1677 print 'The self object is:',self
1677 print 'The self object is:',self
1678
1678
1679 self.define_magic('foo',foo_impl)
1679 self.define_magic('foo',foo_impl)
1680 """
1680 """
1681
1681
1682 import new
1682 import new
1683 im = new.instancemethod(func,self, self.__class__)
1683 im = new.instancemethod(func,self, self.__class__)
1684 old = getattr(self, "magic_" + magicname, None)
1684 old = getattr(self, "magic_" + magicname, None)
1685 setattr(self, "magic_" + magicname, im)
1685 setattr(self, "magic_" + magicname, im)
1686 return old
1686 return old
1687
1687
1688 #-------------------------------------------------------------------------
1688 #-------------------------------------------------------------------------
1689 # Things related to macros
1689 # Things related to macros
1690 #-------------------------------------------------------------------------
1690 #-------------------------------------------------------------------------
1691
1691
1692 def define_macro(self, name, themacro):
1692 def define_macro(self, name, themacro):
1693 """Define a new macro
1693 """Define a new macro
1694
1694
1695 Parameters
1695 Parameters
1696 ----------
1696 ----------
1697 name : str
1697 name : str
1698 The name of the macro.
1698 The name of the macro.
1699 themacro : str or Macro
1699 themacro : str or Macro
1700 The action to do upon invoking the macro. If a string, a new
1700 The action to do upon invoking the macro. If a string, a new
1701 Macro object is created by passing the string to it.
1701 Macro object is created by passing the string to it.
1702 """
1702 """
1703
1703
1704 from IPython.core import macro
1704 from IPython.core import macro
1705
1705
1706 if isinstance(themacro, basestring):
1706 if isinstance(themacro, basestring):
1707 themacro = macro.Macro(themacro)
1707 themacro = macro.Macro(themacro)
1708 if not isinstance(themacro, macro.Macro):
1708 if not isinstance(themacro, macro.Macro):
1709 raise ValueError('A macro must be a string or a Macro instance.')
1709 raise ValueError('A macro must be a string or a Macro instance.')
1710 self.user_ns[name] = themacro
1710 self.user_ns[name] = themacro
1711
1711
1712 #-------------------------------------------------------------------------
1712 #-------------------------------------------------------------------------
1713 # Things related to the running of system commands
1713 # Things related to the running of system commands
1714 #-------------------------------------------------------------------------
1714 #-------------------------------------------------------------------------
1715
1715
1716 def system(self, cmd):
1716 def system(self, cmd):
1717 """Make a system call, using IPython."""
1717 """Make a system call, using IPython."""
1718 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1718 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1719
1719
1720 #-------------------------------------------------------------------------
1720 #-------------------------------------------------------------------------
1721 # Things related to aliases
1721 # Things related to aliases
1722 #-------------------------------------------------------------------------
1722 #-------------------------------------------------------------------------
1723
1723
1724 def init_alias(self):
1724 def init_alias(self):
1725 self.alias_manager = AliasManager(self, config=self.config)
1725 self.alias_manager = AliasManager(self, config=self.config)
1726 self.ns_table['alias'] = self.alias_manager.alias_table,
1726 self.ns_table['alias'] = self.alias_manager.alias_table,
1727
1727
1728 #-------------------------------------------------------------------------
1728 #-------------------------------------------------------------------------
1729 # Things related to the running of code
1729 # Things related to the running of code
1730 #-------------------------------------------------------------------------
1730 #-------------------------------------------------------------------------
1731
1731
1732 def ex(self, cmd):
1732 def ex(self, cmd):
1733 """Execute a normal python statement in user namespace."""
1733 """Execute a normal python statement in user namespace."""
1734 with nested(self.builtin_trap,):
1734 with nested(self.builtin_trap,):
1735 exec cmd in self.user_global_ns, self.user_ns
1735 exec cmd in self.user_global_ns, self.user_ns
1736
1736
1737 def ev(self, expr):
1737 def ev(self, expr):
1738 """Evaluate python expression expr in user namespace.
1738 """Evaluate python expression expr in user namespace.
1739
1739
1740 Returns the result of evaluation
1740 Returns the result of evaluation
1741 """
1741 """
1742 with nested(self.builtin_trap,):
1742 with nested(self.builtin_trap,):
1743 return eval(expr, self.user_global_ns, self.user_ns)
1743 return eval(expr, self.user_global_ns, self.user_ns)
1744
1744
1745 def mainloop(self, display_banner=None):
1745 def mainloop(self, display_banner=None):
1746 """Start the mainloop.
1746 """Start the mainloop.
1747
1747
1748 If an optional banner argument is given, it will override the
1748 If an optional banner argument is given, it will override the
1749 internally created default banner.
1749 internally created default banner.
1750 """
1750 """
1751
1751
1752 with nested(self.builtin_trap, self.display_trap):
1752 with nested(self.builtin_trap, self.display_trap):
1753
1753
1754 # if you run stuff with -c <cmd>, raw hist is not updated
1754 # if you run stuff with -c <cmd>, raw hist is not updated
1755 # ensure that it's in sync
1755 # ensure that it's in sync
1756 if len(self.input_hist) != len (self.input_hist_raw):
1756 if len(self.input_hist) != len (self.input_hist_raw):
1757 self.input_hist_raw = InputList(self.input_hist)
1757 self.input_hist_raw = InputList(self.input_hist)
1758
1758
1759 while 1:
1759 while 1:
1760 try:
1760 try:
1761 self.interact(display_banner=display_banner)
1761 self.interact(display_banner=display_banner)
1762 #self.interact_with_readline()
1762 #self.interact_with_readline()
1763 # XXX for testing of a readline-decoupled repl loop, call
1763 # XXX for testing of a readline-decoupled repl loop, call
1764 # interact_with_readline above
1764 # interact_with_readline above
1765 break
1765 break
1766 except KeyboardInterrupt:
1766 except KeyboardInterrupt:
1767 # this should not be necessary, but KeyboardInterrupt
1767 # this should not be necessary, but KeyboardInterrupt
1768 # handling seems rather unpredictable...
1768 # handling seems rather unpredictable...
1769 self.write("\nKeyboardInterrupt in interact()\n")
1769 self.write("\nKeyboardInterrupt in interact()\n")
1770
1770
1771 def interact_prompt(self):
1771 def interact_prompt(self):
1772 """ Print the prompt (in read-eval-print loop)
1772 """ Print the prompt (in read-eval-print loop)
1773
1773
1774 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1774 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1775 used in standard IPython flow.
1775 used in standard IPython flow.
1776 """
1776 """
1777 if self.more:
1777 if self.more:
1778 try:
1778 try:
1779 prompt = self.hooks.generate_prompt(True)
1779 prompt = self.hooks.generate_prompt(True)
1780 except:
1780 except:
1781 self.showtraceback()
1781 self.showtraceback()
1782 if self.autoindent:
1782 if self.autoindent:
1783 self.rl_do_indent = True
1783 self.rl_do_indent = True
1784
1784
1785 else:
1785 else:
1786 try:
1786 try:
1787 prompt = self.hooks.generate_prompt(False)
1787 prompt = self.hooks.generate_prompt(False)
1788 except:
1788 except:
1789 self.showtraceback()
1789 self.showtraceback()
1790 self.write(prompt)
1790 self.write(prompt)
1791
1791
1792 def interact_handle_input(self,line):
1792 def interact_handle_input(self,line):
1793 """ Handle the input line (in read-eval-print loop)
1793 """ Handle the input line (in read-eval-print loop)
1794
1794
1795 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1795 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1796 used in standard IPython flow.
1796 used in standard IPython flow.
1797 """
1797 """
1798 if line.lstrip() == line:
1798 if line.lstrip() == line:
1799 self.shadowhist.add(line.strip())
1799 self.shadowhist.add(line.strip())
1800 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1800 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1801
1801
1802 if line.strip():
1802 if line.strip():
1803 if self.more:
1803 if self.more:
1804 self.input_hist_raw[-1] += '%s\n' % line
1804 self.input_hist_raw[-1] += '%s\n' % line
1805 else:
1805 else:
1806 self.input_hist_raw.append('%s\n' % line)
1806 self.input_hist_raw.append('%s\n' % line)
1807
1807
1808
1808
1809 self.more = self.push_line(lineout)
1809 self.more = self.push_line(lineout)
1810 if (self.SyntaxTB.last_syntax_error and
1810 if (self.SyntaxTB.last_syntax_error and
1811 self.autoedit_syntax):
1811 self.autoedit_syntax):
1812 self.edit_syntax_error()
1812 self.edit_syntax_error()
1813
1813
1814 def interact_with_readline(self):
1814 def interact_with_readline(self):
1815 """ Demo of using interact_handle_input, interact_prompt
1815 """ Demo of using interact_handle_input, interact_prompt
1816
1816
1817 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1817 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1818 it should work like this.
1818 it should work like this.
1819 """
1819 """
1820 self.readline_startup_hook(self.pre_readline)
1820 self.readline_startup_hook(self.pre_readline)
1821 while not self.exit_now:
1821 while not self.exit_now:
1822 self.interact_prompt()
1822 self.interact_prompt()
1823 if self.more:
1823 if self.more:
1824 self.rl_do_indent = True
1824 self.rl_do_indent = True
1825 else:
1825 else:
1826 self.rl_do_indent = False
1826 self.rl_do_indent = False
1827 line = raw_input_original().decode(self.stdin_encoding)
1827 line = raw_input_original().decode(self.stdin_encoding)
1828 self.interact_handle_input(line)
1828 self.interact_handle_input(line)
1829
1829
1830 def interact(self, display_banner=None):
1830 def interact(self, display_banner=None):
1831 """Closely emulate the interactive Python console."""
1831 """Closely emulate the interactive Python console."""
1832
1832
1833 # batch run -> do not interact
1833 # batch run -> do not interact
1834 if self.exit_now:
1834 if self.exit_now:
1835 return
1835 return
1836
1836
1837 if display_banner is None:
1837 if display_banner is None:
1838 display_banner = self.display_banner
1838 display_banner = self.display_banner
1839 if display_banner:
1839 if display_banner:
1840 self.show_banner()
1840 self.show_banner()
1841
1841
1842 more = 0
1842 more = 0
1843
1843
1844 # Mark activity in the builtins
1844 # Mark activity in the builtins
1845 __builtin__.__dict__['__IPYTHON__active'] += 1
1845 __builtin__.__dict__['__IPYTHON__active'] += 1
1846
1846
1847 if self.has_readline:
1847 if self.has_readline:
1848 self.readline_startup_hook(self.pre_readline)
1848 self.readline_startup_hook(self.pre_readline)
1849 # exit_now is set by a call to %Exit or %Quit, through the
1849 # exit_now is set by a call to %Exit or %Quit, through the
1850 # ask_exit callback.
1850 # ask_exit callback.
1851
1851
1852 while not self.exit_now:
1852 while not self.exit_now:
1853 self.hooks.pre_prompt_hook()
1853 self.hooks.pre_prompt_hook()
1854 if more:
1854 if more:
1855 try:
1855 try:
1856 prompt = self.hooks.generate_prompt(True)
1856 prompt = self.hooks.generate_prompt(True)
1857 except:
1857 except:
1858 self.showtraceback()
1858 self.showtraceback()
1859 if self.autoindent:
1859 if self.autoindent:
1860 self.rl_do_indent = True
1860 self.rl_do_indent = True
1861
1861
1862 else:
1862 else:
1863 try:
1863 try:
1864 prompt = self.hooks.generate_prompt(False)
1864 prompt = self.hooks.generate_prompt(False)
1865 except:
1865 except:
1866 self.showtraceback()
1866 self.showtraceback()
1867 try:
1867 try:
1868 line = self.raw_input(prompt, more)
1868 line = self.raw_input(prompt, more)
1869 if self.exit_now:
1869 if self.exit_now:
1870 # quick exit on sys.std[in|out] close
1870 # quick exit on sys.std[in|out] close
1871 break
1871 break
1872 if self.autoindent:
1872 if self.autoindent:
1873 self.rl_do_indent = False
1873 self.rl_do_indent = False
1874
1874
1875 except KeyboardInterrupt:
1875 except KeyboardInterrupt:
1876 #double-guard against keyboardinterrupts during kbdint handling
1876 #double-guard against keyboardinterrupts during kbdint handling
1877 try:
1877 try:
1878 self.write('\nKeyboardInterrupt\n')
1878 self.write('\nKeyboardInterrupt\n')
1879 self.resetbuffer()
1879 self.resetbuffer()
1880 # keep cache in sync with the prompt counter:
1880 # keep cache in sync with the prompt counter:
1881 self.outputcache.prompt_count -= 1
1881 self.outputcache.prompt_count -= 1
1882
1882
1883 if self.autoindent:
1883 if self.autoindent:
1884 self.indent_current_nsp = 0
1884 self.indent_current_nsp = 0
1885 more = 0
1885 more = 0
1886 except KeyboardInterrupt:
1886 except KeyboardInterrupt:
1887 pass
1887 pass
1888 except EOFError:
1888 except EOFError:
1889 if self.autoindent:
1889 if self.autoindent:
1890 self.rl_do_indent = False
1890 self.rl_do_indent = False
1891 if self.has_readline:
1891 if self.has_readline:
1892 self.readline_startup_hook(None)
1892 self.readline_startup_hook(None)
1893 self.write('\n')
1893 self.write('\n')
1894 self.exit()
1894 self.exit()
1895 except bdb.BdbQuit:
1895 except bdb.BdbQuit:
1896 warn('The Python debugger has exited with a BdbQuit exception.\n'
1896 warn('The Python debugger has exited with a BdbQuit exception.\n'
1897 'Because of how pdb handles the stack, it is impossible\n'
1897 'Because of how pdb handles the stack, it is impossible\n'
1898 'for IPython to properly format this particular exception.\n'
1898 'for IPython to properly format this particular exception.\n'
1899 'IPython will resume normal operation.')
1899 'IPython will resume normal operation.')
1900 except:
1900 except:
1901 # exceptions here are VERY RARE, but they can be triggered
1901 # exceptions here are VERY RARE, but they can be triggered
1902 # asynchronously by signal handlers, for example.
1902 # asynchronously by signal handlers, for example.
1903 self.showtraceback()
1903 self.showtraceback()
1904 else:
1904 else:
1905 more = self.push_line(line)
1905 more = self.push_line(line)
1906 if (self.SyntaxTB.last_syntax_error and
1906 if (self.SyntaxTB.last_syntax_error and
1907 self.autoedit_syntax):
1907 self.autoedit_syntax):
1908 self.edit_syntax_error()
1908 self.edit_syntax_error()
1909
1909
1910 # We are off again...
1910 # We are off again...
1911 __builtin__.__dict__['__IPYTHON__active'] -= 1
1911 __builtin__.__dict__['__IPYTHON__active'] -= 1
1912
1912
1913 # Turn off the exit flag, so the mainloop can be restarted if desired
1913 # Turn off the exit flag, so the mainloop can be restarted if desired
1914 self.exit_now = False
1914 self.exit_now = False
1915
1915
1916 def safe_execfile(self, fname, *where, **kw):
1916 def safe_execfile(self, fname, *where, **kw):
1917 """A safe version of the builtin execfile().
1917 """A safe version of the builtin execfile().
1918
1918
1919 This version will never throw an exception, but instead print
1919 This version will never throw an exception, but instead print
1920 helpful error messages to the screen. This only works on pure
1920 helpful error messages to the screen. This only works on pure
1921 Python files with the .py extension.
1921 Python files with the .py extension.
1922
1922
1923 Parameters
1923 Parameters
1924 ----------
1924 ----------
1925 fname : string
1925 fname : string
1926 The name of the file to be executed.
1926 The name of the file to be executed.
1927 where : tuple
1927 where : tuple
1928 One or two namespaces, passed to execfile() as (globals,locals).
1928 One or two namespaces, passed to execfile() as (globals,locals).
1929 If only one is given, it is passed as both.
1929 If only one is given, it is passed as both.
1930 exit_ignore : bool (False)
1930 exit_ignore : bool (False)
1931 If True, then silence SystemExit for non-zero status (it is always
1931 If True, then silence SystemExit for non-zero status (it is always
1932 silenced for zero status, as it is so common).
1932 silenced for zero status, as it is so common).
1933 """
1933 """
1934 kw.setdefault('exit_ignore', False)
1934 kw.setdefault('exit_ignore', False)
1935
1935
1936 fname = os.path.abspath(os.path.expanduser(fname))
1936 fname = os.path.abspath(os.path.expanduser(fname))
1937
1937
1938 # Make sure we have a .py file
1938 # Make sure we have a .py file
1939 if not fname.endswith('.py'):
1939 if not fname.endswith('.py'):
1940 warn('File must end with .py to be run using execfile: <%s>' % fname)
1940 warn('File must end with .py to be run using execfile: <%s>' % fname)
1941
1941
1942 # Make sure we can open the file
1942 # Make sure we can open the file
1943 try:
1943 try:
1944 with open(fname) as thefile:
1944 with open(fname) as thefile:
1945 pass
1945 pass
1946 except:
1946 except:
1947 warn('Could not open file <%s> for safe execution.' % fname)
1947 warn('Could not open file <%s> for safe execution.' % fname)
1948 return
1948 return
1949
1949
1950 # Find things also in current directory. This is needed to mimic the
1950 # Find things also in current directory. This is needed to mimic the
1951 # behavior of running a script from the system command line, where
1951 # behavior of running a script from the system command line, where
1952 # Python inserts the script's directory into sys.path
1952 # Python inserts the script's directory into sys.path
1953 dname = os.path.dirname(fname)
1953 dname = os.path.dirname(fname)
1954
1954
1955 with prepended_to_syspath(dname):
1955 with prepended_to_syspath(dname):
1956 try:
1956 try:
1957 execfile(fname,*where)
1957 execfile(fname,*where)
1958 except SystemExit, status:
1958 except SystemExit, status:
1959 # If the call was made with 0 or None exit status (sys.exit(0)
1959 # If the call was made with 0 or None exit status (sys.exit(0)
1960 # or sys.exit() ), don't bother showing a traceback, as both of
1960 # or sys.exit() ), don't bother showing a traceback, as both of
1961 # these are considered normal by the OS:
1961 # these are considered normal by the OS:
1962 # > python -c'import sys;sys.exit(0)'; echo $?
1962 # > python -c'import sys;sys.exit(0)'; echo $?
1963 # 0
1963 # 0
1964 # > python -c'import sys;sys.exit()'; echo $?
1964 # > python -c'import sys;sys.exit()'; echo $?
1965 # 0
1965 # 0
1966 # For other exit status, we show the exception unless
1966 # For other exit status, we show the exception unless
1967 # explicitly silenced, but only in short form.
1967 # explicitly silenced, but only in short form.
1968 if status.code not in (0, None) and not kw['exit_ignore']:
1968 if status.code not in (0, None) and not kw['exit_ignore']:
1969 self.showtraceback(exception_only=True)
1969 self.showtraceback(exception_only=True)
1970 except:
1970 except:
1971 self.showtraceback()
1971 self.showtraceback()
1972
1972
1973 def safe_execfile_ipy(self, fname):
1973 def safe_execfile_ipy(self, fname):
1974 """Like safe_execfile, but for .ipy files with IPython syntax.
1974 """Like safe_execfile, but for .ipy files with IPython syntax.
1975
1975
1976 Parameters
1976 Parameters
1977 ----------
1977 ----------
1978 fname : str
1978 fname : str
1979 The name of the file to execute. The filename must have a
1979 The name of the file to execute. The filename must have a
1980 .ipy extension.
1980 .ipy extension.
1981 """
1981 """
1982 fname = os.path.abspath(os.path.expanduser(fname))
1982 fname = os.path.abspath(os.path.expanduser(fname))
1983
1983
1984 # Make sure we have a .py file
1984 # Make sure we have a .py file
1985 if not fname.endswith('.ipy'):
1985 if not fname.endswith('.ipy'):
1986 warn('File must end with .py to be run using execfile: <%s>' % fname)
1986 warn('File must end with .py to be run using execfile: <%s>' % fname)
1987
1987
1988 # Make sure we can open the file
1988 # Make sure we can open the file
1989 try:
1989 try:
1990 with open(fname) as thefile:
1990 with open(fname) as thefile:
1991 pass
1991 pass
1992 except:
1992 except:
1993 warn('Could not open file <%s> for safe execution.' % fname)
1993 warn('Could not open file <%s> for safe execution.' % fname)
1994 return
1994 return
1995
1995
1996 # Find things also in current directory. This is needed to mimic the
1996 # Find things also in current directory. This is needed to mimic the
1997 # behavior of running a script from the system command line, where
1997 # behavior of running a script from the system command line, where
1998 # Python inserts the script's directory into sys.path
1998 # Python inserts the script's directory into sys.path
1999 dname = os.path.dirname(fname)
1999 dname = os.path.dirname(fname)
2000
2000
2001 with prepended_to_syspath(dname):
2001 with prepended_to_syspath(dname):
2002 try:
2002 try:
2003 with open(fname) as thefile:
2003 with open(fname) as thefile:
2004 script = thefile.read()
2004 script = thefile.read()
2005 # self.runlines currently captures all exceptions
2005 # self.runlines currently captures all exceptions
2006 # raise in user code. It would be nice if there were
2006 # raise in user code. It would be nice if there were
2007 # versions of runlines, execfile that did raise, so
2007 # versions of runlines, execfile that did raise, so
2008 # we could catch the errors.
2008 # we could catch the errors.
2009 self.runlines(script, clean=True)
2009 self.runlines(script, clean=True)
2010 except:
2010 except:
2011 self.showtraceback()
2011 self.showtraceback()
2012 warn('Unknown failure executing file: <%s>' % fname)
2012 warn('Unknown failure executing file: <%s>' % fname)
2013
2013
2014 def _is_secondary_block_start(self, s):
2014 def _is_secondary_block_start(self, s):
2015 if not s.endswith(':'):
2015 if not s.endswith(':'):
2016 return False
2016 return False
2017 if (s.startswith('elif') or
2017 if (s.startswith('elif') or
2018 s.startswith('else') or
2018 s.startswith('else') or
2019 s.startswith('except') or
2019 s.startswith('except') or
2020 s.startswith('finally')):
2020 s.startswith('finally')):
2021 return True
2021 return True
2022
2022
2023 def cleanup_ipy_script(self, script):
2023 def cleanup_ipy_script(self, script):
2024 """Make a script safe for self.runlines()
2024 """Make a script safe for self.runlines()
2025
2025
2026 Currently, IPython is lines based, with blocks being detected by
2026 Currently, IPython is lines based, with blocks being detected by
2027 empty lines. This is a problem for block based scripts that may
2027 empty lines. This is a problem for block based scripts that may
2028 not have empty lines after blocks. This script adds those empty
2028 not have empty lines after blocks. This script adds those empty
2029 lines to make scripts safe for running in the current line based
2029 lines to make scripts safe for running in the current line based
2030 IPython.
2030 IPython.
2031 """
2031 """
2032 res = []
2032 res = []
2033 lines = script.splitlines()
2033 lines = script.splitlines()
2034 level = 0
2034 level = 0
2035
2035
2036 for l in lines:
2036 for l in lines:
2037 lstripped = l.lstrip()
2037 lstripped = l.lstrip()
2038 stripped = l.strip()
2038 stripped = l.strip()
2039 if not stripped:
2039 if not stripped:
2040 continue
2040 continue
2041 newlevel = len(l) - len(lstripped)
2041 newlevel = len(l) - len(lstripped)
2042 if level > 0 and newlevel == 0 and \
2042 if level > 0 and newlevel == 0 and \
2043 not self._is_secondary_block_start(stripped):
2043 not self._is_secondary_block_start(stripped):
2044 # add empty line
2044 # add empty line
2045 res.append('')
2045 res.append('')
2046 res.append(l)
2046 res.append(l)
2047 level = newlevel
2047 level = newlevel
2048
2048
2049 return '\n'.join(res) + '\n'
2049 return '\n'.join(res) + '\n'
2050
2050
2051 def runlines(self, lines, clean=False):
2051 def runlines(self, lines, clean=False):
2052 """Run a string of one or more lines of source.
2052 """Run a string of one or more lines of source.
2053
2053
2054 This method is capable of running a string containing multiple source
2054 This method is capable of running a string containing multiple source
2055 lines, as if they had been entered at the IPython prompt. Since it
2055 lines, as if they had been entered at the IPython prompt. Since it
2056 exposes IPython's processing machinery, the given strings can contain
2056 exposes IPython's processing machinery, the given strings can contain
2057 magic calls (%magic), special shell access (!cmd), etc.
2057 magic calls (%magic), special shell access (!cmd), etc.
2058 """
2058 """
2059
2059
2060 if isinstance(lines, (list, tuple)):
2060 if isinstance(lines, (list, tuple)):
2061 lines = '\n'.join(lines)
2061 lines = '\n'.join(lines)
2062
2062
2063 if clean:
2063 if clean:
2064 lines = self.cleanup_ipy_script(lines)
2064 lines = self.cleanup_ipy_script(lines)
2065
2065
2066 # We must start with a clean buffer, in case this is run from an
2066 # We must start with a clean buffer, in case this is run from an
2067 # interactive IPython session (via a magic, for example).
2067 # interactive IPython session (via a magic, for example).
2068 self.resetbuffer()
2068 self.resetbuffer()
2069 lines = lines.splitlines()
2069 lines = lines.splitlines()
2070 more = 0
2070 more = 0
2071
2071
2072 with nested(self.builtin_trap, self.display_trap):
2072 with nested(self.builtin_trap, self.display_trap):
2073 for line in lines:
2073 for line in lines:
2074 # skip blank lines so we don't mess up the prompt counter, but do
2074 # skip blank lines so we don't mess up the prompt counter, but do
2075 # NOT skip even a blank line if we are in a code block (more is
2075 # NOT skip even a blank line if we are in a code block (more is
2076 # true)
2076 # true)
2077
2077
2078 if line or more:
2078 if line or more:
2079 # push to raw history, so hist line numbers stay in sync
2079 # push to raw history, so hist line numbers stay in sync
2080 self.input_hist_raw.append("# " + line + "\n")
2080 self.input_hist_raw.append("# " + line + "\n")
2081 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2081 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2082 more = self.push_line(prefiltered)
2082 more = self.push_line(prefiltered)
2083 # IPython's runsource returns None if there was an error
2083 # IPython's runsource returns None if there was an error
2084 # compiling the code. This allows us to stop processing right
2084 # compiling the code. This allows us to stop processing right
2085 # away, so the user gets the error message at the right place.
2085 # away, so the user gets the error message at the right place.
2086 if more is None:
2086 if more is None:
2087 break
2087 break
2088 else:
2088 else:
2089 self.input_hist_raw.append("\n")
2089 self.input_hist_raw.append("\n")
2090 # final newline in case the input didn't have it, so that the code
2090 # final newline in case the input didn't have it, so that the code
2091 # actually does get executed
2091 # actually does get executed
2092 if more:
2092 if more:
2093 self.push_line('\n')
2093 self.push_line('\n')
2094
2094
2095 def runsource(self, source, filename='<input>', symbol='single'):
2095 def runsource(self, source, filename='<input>', symbol='single'):
2096 """Compile and run some source in the interpreter.
2096 """Compile and run some source in the interpreter.
2097
2097
2098 Arguments are as for compile_command().
2098 Arguments are as for compile_command().
2099
2099
2100 One several things can happen:
2100 One several things can happen:
2101
2101
2102 1) The input is incorrect; compile_command() raised an
2102 1) The input is incorrect; compile_command() raised an
2103 exception (SyntaxError or OverflowError). A syntax traceback
2103 exception (SyntaxError or OverflowError). A syntax traceback
2104 will be printed by calling the showsyntaxerror() method.
2104 will be printed by calling the showsyntaxerror() method.
2105
2105
2106 2) The input is incomplete, and more input is required;
2106 2) The input is incomplete, and more input is required;
2107 compile_command() returned None. Nothing happens.
2107 compile_command() returned None. Nothing happens.
2108
2108
2109 3) The input is complete; compile_command() returned a code
2109 3) The input is complete; compile_command() returned a code
2110 object. The code is executed by calling self.runcode() (which
2110 object. The code is executed by calling self.runcode() (which
2111 also handles run-time exceptions, except for SystemExit).
2111 also handles run-time exceptions, except for SystemExit).
2112
2112
2113 The return value is:
2113 The return value is:
2114
2114
2115 - True in case 2
2115 - True in case 2
2116
2116
2117 - False in the other cases, unless an exception is raised, where
2117 - False in the other cases, unless an exception is raised, where
2118 None is returned instead. This can be used by external callers to
2118 None is returned instead. This can be used by external callers to
2119 know whether to continue feeding input or not.
2119 know whether to continue feeding input or not.
2120
2120
2121 The return value can be used to decide whether to use sys.ps1 or
2121 The return value can be used to decide whether to use sys.ps1 or
2122 sys.ps2 to prompt the next line."""
2122 sys.ps2 to prompt the next line."""
2123
2123
2124 # if the source code has leading blanks, add 'if 1:\n' to it
2124 # if the source code has leading blanks, add 'if 1:\n' to it
2125 # this allows execution of indented pasted code. It is tempting
2125 # this allows execution of indented pasted code. It is tempting
2126 # to add '\n' at the end of source to run commands like ' a=1'
2126 # to add '\n' at the end of source to run commands like ' a=1'
2127 # directly, but this fails for more complicated scenarios
2127 # directly, but this fails for more complicated scenarios
2128 source=source.encode(self.stdin_encoding)
2128 source=source.encode(self.stdin_encoding)
2129 if source[:1] in [' ', '\t']:
2129 if source[:1] in [' ', '\t']:
2130 source = 'if 1:\n%s' % source
2130 source = 'if 1:\n%s' % source
2131
2131
2132 try:
2132 try:
2133 code = self.compile(source,filename,symbol)
2133 code = self.compile(source,filename,symbol)
2134 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2134 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2135 # Case 1
2135 # Case 1
2136 self.showsyntaxerror(filename)
2136 self.showsyntaxerror(filename)
2137 return None
2137 return None
2138
2138
2139 if code is None:
2139 if code is None:
2140 # Case 2
2140 # Case 2
2141 return True
2141 return True
2142
2142
2143 # Case 3
2143 # Case 3
2144 # We store the code object so that threaded shells and
2144 # We store the code object so that threaded shells and
2145 # custom exception handlers can access all this info if needed.
2145 # custom exception handlers can access all this info if needed.
2146 # The source corresponding to this can be obtained from the
2146 # The source corresponding to this can be obtained from the
2147 # buffer attribute as '\n'.join(self.buffer).
2147 # buffer attribute as '\n'.join(self.buffer).
2148 self.code_to_run = code
2148 self.code_to_run = code
2149 # now actually execute the code object
2149 # now actually execute the code object
2150 if self.runcode(code) == 0:
2150 if self.runcode(code) == 0:
2151 return False
2151 return False
2152 else:
2152 else:
2153 return None
2153 return None
2154
2154
2155 def runcode(self,code_obj):
2155 def runcode(self,code_obj):
2156 """Execute a code object.
2156 """Execute a code object.
2157
2157
2158 When an exception occurs, self.showtraceback() is called to display a
2158 When an exception occurs, self.showtraceback() is called to display a
2159 traceback.
2159 traceback.
2160
2160
2161 Return value: a flag indicating whether the code to be run completed
2161 Return value: a flag indicating whether the code to be run completed
2162 successfully:
2162 successfully:
2163
2163
2164 - 0: successful execution.
2164 - 0: successful execution.
2165 - 1: an error occurred.
2165 - 1: an error occurred.
2166 """
2166 """
2167
2167
2168 # Set our own excepthook in case the user code tries to call it
2168 # Set our own excepthook in case the user code tries to call it
2169 # directly, so that the IPython crash handler doesn't get triggered
2169 # directly, so that the IPython crash handler doesn't get triggered
2170 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2170 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2171
2171
2172 # we save the original sys.excepthook in the instance, in case config
2172 # we save the original sys.excepthook in the instance, in case config
2173 # code (such as magics) needs access to it.
2173 # code (such as magics) needs access to it.
2174 self.sys_excepthook = old_excepthook
2174 self.sys_excepthook = old_excepthook
2175 outflag = 1 # happens in more places, so it's easier as default
2175 outflag = 1 # happens in more places, so it's easier as default
2176 try:
2176 try:
2177 try:
2177 try:
2178 self.hooks.pre_runcode_hook()
2178 self.hooks.pre_runcode_hook()
2179 exec code_obj in self.user_global_ns, self.user_ns
2179 exec code_obj in self.user_global_ns, self.user_ns
2180 finally:
2180 finally:
2181 # Reset our crash handler in place
2181 # Reset our crash handler in place
2182 sys.excepthook = old_excepthook
2182 sys.excepthook = old_excepthook
2183 except SystemExit:
2183 except SystemExit:
2184 self.resetbuffer()
2184 self.resetbuffer()
2185 self.showtraceback(exception_only=True)
2185 self.showtraceback(exception_only=True)
2186 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
2186 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
2187 except self.custom_exceptions:
2187 except self.custom_exceptions:
2188 etype,value,tb = sys.exc_info()
2188 etype,value,tb = sys.exc_info()
2189 self.CustomTB(etype,value,tb)
2189 self.CustomTB(etype,value,tb)
2190 except:
2190 except:
2191 self.showtraceback()
2191 self.showtraceback()
2192 else:
2192 else:
2193 outflag = 0
2193 outflag = 0
2194 if softspace(sys.stdout, 0):
2194 if softspace(sys.stdout, 0):
2195 print
2195 print
2196 # Flush out code object which has been run (and source)
2196 # Flush out code object which has been run (and source)
2197 self.code_to_run = None
2197 self.code_to_run = None
2198 return outflag
2198 return outflag
2199
2199
2200 def push_line(self, line):
2200 def push_line(self, line):
2201 """Push a line to the interpreter.
2201 """Push a line to the interpreter.
2202
2202
2203 The line should not have a trailing newline; it may have
2203 The line should not have a trailing newline; it may have
2204 internal newlines. The line is appended to a buffer and the
2204 internal newlines. The line is appended to a buffer and the
2205 interpreter's runsource() method is called with the
2205 interpreter's runsource() method is called with the
2206 concatenated contents of the buffer as source. If this
2206 concatenated contents of the buffer as source. If this
2207 indicates that the command was executed or invalid, the buffer
2207 indicates that the command was executed or invalid, the buffer
2208 is reset; otherwise, the command is incomplete, and the buffer
2208 is reset; otherwise, the command is incomplete, and the buffer
2209 is left as it was after the line was appended. The return
2209 is left as it was after the line was appended. The return
2210 value is 1 if more input is required, 0 if the line was dealt
2210 value is 1 if more input is required, 0 if the line was dealt
2211 with in some way (this is the same as runsource()).
2211 with in some way (this is the same as runsource()).
2212 """
2212 """
2213
2213
2214 # autoindent management should be done here, and not in the
2214 # autoindent management should be done here, and not in the
2215 # interactive loop, since that one is only seen by keyboard input. We
2215 # interactive loop, since that one is only seen by keyboard input. We
2216 # need this done correctly even for code run via runlines (which uses
2216 # need this done correctly even for code run via runlines (which uses
2217 # push).
2217 # push).
2218
2218
2219 #print 'push line: <%s>' % line # dbg
2219 #print 'push line: <%s>' % line # dbg
2220 for subline in line.splitlines():
2220 for subline in line.splitlines():
2221 self._autoindent_update(subline)
2221 self._autoindent_update(subline)
2222 self.buffer.append(line)
2222 self.buffer.append(line)
2223 more = self.runsource('\n'.join(self.buffer), self.filename)
2223 more = self.runsource('\n'.join(self.buffer), self.filename)
2224 if not more:
2224 if not more:
2225 self.resetbuffer()
2225 self.resetbuffer()
2226 return more
2226 return more
2227
2227
2228 def _autoindent_update(self,line):
2228 def _autoindent_update(self,line):
2229 """Keep track of the indent level."""
2229 """Keep track of the indent level."""
2230
2230
2231 #debugx('line')
2231 #debugx('line')
2232 #debugx('self.indent_current_nsp')
2232 #debugx('self.indent_current_nsp')
2233 if self.autoindent:
2233 if self.autoindent:
2234 if line:
2234 if line:
2235 inisp = num_ini_spaces(line)
2235 inisp = num_ini_spaces(line)
2236 if inisp < self.indent_current_nsp:
2236 if inisp < self.indent_current_nsp:
2237 self.indent_current_nsp = inisp
2237 self.indent_current_nsp = inisp
2238
2238
2239 if line[-1] == ':':
2239 if line[-1] == ':':
2240 self.indent_current_nsp += 4
2240 self.indent_current_nsp += 4
2241 elif dedent_re.match(line):
2241 elif dedent_re.match(line):
2242 self.indent_current_nsp -= 4
2242 self.indent_current_nsp -= 4
2243 else:
2243 else:
2244 self.indent_current_nsp = 0
2244 self.indent_current_nsp = 0
2245
2245
2246 def resetbuffer(self):
2246 def resetbuffer(self):
2247 """Reset the input buffer."""
2247 """Reset the input buffer."""
2248 self.buffer[:] = []
2248 self.buffer[:] = []
2249
2249
2250 def raw_input(self,prompt='',continue_prompt=False):
2250 def raw_input(self,prompt='',continue_prompt=False):
2251 """Write a prompt and read a line.
2251 """Write a prompt and read a line.
2252
2252
2253 The returned line does not include the trailing newline.
2253 The returned line does not include the trailing newline.
2254 When the user enters the EOF key sequence, EOFError is raised.
2254 When the user enters the EOF key sequence, EOFError is raised.
2255
2255
2256 Optional inputs:
2256 Optional inputs:
2257
2257
2258 - prompt(''): a string to be printed to prompt the user.
2258 - prompt(''): a string to be printed to prompt the user.
2259
2259
2260 - continue_prompt(False): whether this line is the first one or a
2260 - continue_prompt(False): whether this line is the first one or a
2261 continuation in a sequence of inputs.
2261 continuation in a sequence of inputs.
2262 """
2262 """
2263 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2263 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2264
2264
2265 # Code run by the user may have modified the readline completer state.
2265 # Code run by the user may have modified the readline completer state.
2266 # We must ensure that our completer is back in place.
2266 # We must ensure that our completer is back in place.
2267
2267
2268 if self.has_readline:
2268 if self.has_readline:
2269 self.set_completer()
2269 self.set_completer()
2270
2270
2271 try:
2271 try:
2272 line = raw_input_original(prompt).decode(self.stdin_encoding)
2272 line = raw_input_original(prompt).decode(self.stdin_encoding)
2273 except ValueError:
2273 except ValueError:
2274 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2274 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2275 " or sys.stdout.close()!\nExiting IPython!")
2275 " or sys.stdout.close()!\nExiting IPython!")
2276 self.ask_exit()
2276 self.ask_exit()
2277 return ""
2277 return ""
2278
2278
2279 # Try to be reasonably smart about not re-indenting pasted input more
2279 # Try to be reasonably smart about not re-indenting pasted input more
2280 # than necessary. We do this by trimming out the auto-indent initial
2280 # than necessary. We do this by trimming out the auto-indent initial
2281 # spaces, if the user's actual input started itself with whitespace.
2281 # spaces, if the user's actual input started itself with whitespace.
2282 #debugx('self.buffer[-1]')
2282 #debugx('self.buffer[-1]')
2283
2283
2284 if self.autoindent:
2284 if self.autoindent:
2285 if num_ini_spaces(line) > self.indent_current_nsp:
2285 if num_ini_spaces(line) > self.indent_current_nsp:
2286 line = line[self.indent_current_nsp:]
2286 line = line[self.indent_current_nsp:]
2287 self.indent_current_nsp = 0
2287 self.indent_current_nsp = 0
2288
2288
2289 # store the unfiltered input before the user has any chance to modify
2289 # store the unfiltered input before the user has any chance to modify
2290 # it.
2290 # it.
2291 if line.strip():
2291 if line.strip():
2292 if continue_prompt:
2292 if continue_prompt:
2293 self.input_hist_raw[-1] += '%s\n' % line
2293 self.input_hist_raw[-1] += '%s\n' % line
2294 if self.has_readline and self.readline_use:
2294 if self.has_readline and self.readline_use:
2295 try:
2295 try:
2296 histlen = self.readline.get_current_history_length()
2296 histlen = self.readline.get_current_history_length()
2297 if histlen > 1:
2297 if histlen > 1:
2298 newhist = self.input_hist_raw[-1].rstrip()
2298 newhist = self.input_hist_raw[-1].rstrip()
2299 self.readline.remove_history_item(histlen-1)
2299 self.readline.remove_history_item(histlen-1)
2300 self.readline.replace_history_item(histlen-2,
2300 self.readline.replace_history_item(histlen-2,
2301 newhist.encode(self.stdin_encoding))
2301 newhist.encode(self.stdin_encoding))
2302 except AttributeError:
2302 except AttributeError:
2303 pass # re{move,place}_history_item are new in 2.4.
2303 pass # re{move,place}_history_item are new in 2.4.
2304 else:
2304 else:
2305 self.input_hist_raw.append('%s\n' % line)
2305 self.input_hist_raw.append('%s\n' % line)
2306 # only entries starting at first column go to shadow history
2306 # only entries starting at first column go to shadow history
2307 if line.lstrip() == line:
2307 if line.lstrip() == line:
2308 self.shadowhist.add(line.strip())
2308 self.shadowhist.add(line.strip())
2309 elif not continue_prompt:
2309 elif not continue_prompt:
2310 self.input_hist_raw.append('\n')
2310 self.input_hist_raw.append('\n')
2311 try:
2311 try:
2312 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2312 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2313 except:
2313 except:
2314 # blanket except, in case a user-defined prefilter crashes, so it
2314 # blanket except, in case a user-defined prefilter crashes, so it
2315 # can't take all of ipython with it.
2315 # can't take all of ipython with it.
2316 self.showtraceback()
2316 self.showtraceback()
2317 return ''
2317 return ''
2318 else:
2318 else:
2319 return lineout
2319 return lineout
2320
2320
2321 #-------------------------------------------------------------------------
2321 #-------------------------------------------------------------------------
2322 # Working with components
2322 # Working with components
2323 #-------------------------------------------------------------------------
2323 #-------------------------------------------------------------------------
2324
2324
2325 def get_component(self, name=None, klass=None):
2325 def get_component(self, name=None, klass=None):
2326 """Fetch a component by name and klass in my tree."""
2326 """Fetch a component by name and klass in my tree."""
2327 c = Component.get_instances(root=self, name=name, klass=klass)
2327 c = Component.get_instances(root=self, name=name, klass=klass)
2328 if len(c) == 0:
2328 if len(c) == 0:
2329 return None
2329 return None
2330 if len(c) == 1:
2330 if len(c) == 1:
2331 return c[0]
2331 return c[0]
2332 else:
2332 else:
2333 return c
2333 return c
2334
2334
2335 #-------------------------------------------------------------------------
2335 #-------------------------------------------------------------------------
2336 # IPython extensions
2336 # IPython extensions
2337 #-------------------------------------------------------------------------
2337 #-------------------------------------------------------------------------
2338
2338
2339 def load_extension(self, module_str):
2339 def load_extension(self, module_str):
2340 """Load an IPython extension by its module name.
2340 """Load an IPython extension by its module name.
2341
2341
2342 An IPython extension is an importable Python module that has
2342 An IPython extension is an importable Python module that has
2343 a function with the signature::
2343 a function with the signature::
2344
2344
2345 def load_ipython_extension(ipython):
2345 def load_ipython_extension(ipython):
2346 # Do things with ipython
2346 # Do things with ipython
2347
2347
2348 This function is called after your extension is imported and the
2348 This function is called after your extension is imported and the
2349 currently active :class:`InteractiveShell` instance is passed as
2349 currently active :class:`InteractiveShell` instance is passed as
2350 the only argument. You can do anything you want with IPython at
2350 the only argument. You can do anything you want with IPython at
2351 that point, including defining new magic and aliases, adding new
2351 that point, including defining new magic and aliases, adding new
2352 components, etc.
2352 components, etc.
2353
2353
2354 The :func:`load_ipython_extension` will be called again is you
2354 The :func:`load_ipython_extension` will be called again is you
2355 load or reload the extension again. It is up to the extension
2355 load or reload the extension again. It is up to the extension
2356 author to add code to manage that.
2356 author to add code to manage that.
2357
2357
2358 You can put your extension modules anywhere you want, as long as
2358 You can put your extension modules anywhere you want, as long as
2359 they can be imported by Python's standard import mechanism. However,
2359 they can be imported by Python's standard import mechanism. However,
2360 to make it easy to write extensions, you can also put your extensions
2360 to make it easy to write extensions, you can also put your extensions
2361 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2361 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2362 is added to ``sys.path`` automatically.
2362 is added to ``sys.path`` automatically.
2363
2363
2364 If :func:`load_ipython_extension` returns anything, this function
2364 If :func:`load_ipython_extension` returns anything, this function
2365 will return that object.
2365 will return that object.
2366 """
2366 """
2367 from IPython.utils.syspathcontext import prepended_to_syspath
2367 from IPython.utils.syspathcontext import prepended_to_syspath
2368
2368
2369 if module_str not in sys.modules:
2369 if module_str not in sys.modules:
2370 with prepended_to_syspath(self.ipython_extension_dir):
2370 with prepended_to_syspath(self.ipython_extension_dir):
2371 __import__(module_str)
2371 __import__(module_str)
2372 mod = sys.modules[module_str]
2372 mod = sys.modules[module_str]
2373 return self._call_load_ipython_extension(mod)
2373 return self._call_load_ipython_extension(mod)
2374
2374
2375 def unload_extension(self, module_str):
2375 def unload_extension(self, module_str):
2376 """Unload an IPython extension by its module name.
2376 """Unload an IPython extension by its module name.
2377
2377
2378 This function looks up the extension's name in ``sys.modules`` and
2378 This function looks up the extension's name in ``sys.modules`` and
2379 simply calls ``mod.unload_ipython_extension(self)``.
2379 simply calls ``mod.unload_ipython_extension(self)``.
2380 """
2380 """
2381 if module_str in sys.modules:
2381 if module_str in sys.modules:
2382 mod = sys.modules[module_str]
2382 mod = sys.modules[module_str]
2383 self._call_unload_ipython_extension(mod)
2383 self._call_unload_ipython_extension(mod)
2384
2384
2385 def reload_extension(self, module_str):
2385 def reload_extension(self, module_str):
2386 """Reload an IPython extension by calling reload.
2386 """Reload an IPython extension by calling reload.
2387
2387
2388 If the module has not been loaded before,
2388 If the module has not been loaded before,
2389 :meth:`InteractiveShell.load_extension` is called. Otherwise
2389 :meth:`InteractiveShell.load_extension` is called. Otherwise
2390 :func:`reload` is called and then the :func:`load_ipython_extension`
2390 :func:`reload` is called and then the :func:`load_ipython_extension`
2391 function of the module, if it exists is called.
2391 function of the module, if it exists is called.
2392 """
2392 """
2393 from IPython.utils.syspathcontext import prepended_to_syspath
2393 from IPython.utils.syspathcontext import prepended_to_syspath
2394
2394
2395 with prepended_to_syspath(self.ipython_extension_dir):
2395 with prepended_to_syspath(self.ipython_extension_dir):
2396 if module_str in sys.modules:
2396 if module_str in sys.modules:
2397 mod = sys.modules[module_str]
2397 mod = sys.modules[module_str]
2398 reload(mod)
2398 reload(mod)
2399 self._call_load_ipython_extension(mod)
2399 self._call_load_ipython_extension(mod)
2400 else:
2400 else:
2401 self.load_extension(module_str)
2401 self.load_extension(module_str)
2402
2402
2403 def _call_load_ipython_extension(self, mod):
2403 def _call_load_ipython_extension(self, mod):
2404 if hasattr(mod, 'load_ipython_extension'):
2404 if hasattr(mod, 'load_ipython_extension'):
2405 return mod.load_ipython_extension(self)
2405 return mod.load_ipython_extension(self)
2406
2406
2407 def _call_unload_ipython_extension(self, mod):
2407 def _call_unload_ipython_extension(self, mod):
2408 if hasattr(mod, 'unload_ipython_extension'):
2408 if hasattr(mod, 'unload_ipython_extension'):
2409 return mod.unload_ipython_extension(self)
2409 return mod.unload_ipython_extension(self)
2410
2410
2411 #-------------------------------------------------------------------------
2411 #-------------------------------------------------------------------------
2412 # Things related to the prefilter
2412 # Things related to the prefilter
2413 #-------------------------------------------------------------------------
2413 #-------------------------------------------------------------------------
2414
2414
2415 def init_prefilter(self):
2415 def init_prefilter(self):
2416 self.prefilter_manager = PrefilterManager(self, config=self.config)
2416 self.prefilter_manager = PrefilterManager(self, config=self.config)
2417 # Ultimately this will be refactored in the new interpreter code, but
2417 # Ultimately this will be refactored in the new interpreter code, but
2418 # for now, we should expose the main prefilter method (there's legacy
2418 # for now, we should expose the main prefilter method (there's legacy
2419 # code out there that may rely on this).
2419 # code out there that may rely on this).
2420 self.prefilter = self.prefilter_manager.prefilter_lines
2420 self.prefilter = self.prefilter_manager.prefilter_lines
2421
2421
2422 #-------------------------------------------------------------------------
2422 #-------------------------------------------------------------------------
2423 # Utilities
2423 # Utilities
2424 #-------------------------------------------------------------------------
2424 #-------------------------------------------------------------------------
2425
2425
2426 def getoutput(self, cmd):
2426 def getoutput(self, cmd):
2427 return getoutput(self.var_expand(cmd,depth=2),
2427 return getoutput(self.var_expand(cmd,depth=2),
2428 header=self.system_header,
2428 header=self.system_header,
2429 verbose=self.system_verbose)
2429 verbose=self.system_verbose)
2430
2430
2431 def getoutputerror(self, cmd):
2431 def getoutputerror(self, cmd):
2432 return getoutputerror(self.var_expand(cmd,depth=2),
2432 return getoutputerror(self.var_expand(cmd,depth=2),
2433 header=self.system_header,
2433 header=self.system_header,
2434 verbose=self.system_verbose)
2434 verbose=self.system_verbose)
2435
2435
2436 def var_expand(self,cmd,depth=0):
2436 def var_expand(self,cmd,depth=0):
2437 """Expand python variables in a string.
2437 """Expand python variables in a string.
2438
2438
2439 The depth argument indicates how many frames above the caller should
2439 The depth argument indicates how many frames above the caller should
2440 be walked to look for the local namespace where to expand variables.
2440 be walked to look for the local namespace where to expand variables.
2441
2441
2442 The global namespace for expansion is always the user's interactive
2442 The global namespace for expansion is always the user's interactive
2443 namespace.
2443 namespace.
2444 """
2444 """
2445
2445
2446 return str(ItplNS(cmd,
2446 return str(ItplNS(cmd,
2447 self.user_ns, # globals
2447 self.user_ns, # globals
2448 # Skip our own frame in searching for locals:
2448 # Skip our own frame in searching for locals:
2449 sys._getframe(depth+1).f_locals # locals
2449 sys._getframe(depth+1).f_locals # locals
2450 ))
2450 ))
2451
2451
2452 def mktempfile(self,data=None):
2452 def mktempfile(self,data=None):
2453 """Make a new tempfile and return its filename.
2453 """Make a new tempfile and return its filename.
2454
2454
2455 This makes a call to tempfile.mktemp, but it registers the created
2455 This makes a call to tempfile.mktemp, but it registers the created
2456 filename internally so ipython cleans it up at exit time.
2456 filename internally so ipython cleans it up at exit time.
2457
2457
2458 Optional inputs:
2458 Optional inputs:
2459
2459
2460 - data(None): if data is given, it gets written out to the temp file
2460 - data(None): if data is given, it gets written out to the temp file
2461 immediately, and the file is closed again."""
2461 immediately, and the file is closed again."""
2462
2462
2463 filename = tempfile.mktemp('.py','ipython_edit_')
2463 filename = tempfile.mktemp('.py','ipython_edit_')
2464 self.tempfiles.append(filename)
2464 self.tempfiles.append(filename)
2465
2465
2466 if data:
2466 if data:
2467 tmp_file = open(filename,'w')
2467 tmp_file = open(filename,'w')
2468 tmp_file.write(data)
2468 tmp_file.write(data)
2469 tmp_file.close()
2469 tmp_file.close()
2470 return filename
2470 return filename
2471
2471
2472 def write(self,data):
2472 def write(self,data):
2473 """Write a string to the default output"""
2473 """Write a string to the default output"""
2474 Term.cout.write(data)
2474 Term.cout.write(data)
2475
2475
2476 def write_err(self,data):
2476 def write_err(self,data):
2477 """Write a string to the default error output"""
2477 """Write a string to the default error output"""
2478 Term.cerr.write(data)
2478 Term.cerr.write(data)
2479
2479
2480 def ask_yes_no(self,prompt,default=True):
2480 def ask_yes_no(self,prompt,default=True):
2481 if self.quiet:
2481 if self.quiet:
2482 return True
2482 return True
2483 return ask_yes_no(prompt,default)
2483 return ask_yes_no(prompt,default)
2484
2484
2485 #-------------------------------------------------------------------------
2485 #-------------------------------------------------------------------------
2486 # Things related to GUI support and pylab
2486 # Things related to GUI support and pylab
2487 #-------------------------------------------------------------------------
2487 #-------------------------------------------------------------------------
2488
2488
2489 def enable_pylab(self, gui=None):
2489 def enable_pylab(self, gui=None):
2490 """Activate pylab support at runtime.
2490 """Activate pylab support at runtime.
2491
2491
2492 This turns on support for matplotlib, preloads into the interactive
2492 This turns on support for matplotlib, preloads into the interactive
2493 namespace all of numpy and pylab, and configures IPython to correcdtly
2493 namespace all of numpy and pylab, and configures IPython to correcdtly
2494 interact with the GUI event loop. The GUI backend to be used can be
2494 interact with the GUI event loop. The GUI backend to be used can be
2495 optionally selected with the optional :param:`gui` argument.
2495 optionally selected with the optional :param:`gui` argument.
2496
2496
2497 Parameters
2497 Parameters
2498 ----------
2498 ----------
2499 gui : optional, string
2499 gui : optional, string
2500
2500
2501 If given, dictates the choice of matplotlib GUI backend to use
2501 If given, dictates the choice of matplotlib GUI backend to use
2502 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
2502 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
2503 'gtk'), otherwise we use the default chosen by matplotlib (as
2503 'gtk'), otherwise we use the default chosen by matplotlib (as
2504 dictated by the matplotlib build-time options plus the user's
2504 dictated by the matplotlib build-time options plus the user's
2505 matplotlibrc configuration file).
2505 matplotlibrc configuration file).
2506 """
2506 """
2507 # We want to prevent the loading of pylab to pollute the user's
2507 # We want to prevent the loading of pylab to pollute the user's
2508 # namespace as shown by the %who* magics, so we execute the activation
2508 # namespace as shown by the %who* magics, so we execute the activation
2509 # code in an empty namespace, and we update *both* user_ns and
2509 # code in an empty namespace, and we update *both* user_ns and
2510 # user_ns_hidden with this information.
2510 # user_ns_hidden with this information.
2511 ns = {}
2511 ns = {}
2512 gui = pylab_activate(ns, gui)
2512 gui = pylab_activate(ns, gui)
2513 self.user_ns.update(ns)
2513 self.user_ns.update(ns)
2514 self.user_ns_hidden.update(ns)
2514 self.user_ns_hidden.update(ns)
2515 # Now we must activate the gui pylab wants to use, and fix %run to take
2515 # Now we must activate the gui pylab wants to use, and fix %run to take
2516 # plot updates into account
2516 # plot updates into account
2517 enable_gui(gui)
2517 enable_gui(gui)
2518 self.magic_run = self._pylab_magic_run
2518 self.magic_run = self._pylab_magic_run
2519
2519
2520 #-------------------------------------------------------------------------
2520 #-------------------------------------------------------------------------
2521 # Things related to IPython exiting
2521 # Things related to IPython exiting
2522 #-------------------------------------------------------------------------
2522 #-------------------------------------------------------------------------
2523
2523
2524 def ask_exit(self):
2524 def ask_exit(self):
2525 """ Ask the shell to exit. Can be overiden and used as a callback. """
2525 """ Ask the shell to exit. Can be overiden and used as a callback. """
2526 self.exit_now = True
2526 self.exit_now = True
2527
2527
2528 def exit(self):
2528 def exit(self):
2529 """Handle interactive exit.
2529 """Handle interactive exit.
2530
2530
2531 This method calls the ask_exit callback."""
2531 This method calls the ask_exit callback."""
2532 if self.confirm_exit:
2532 if self.confirm_exit:
2533 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2533 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2534 self.ask_exit()
2534 self.ask_exit()
2535 else:
2535 else:
2536 self.ask_exit()
2536 self.ask_exit()
2537
2537
2538 def atexit_operations(self):
2538 def atexit_operations(self):
2539 """This will be executed at the time of exit.
2539 """This will be executed at the time of exit.
2540
2540
2541 Saving of persistent data should be performed here.
2541 Saving of persistent data should be performed here.
2542 """
2542 """
2543 self.savehist()
2543 self.savehist()
2544
2544
2545 # Cleanup all tempfiles left around
2545 # Cleanup all tempfiles left around
2546 for tfile in self.tempfiles:
2546 for tfile in self.tempfiles:
2547 try:
2547 try:
2548 os.unlink(tfile)
2548 os.unlink(tfile)
2549 except OSError:
2549 except OSError:
2550 pass
2550 pass
2551
2551
2552 # Clear all user namespaces to release all references cleanly.
2552 # Clear all user namespaces to release all references cleanly.
2553 self.reset()
2553 self.reset()
2554
2554
2555 # Run user hooks
2555 # Run user hooks
2556 self.hooks.shutdown_hook()
2556 self.hooks.shutdown_hook()
2557
2557
2558 def cleanup(self):
2558 def cleanup(self):
2559 self.restore_sys_module_state()
2559 self.restore_sys_module_state()
2560
2560
2561
2561
@@ -1,214 +1,214 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.core.component
4 Tests for IPython.core.component
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from unittest import TestCase
23 from unittest import TestCase
24
24
25 from IPython.core.component import Component, ComponentError
25 from IPython.core.component import Component, ComponentError
26 from IPython.utils.traitlets import (
26 from IPython.utils.traitlets import (
27 TraitletError, Int, Float, Str
27 TraitError, Int, Float, Str
28 )
28 )
29 from IPython.config.loader import Config
29 from IPython.config.loader import Config
30
30
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Test cases
33 # Test cases
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36
36
37 class TestComponentMeta(TestCase):
37 class TestComponentMeta(TestCase):
38
38
39 def test_get_instances(self):
39 def test_get_instances(self):
40 class BaseComponent(Component):
40 class BaseComponent(Component):
41 pass
41 pass
42 c1 = BaseComponent(None)
42 c1 = BaseComponent(None)
43 c2 = BaseComponent(c1)
43 c2 = BaseComponent(c1)
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
45
45
46 def test_get_instances_subclass(self):
46 def test_get_instances_subclass(self):
47 class MyComponent(Component):
47 class MyComponent(Component):
48 pass
48 pass
49 class MyOtherComponent(MyComponent):
49 class MyOtherComponent(MyComponent):
50 pass
50 pass
51 c1 = MyComponent(None)
51 c1 = MyComponent(None)
52 c2 = MyOtherComponent(c1)
52 c2 = MyOtherComponent(c1)
53 c3 = MyOtherComponent(c2)
53 c3 = MyOtherComponent(c2)
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
56
56
57 def test_get_instances_root(self):
57 def test_get_instances_root(self):
58 class MyComponent(Component):
58 class MyComponent(Component):
59 pass
59 pass
60 class MyOtherComponent(MyComponent):
60 class MyOtherComponent(MyComponent):
61 pass
61 pass
62 c1 = MyComponent(None)
62 c1 = MyComponent(None)
63 c2 = MyOtherComponent(c1)
63 c2 = MyOtherComponent(c1)
64 c3 = MyOtherComponent(c2)
64 c3 = MyOtherComponent(c2)
65 c4 = MyComponent(None)
65 c4 = MyComponent(None)
66 c5 = MyComponent(c4)
66 c5 = MyComponent(c4)
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
69
69
70
70
71 class TestComponent(TestCase):
71 class TestComponent(TestCase):
72
72
73 def test_parent_child(self):
73 def test_parent_child(self):
74 c1 = Component(None)
74 c1 = Component(None)
75 c2 = Component(c1)
75 c2 = Component(c1)
76 c3 = Component(c1)
76 c3 = Component(c1)
77 c4 = Component(c3)
77 c4 = Component(c3)
78 self.assertEquals(c1.parent, None)
78 self.assertEquals(c1.parent, None)
79 self.assertEquals(c2.parent, c1)
79 self.assertEquals(c2.parent, c1)
80 self.assertEquals(c3.parent, c1)
80 self.assertEquals(c3.parent, c1)
81 self.assertEquals(c4.parent, c3)
81 self.assertEquals(c4.parent, c3)
82 self.assertEquals(c1.children, [c2, c3])
82 self.assertEquals(c1.children, [c2, c3])
83 self.assertEquals(c2.children, [])
83 self.assertEquals(c2.children, [])
84 self.assertEquals(c3.children, [c4])
84 self.assertEquals(c3.children, [c4])
85 self.assertEquals(c4.children, [])
85 self.assertEquals(c4.children, [])
86
86
87 def test_root(self):
87 def test_root(self):
88 c1 = Component(None)
88 c1 = Component(None)
89 c2 = Component(c1)
89 c2 = Component(c1)
90 c3 = Component(c1)
90 c3 = Component(c1)
91 c4 = Component(c3)
91 c4 = Component(c3)
92 self.assertEquals(c1.root, c1.root)
92 self.assertEquals(c1.root, c1.root)
93 self.assertEquals(c2.root, c1)
93 self.assertEquals(c2.root, c1)
94 self.assertEquals(c3.root, c1)
94 self.assertEquals(c3.root, c1)
95 self.assertEquals(c4.root, c1)
95 self.assertEquals(c4.root, c1)
96
96
97 def test_change_parent(self):
97 def test_change_parent(self):
98 c1 = Component(None)
98 c1 = Component(None)
99 c2 = Component(None)
99 c2 = Component(None)
100 c3 = Component(c1)
100 c3 = Component(c1)
101 self.assertEquals(c3.root, c1)
101 self.assertEquals(c3.root, c1)
102 self.assertEquals(c3.parent, c1)
102 self.assertEquals(c3.parent, c1)
103 self.assertEquals(c1.children,[c3])
103 self.assertEquals(c1.children,[c3])
104 c3.parent = c2
104 c3.parent = c2
105 self.assertEquals(c3.root, c2)
105 self.assertEquals(c3.root, c2)
106 self.assertEquals(c3.parent, c2)
106 self.assertEquals(c3.parent, c2)
107 self.assertEquals(c2.children,[c3])
107 self.assertEquals(c2.children,[c3])
108 self.assertEquals(c1.children,[])
108 self.assertEquals(c1.children,[])
109
109
110 def test_subclass_parent(self):
110 def test_subclass_parent(self):
111 c1 = Component(None)
111 c1 = Component(None)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
112 self.assertRaises(TraitError, setattr, c1, 'parent', 10)
113
113
114 class MyComponent(Component):
114 class MyComponent(Component):
115 pass
115 pass
116 c1 = Component(None)
116 c1 = Component(None)
117 c2 = MyComponent(c1)
117 c2 = MyComponent(c1)
118 self.assertEquals(MyComponent.parent.this_class, Component)
118 self.assertEquals(MyComponent.parent.this_class, Component)
119 self.assertEquals(c2.parent, c1)
119 self.assertEquals(c2.parent, c1)
120
120
121 def test_bad_root(self):
121 def test_bad_root(self):
122 c1 = Component(None)
122 c1 = Component(None)
123 c2 = Component(None)
123 c2 = Component(None)
124 c3 = Component(None)
124 c3 = Component(None)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
126 c1.parent = c2
126 c1.parent = c2
127 self.assertEquals(c1.root, c2)
127 self.assertEquals(c1.root, c2)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
129
129
130
130
131 class TestComponentConfig(TestCase):
131 class TestComponentConfig(TestCase):
132
132
133 def test_default(self):
133 def test_default(self):
134 c1 = Component(None)
134 c1 = Component(None)
135 c2 = Component(c1)
135 c2 = Component(c1)
136 c3 = Component(c2)
136 c3 = Component(c2)
137 self.assertEquals(c1.config, c2.config)
137 self.assertEquals(c1.config, c2.config)
138 self.assertEquals(c2.config, c3.config)
138 self.assertEquals(c2.config, c3.config)
139
139
140 def test_custom(self):
140 def test_custom(self):
141 config = Config()
141 config = Config()
142 config.foo = 'foo'
142 config.foo = 'foo'
143 config.bar = 'bar'
143 config.bar = 'bar'
144 c1 = Component(None, config=config)
144 c1 = Component(None, config=config)
145 c2 = Component(c1)
145 c2 = Component(c1)
146 c3 = Component(c2)
146 c3 = Component(c2)
147 self.assertEquals(c1.config, config)
147 self.assertEquals(c1.config, config)
148 self.assertEquals(c2.config, config)
148 self.assertEquals(c2.config, config)
149 self.assertEquals(c3.config, config)
149 self.assertEquals(c3.config, config)
150 # Test that copies are not made
150 # Test that copies are not made
151 self.assert_(c1.config is config)
151 self.assert_(c1.config is config)
152 self.assert_(c2.config is config)
152 self.assert_(c2.config is config)
153 self.assert_(c3.config is config)
153 self.assert_(c3.config is config)
154 self.assert_(c1.config is c2.config)
154 self.assert_(c1.config is c2.config)
155 self.assert_(c2.config is c3.config)
155 self.assert_(c2.config is c3.config)
156
156
157 def test_inheritance(self):
157 def test_inheritance(self):
158 class MyComponent(Component):
158 class MyComponent(Component):
159 a = Int(1, config=True)
159 a = Int(1, config=True)
160 b = Float(1.0, config=True)
160 b = Float(1.0, config=True)
161 c = Str('no config')
161 c = Str('no config')
162 config = Config()
162 config = Config()
163 config.MyComponent.a = 2
163 config.MyComponent.a = 2
164 config.MyComponent.b = 2.0
164 config.MyComponent.b = 2.0
165 c1 = MyComponent(None, config=config)
165 c1 = MyComponent(None, config=config)
166 c2 = MyComponent(c1)
166 c2 = MyComponent(c1)
167 self.assertEquals(c1.a, config.MyComponent.a)
167 self.assertEquals(c1.a, config.MyComponent.a)
168 self.assertEquals(c1.b, config.MyComponent.b)
168 self.assertEquals(c1.b, config.MyComponent.b)
169 self.assertEquals(c2.a, config.MyComponent.a)
169 self.assertEquals(c2.a, config.MyComponent.a)
170 self.assertEquals(c2.b, config.MyComponent.b)
170 self.assertEquals(c2.b, config.MyComponent.b)
171 c4 = MyComponent(c2, config=Config())
171 c4 = MyComponent(c2, config=Config())
172 self.assertEquals(c4.a, 1)
172 self.assertEquals(c4.a, 1)
173 self.assertEquals(c4.b, 1.0)
173 self.assertEquals(c4.b, 1.0)
174
174
175 def test_parent(self):
175 def test_parent(self):
176 class Foo(Component):
176 class Foo(Component):
177 a = Int(0, config=True)
177 a = Int(0, config=True)
178 b = Str('nope', config=True)
178 b = Str('nope', config=True)
179 class Bar(Foo):
179 class Bar(Foo):
180 b = Str('gotit', config=False)
180 b = Str('gotit', config=False)
181 c = Float(config=True)
181 c = Float(config=True)
182 config = Config()
182 config = Config()
183 config.Foo.a = 10
183 config.Foo.a = 10
184 config.Foo.b = "wow"
184 config.Foo.b = "wow"
185 config.Bar.b = 'later'
185 config.Bar.b = 'later'
186 config.Bar.c = 100.0
186 config.Bar.c = 100.0
187 f = Foo(None, config=config)
187 f = Foo(None, config=config)
188 b = Bar(f)
188 b = Bar(f)
189 self.assertEquals(f.a, 10)
189 self.assertEquals(f.a, 10)
190 self.assertEquals(f.b, 'wow')
190 self.assertEquals(f.b, 'wow')
191 self.assertEquals(b.b, 'gotit')
191 self.assertEquals(b.b, 'gotit')
192 self.assertEquals(b.c, 100.0)
192 self.assertEquals(b.c, 100.0)
193
193
194
194
195 class TestComponentName(TestCase):
195 class TestComponentName(TestCase):
196
196
197 def test_default(self):
197 def test_default(self):
198 class MyComponent(Component):
198 class MyComponent(Component):
199 pass
199 pass
200 c1 = Component(None)
200 c1 = Component(None)
201 c2 = MyComponent(None)
201 c2 = MyComponent(None)
202 c3 = Component(c2)
202 c3 = Component(c2)
203 self.assertNotEquals(c1.name, c2.name)
203 self.assertNotEquals(c1.name, c2.name)
204 self.assertNotEquals(c1.name, c3.name)
204 self.assertNotEquals(c1.name, c3.name)
205
205
206 def test_manual(self):
206 def test_manual(self):
207 class MyComponent(Component):
207 class MyComponent(Component):
208 pass
208 pass
209 c1 = Component(None, name='foo')
209 c1 = Component(None, name='foo')
210 c2 = MyComponent(None, name='bar')
210 c2 = MyComponent(None, name='bar')
211 c3 = Component(c2, name='bah')
211 c3 = Component(c2, name='bah')
212 self.assertEquals(c1.name, 'foo')
212 self.assertEquals(c1.name, 'foo')
213 self.assertEquals(c2.name, 'bar')
213 self.assertEquals(c2.name, 'bar')
214 self.assertEquals(c3.name, 'bah')
214 self.assertEquals(c3.name, 'bah')
@@ -1,686 +1,686 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.utils.traitlets.
4 Tests for IPython.utils.traitlets.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
10 and is licensed under the BSD license. Also, many of the ideas also come
10 and is licensed under the BSD license. Also, many of the ideas also come
11 from enthought.traits even though our implementation is very different.
11 from enthought.traits even though our implementation is very different.
12 """
12 """
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Copyright (C) 2008-2009 The IPython Development Team
15 # Copyright (C) 2008-2009 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 HasTraitlets, MetaHasTraitlets, TraitletType, Any,
28 HasTraits, MetaHasTraits, TraitType, Any,
29 Int, Long, Float, Complex, Str, Unicode, TraitletError,
29 Int, Long, Float, Complex, Str, Unicode, TraitError,
30 Undefined, Type, This, Instance
30 Undefined, Type, This, Instance
31 )
31 )
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Helper classes for testing
35 # Helper classes for testing
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 class HasTraitletsStub(HasTraitlets):
39 class HasTraitsStub(HasTraits):
40
40
41 def _notify_traitlet(self, name, old, new):
41 def _notify_trait(self, name, old, new):
42 self._notify_name = name
42 self._notify_name = name
43 self._notify_old = old
43 self._notify_old = old
44 self._notify_new = new
44 self._notify_new = new
45
45
46
46
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48 # Test classes
48 # Test classes
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 class TestTraitletType(TestCase):
52 class TestTraitType(TestCase):
53
53
54 def test_get_undefined(self):
54 def test_get_undefined(self):
55 class A(HasTraitlets):
55 class A(HasTraits):
56 a = TraitletType
56 a = TraitType
57 a = A()
57 a = A()
58 self.assertEquals(a.a, Undefined)
58 self.assertEquals(a.a, Undefined)
59
59
60 def test_set(self):
60 def test_set(self):
61 class A(HasTraitletsStub):
61 class A(HasTraitsStub):
62 a = TraitletType
62 a = TraitType
63
63
64 a = A()
64 a = A()
65 a.a = 10
65 a.a = 10
66 self.assertEquals(a.a, 10)
66 self.assertEquals(a.a, 10)
67 self.assertEquals(a._notify_name, 'a')
67 self.assertEquals(a._notify_name, 'a')
68 self.assertEquals(a._notify_old, Undefined)
68 self.assertEquals(a._notify_old, Undefined)
69 self.assertEquals(a._notify_new, 10)
69 self.assertEquals(a._notify_new, 10)
70
70
71 def test_validate(self):
71 def test_validate(self):
72 class MyTT(TraitletType):
72 class MyTT(TraitType):
73 def validate(self, inst, value):
73 def validate(self, inst, value):
74 return -1
74 return -1
75 class A(HasTraitletsStub):
75 class A(HasTraitsStub):
76 tt = MyTT
76 tt = MyTT
77
77
78 a = A()
78 a = A()
79 a.tt = 10
79 a.tt = 10
80 self.assertEquals(a.tt, -1)
80 self.assertEquals(a.tt, -1)
81
81
82 def test_default_validate(self):
82 def test_default_validate(self):
83 class MyIntTT(TraitletType):
83 class MyIntTT(TraitType):
84 def validate(self, obj, value):
84 def validate(self, obj, value):
85 if isinstance(value, int):
85 if isinstance(value, int):
86 return value
86 return value
87 self.error(obj, value)
87 self.error(obj, value)
88 class A(HasTraitlets):
88 class A(HasTraits):
89 tt = MyIntTT(10)
89 tt = MyIntTT(10)
90 a = A()
90 a = A()
91 self.assertEquals(a.tt, 10)
91 self.assertEquals(a.tt, 10)
92
92
93 # Defaults are validated when the HasTraitlets is instantiated
93 # Defaults are validated when the HasTraits is instantiated
94 class B(HasTraitlets):
94 class B(HasTraits):
95 tt = MyIntTT('bad default')
95 tt = MyIntTT('bad default')
96 self.assertRaises(TraitletError, B)
96 self.assertRaises(TraitError, B)
97
97
98 def test_is_valid_for(self):
98 def test_is_valid_for(self):
99 class MyTT(TraitletType):
99 class MyTT(TraitType):
100 def is_valid_for(self, value):
100 def is_valid_for(self, value):
101 return True
101 return True
102 class A(HasTraitlets):
102 class A(HasTraits):
103 tt = MyTT
103 tt = MyTT
104
104
105 a = A()
105 a = A()
106 a.tt = 10
106 a.tt = 10
107 self.assertEquals(a.tt, 10)
107 self.assertEquals(a.tt, 10)
108
108
109 def test_value_for(self):
109 def test_value_for(self):
110 class MyTT(TraitletType):
110 class MyTT(TraitType):
111 def value_for(self, value):
111 def value_for(self, value):
112 return 20
112 return 20
113 class A(HasTraitlets):
113 class A(HasTraits):
114 tt = MyTT
114 tt = MyTT
115
115
116 a = A()
116 a = A()
117 a.tt = 10
117 a.tt = 10
118 self.assertEquals(a.tt, 20)
118 self.assertEquals(a.tt, 20)
119
119
120 def test_info(self):
120 def test_info(self):
121 class A(HasTraitlets):
121 class A(HasTraits):
122 tt = TraitletType
122 tt = TraitType
123 a = A()
123 a = A()
124 self.assertEquals(A.tt.info(), 'any value')
124 self.assertEquals(A.tt.info(), 'any value')
125
125
126 def test_error(self):
126 def test_error(self):
127 class A(HasTraitlets):
127 class A(HasTraits):
128 tt = TraitletType
128 tt = TraitType
129 a = A()
129 a = A()
130 self.assertRaises(TraitletError, A.tt.error, a, 10)
130 self.assertRaises(TraitError, A.tt.error, a, 10)
131
131
132
132
133 class TestHasTraitletsMeta(TestCase):
133 class TestHasTraitsMeta(TestCase):
134
134
135 def test_metaclass(self):
135 def test_metaclass(self):
136 self.assertEquals(type(HasTraitlets), MetaHasTraitlets)
136 self.assertEquals(type(HasTraits), MetaHasTraits)
137
137
138 class A(HasTraitlets):
138 class A(HasTraits):
139 a = Int
139 a = Int
140
140
141 a = A()
141 a = A()
142 self.assertEquals(type(a.__class__), MetaHasTraitlets)
142 self.assertEquals(type(a.__class__), MetaHasTraits)
143 self.assertEquals(a.a,0)
143 self.assertEquals(a.a,0)
144 a.a = 10
144 a.a = 10
145 self.assertEquals(a.a,10)
145 self.assertEquals(a.a,10)
146
146
147 class B(HasTraitlets):
147 class B(HasTraits):
148 b = Int()
148 b = Int()
149
149
150 b = B()
150 b = B()
151 self.assertEquals(b.b,0)
151 self.assertEquals(b.b,0)
152 b.b = 10
152 b.b = 10
153 self.assertEquals(b.b,10)
153 self.assertEquals(b.b,10)
154
154
155 class C(HasTraitlets):
155 class C(HasTraits):
156 c = Int(30)
156 c = Int(30)
157
157
158 c = C()
158 c = C()
159 self.assertEquals(c.c,30)
159 self.assertEquals(c.c,30)
160 c.c = 10
160 c.c = 10
161 self.assertEquals(c.c,10)
161 self.assertEquals(c.c,10)
162
162
163 def test_this_class(self):
163 def test_this_class(self):
164 class A(HasTraitlets):
164 class A(HasTraits):
165 t = This()
165 t = This()
166 tt = This()
166 tt = This()
167 class B(A):
167 class B(A):
168 tt = This()
168 tt = This()
169 ttt = This()
169 ttt = This()
170 self.assertEquals(A.t.this_class, A)
170 self.assertEquals(A.t.this_class, A)
171 self.assertEquals(B.t.this_class, A)
171 self.assertEquals(B.t.this_class, A)
172 self.assertEquals(B.tt.this_class, B)
172 self.assertEquals(B.tt.this_class, B)
173 self.assertEquals(B.ttt.this_class, B)
173 self.assertEquals(B.ttt.this_class, B)
174
174
175 class TestHasTraitletsNotify(TestCase):
175 class TestHasTraitsNotify(TestCase):
176
176
177 def setUp(self):
177 def setUp(self):
178 self._notify1 = []
178 self._notify1 = []
179 self._notify2 = []
179 self._notify2 = []
180
180
181 def notify1(self, name, old, new):
181 def notify1(self, name, old, new):
182 self._notify1.append((name, old, new))
182 self._notify1.append((name, old, new))
183
183
184 def notify2(self, name, old, new):
184 def notify2(self, name, old, new):
185 self._notify2.append((name, old, new))
185 self._notify2.append((name, old, new))
186
186
187 def test_notify_all(self):
187 def test_notify_all(self):
188
188
189 class A(HasTraitlets):
189 class A(HasTraits):
190 a = Int
190 a = Int
191 b = Float
191 b = Float
192
192
193 a = A()
193 a = A()
194 a.on_traitlet_change(self.notify1)
194 a.on_trait_change(self.notify1)
195 a.a = 0
195 a.a = 0
196 self.assertEquals(len(self._notify1),0)
196 self.assertEquals(len(self._notify1),0)
197 a.b = 0.0
197 a.b = 0.0
198 self.assertEquals(len(self._notify1),0)
198 self.assertEquals(len(self._notify1),0)
199 a.a = 10
199 a.a = 10
200 self.assert_(('a',0,10) in self._notify1)
200 self.assert_(('a',0,10) in self._notify1)
201 a.b = 10.0
201 a.b = 10.0
202 self.assert_(('b',0.0,10.0) in self._notify1)
202 self.assert_(('b',0.0,10.0) in self._notify1)
203 self.assertRaises(TraitletError,setattr,a,'a','bad string')
203 self.assertRaises(TraitError,setattr,a,'a','bad string')
204 self.assertRaises(TraitletError,setattr,a,'b','bad string')
204 self.assertRaises(TraitError,setattr,a,'b','bad string')
205 self._notify1 = []
205 self._notify1 = []
206 a.on_traitlet_change(self.notify1,remove=True)
206 a.on_trait_change(self.notify1,remove=True)
207 a.a = 20
207 a.a = 20
208 a.b = 20.0
208 a.b = 20.0
209 self.assertEquals(len(self._notify1),0)
209 self.assertEquals(len(self._notify1),0)
210
210
211 def test_notify_one(self):
211 def test_notify_one(self):
212
212
213 class A(HasTraitlets):
213 class A(HasTraits):
214 a = Int
214 a = Int
215 b = Float
215 b = Float
216
216
217 a = A()
217 a = A()
218 a.on_traitlet_change(self.notify1, 'a')
218 a.on_trait_change(self.notify1, 'a')
219 a.a = 0
219 a.a = 0
220 self.assertEquals(len(self._notify1),0)
220 self.assertEquals(len(self._notify1),0)
221 a.a = 10
221 a.a = 10
222 self.assert_(('a',0,10) in self._notify1)
222 self.assert_(('a',0,10) in self._notify1)
223 self.assertRaises(TraitletError,setattr,a,'a','bad string')
223 self.assertRaises(TraitError,setattr,a,'a','bad string')
224
224
225 def test_subclass(self):
225 def test_subclass(self):
226
226
227 class A(HasTraitlets):
227 class A(HasTraits):
228 a = Int
228 a = Int
229
229
230 class B(A):
230 class B(A):
231 b = Float
231 b = Float
232
232
233 b = B()
233 b = B()
234 self.assertEquals(b.a,0)
234 self.assertEquals(b.a,0)
235 self.assertEquals(b.b,0.0)
235 self.assertEquals(b.b,0.0)
236 b.a = 100
236 b.a = 100
237 b.b = 100.0
237 b.b = 100.0
238 self.assertEquals(b.a,100)
238 self.assertEquals(b.a,100)
239 self.assertEquals(b.b,100.0)
239 self.assertEquals(b.b,100.0)
240
240
241 def test_notify_subclass(self):
241 def test_notify_subclass(self):
242
242
243 class A(HasTraitlets):
243 class A(HasTraits):
244 a = Int
244 a = Int
245
245
246 class B(A):
246 class B(A):
247 b = Float
247 b = Float
248
248
249 b = B()
249 b = B()
250 b.on_traitlet_change(self.notify1, 'a')
250 b.on_trait_change(self.notify1, 'a')
251 b.on_traitlet_change(self.notify2, 'b')
251 b.on_trait_change(self.notify2, 'b')
252 b.a = 0
252 b.a = 0
253 b.b = 0.0
253 b.b = 0.0
254 self.assertEquals(len(self._notify1),0)
254 self.assertEquals(len(self._notify1),0)
255 self.assertEquals(len(self._notify2),0)
255 self.assertEquals(len(self._notify2),0)
256 b.a = 10
256 b.a = 10
257 b.b = 10.0
257 b.b = 10.0
258 self.assert_(('a',0,10) in self._notify1)
258 self.assert_(('a',0,10) in self._notify1)
259 self.assert_(('b',0.0,10.0) in self._notify2)
259 self.assert_(('b',0.0,10.0) in self._notify2)
260
260
261 def test_static_notify(self):
261 def test_static_notify(self):
262
262
263 class A(HasTraitlets):
263 class A(HasTraits):
264 a = Int
264 a = Int
265 _notify1 = []
265 _notify1 = []
266 def _a_changed(self, name, old, new):
266 def _a_changed(self, name, old, new):
267 self._notify1.append((name, old, new))
267 self._notify1.append((name, old, new))
268
268
269 a = A()
269 a = A()
270 a.a = 0
270 a.a = 0
271 # This is broken!!!
271 # This is broken!!!
272 self.assertEquals(len(a._notify1),0)
272 self.assertEquals(len(a._notify1),0)
273 a.a = 10
273 a.a = 10
274 self.assert_(('a',0,10) in a._notify1)
274 self.assert_(('a',0,10) in a._notify1)
275
275
276 class B(A):
276 class B(A):
277 b = Float
277 b = Float
278 _notify2 = []
278 _notify2 = []
279 def _b_changed(self, name, old, new):
279 def _b_changed(self, name, old, new):
280 self._notify2.append((name, old, new))
280 self._notify2.append((name, old, new))
281
281
282 b = B()
282 b = B()
283 b.a = 10
283 b.a = 10
284 b.b = 10.0
284 b.b = 10.0
285 self.assert_(('a',0,10) in b._notify1)
285 self.assert_(('a',0,10) in b._notify1)
286 self.assert_(('b',0.0,10.0) in b._notify2)
286 self.assert_(('b',0.0,10.0) in b._notify2)
287
287
288 def test_notify_args(self):
288 def test_notify_args(self):
289
289
290 def callback0():
290 def callback0():
291 self.cb = ()
291 self.cb = ()
292 def callback1(name):
292 def callback1(name):
293 self.cb = (name,)
293 self.cb = (name,)
294 def callback2(name, new):
294 def callback2(name, new):
295 self.cb = (name, new)
295 self.cb = (name, new)
296 def callback3(name, old, new):
296 def callback3(name, old, new):
297 self.cb = (name, old, new)
297 self.cb = (name, old, new)
298
298
299 class A(HasTraitlets):
299 class A(HasTraits):
300 a = Int
300 a = Int
301
301
302 a = A()
302 a = A()
303 a.on_traitlet_change(callback0, 'a')
303 a.on_trait_change(callback0, 'a')
304 a.a = 10
304 a.a = 10
305 self.assertEquals(self.cb,())
305 self.assertEquals(self.cb,())
306 a.on_traitlet_change(callback0, 'a', remove=True)
306 a.on_trait_change(callback0, 'a', remove=True)
307
307
308 a.on_traitlet_change(callback1, 'a')
308 a.on_trait_change(callback1, 'a')
309 a.a = 100
309 a.a = 100
310 self.assertEquals(self.cb,('a',))
310 self.assertEquals(self.cb,('a',))
311 a.on_traitlet_change(callback1, 'a', remove=True)
311 a.on_trait_change(callback1, 'a', remove=True)
312
312
313 a.on_traitlet_change(callback2, 'a')
313 a.on_trait_change(callback2, 'a')
314 a.a = 1000
314 a.a = 1000
315 self.assertEquals(self.cb,('a',1000))
315 self.assertEquals(self.cb,('a',1000))
316 a.on_traitlet_change(callback2, 'a', remove=True)
316 a.on_trait_change(callback2, 'a', remove=True)
317
317
318 a.on_traitlet_change(callback3, 'a')
318 a.on_trait_change(callback3, 'a')
319 a.a = 10000
319 a.a = 10000
320 self.assertEquals(self.cb,('a',1000,10000))
320 self.assertEquals(self.cb,('a',1000,10000))
321 a.on_traitlet_change(callback3, 'a', remove=True)
321 a.on_trait_change(callback3, 'a', remove=True)
322
322
323 self.assertEquals(len(a._traitlet_notifiers['a']),0)
323 self.assertEquals(len(a._trait_notifiers['a']),0)
324
324
325
325
326 class TestHasTraitlets(TestCase):
326 class TestHasTraits(TestCase):
327
327
328 def test_traitlet_names(self):
328 def test_trait_names(self):
329 class A(HasTraitlets):
329 class A(HasTraits):
330 i = Int
330 i = Int
331 f = Float
331 f = Float
332 a = A()
332 a = A()
333 self.assertEquals(a.traitlet_names(),['i','f'])
333 self.assertEquals(a.trait_names(),['i','f'])
334
334
335 def test_traitlet_metadata(self):
335 def test_trait_metadata(self):
336 class A(HasTraitlets):
336 class A(HasTraits):
337 i = Int(config_key='MY_VALUE')
337 i = Int(config_key='MY_VALUE')
338 a = A()
338 a = A()
339 self.assertEquals(a.traitlet_metadata('i','config_key'), 'MY_VALUE')
339 self.assertEquals(a.trait_metadata('i','config_key'), 'MY_VALUE')
340
340
341 def test_traitlets(self):
341 def test_traits(self):
342 class A(HasTraitlets):
342 class A(HasTraits):
343 i = Int
343 i = Int
344 f = Float
344 f = Float
345 a = A()
345 a = A()
346 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
346 self.assertEquals(a.traits(), dict(i=A.i, f=A.f))
347
347
348 def test_traitlets_metadata(self):
348 def test_traits_metadata(self):
349 class A(HasTraitlets):
349 class A(HasTraits):
350 i = Int(config_key='VALUE1', other_thing='VALUE2')
350 i = Int(config_key='VALUE1', other_thing='VALUE2')
351 f = Float(config_key='VALUE3', other_thing='VALUE2')
351 f = Float(config_key='VALUE3', other_thing='VALUE2')
352 j = Int(0)
352 j = Int(0)
353 a = A()
353 a = A()
354 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f, j=A.j))
354 self.assertEquals(a.traits(), dict(i=A.i, f=A.f, j=A.j))
355 traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2')
355 traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
356 self.assertEquals(traitlets, dict(i=A.i))
356 self.assertEquals(traits, dict(i=A.i))
357
357
358 # This passes, but it shouldn't because I am replicating a bug in
358 # This passes, but it shouldn't because I am replicating a bug in
359 # traits.
359 # traits.
360 traitlets = a.traitlets(config_key=lambda v: True)
360 traits = a.traits(config_key=lambda v: True)
361 self.assertEquals(traitlets, dict(i=A.i, f=A.f, j=A.j))
361 self.assertEquals(traits, dict(i=A.i, f=A.f, j=A.j))
362
362
363
363
364 #-----------------------------------------------------------------------------
364 #-----------------------------------------------------------------------------
365 # Tests for specific traitlet types
365 # Tests for specific trait types
366 #-----------------------------------------------------------------------------
366 #-----------------------------------------------------------------------------
367
367
368
368
369 class TestType(TestCase):
369 class TestType(TestCase):
370
370
371 def test_default(self):
371 def test_default(self):
372
372
373 class B(object): pass
373 class B(object): pass
374 class A(HasTraitlets):
374 class A(HasTraits):
375 klass = Type
375 klass = Type
376
376
377 a = A()
377 a = A()
378 self.assertEquals(a.klass, None)
378 self.assertEquals(a.klass, None)
379
379
380 a.klass = B
380 a.klass = B
381 self.assertEquals(a.klass, B)
381 self.assertEquals(a.klass, B)
382 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
382 self.assertRaises(TraitError, setattr, a, 'klass', 10)
383
383
384 def test_value(self):
384 def test_value(self):
385
385
386 class B(object): pass
386 class B(object): pass
387 class C(object): pass
387 class C(object): pass
388 class A(HasTraitlets):
388 class A(HasTraits):
389 klass = Type(B)
389 klass = Type(B)
390
390
391 a = A()
391 a = A()
392 self.assertEquals(a.klass, B)
392 self.assertEquals(a.klass, B)
393 self.assertRaises(TraitletError, setattr, a, 'klass', C)
393 self.assertRaises(TraitError, setattr, a, 'klass', C)
394 self.assertRaises(TraitletError, setattr, a, 'klass', object)
394 self.assertRaises(TraitError, setattr, a, 'klass', object)
395 a.klass = B
395 a.klass = B
396
396
397 def test_allow_none(self):
397 def test_allow_none(self):
398
398
399 class B(object): pass
399 class B(object): pass
400 class C(B): pass
400 class C(B): pass
401 class A(HasTraitlets):
401 class A(HasTraits):
402 klass = Type(B, allow_none=False)
402 klass = Type(B, allow_none=False)
403
403
404 a = A()
404 a = A()
405 self.assertEquals(a.klass, B)
405 self.assertEquals(a.klass, B)
406 self.assertRaises(TraitletError, setattr, a, 'klass', None)
406 self.assertRaises(TraitError, setattr, a, 'klass', None)
407 a.klass = C
407 a.klass = C
408 self.assertEquals(a.klass, C)
408 self.assertEquals(a.klass, C)
409
409
410 def test_validate_klass(self):
410 def test_validate_klass(self):
411
411
412 class A(HasTraitlets):
412 class A(HasTraits):
413 klass = Type('no strings allowed')
413 klass = Type('no strings allowed')
414
414
415 self.assertRaises(ImportError, A)
415 self.assertRaises(ImportError, A)
416
416
417 class A(HasTraitlets):
417 class A(HasTraits):
418 klass = Type('rub.adub.Duck')
418 klass = Type('rub.adub.Duck')
419
419
420 self.assertRaises(ImportError, A)
420 self.assertRaises(ImportError, A)
421
421
422 def test_validate_default(self):
422 def test_validate_default(self):
423
423
424 class B(object): pass
424 class B(object): pass
425 class A(HasTraitlets):
425 class A(HasTraits):
426 klass = Type('bad default', B)
426 klass = Type('bad default', B)
427
427
428 self.assertRaises(ImportError, A)
428 self.assertRaises(ImportError, A)
429
429
430 class C(HasTraitlets):
430 class C(HasTraits):
431 klass = Type(None, B, allow_none=False)
431 klass = Type(None, B, allow_none=False)
432
432
433 self.assertRaises(TraitletError, C)
433 self.assertRaises(TraitError, C)
434
434
435 def test_str_klass(self):
435 def test_str_klass(self):
436
436
437 class A(HasTraitlets):
437 class A(HasTraits):
438 klass = Type('IPython.utils.ipstruct.Struct')
438 klass = Type('IPython.utils.ipstruct.Struct')
439
439
440 from IPython.utils.ipstruct import Struct
440 from IPython.utils.ipstruct import Struct
441 a = A()
441 a = A()
442 a.klass = Struct
442 a.klass = Struct
443 self.assertEquals(a.klass, Struct)
443 self.assertEquals(a.klass, Struct)
444
444
445 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
445 self.assertRaises(TraitError, setattr, a, 'klass', 10)
446
446
447 class TestInstance(TestCase):
447 class TestInstance(TestCase):
448
448
449 def test_basic(self):
449 def test_basic(self):
450 class Foo(object): pass
450 class Foo(object): pass
451 class Bar(Foo): pass
451 class Bar(Foo): pass
452 class Bah(object): pass
452 class Bah(object): pass
453
453
454 class A(HasTraitlets):
454 class A(HasTraits):
455 inst = Instance(Foo)
455 inst = Instance(Foo)
456
456
457 a = A()
457 a = A()
458 self.assert_(a.inst is None)
458 self.assert_(a.inst is None)
459 a.inst = Foo()
459 a.inst = Foo()
460 self.assert_(isinstance(a.inst, Foo))
460 self.assert_(isinstance(a.inst, Foo))
461 a.inst = Bar()
461 a.inst = Bar()
462 self.assert_(isinstance(a.inst, Foo))
462 self.assert_(isinstance(a.inst, Foo))
463 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
463 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
464 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
464 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
465 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
465 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
466
466
467 def test_unique_default_value(self):
467 def test_unique_default_value(self):
468 class Foo(object): pass
468 class Foo(object): pass
469 class A(HasTraitlets):
469 class A(HasTraits):
470 inst = Instance(Foo,(),{})
470 inst = Instance(Foo,(),{})
471
471
472 a = A()
472 a = A()
473 b = A()
473 b = A()
474 self.assert_(a.inst is not b.inst)
474 self.assert_(a.inst is not b.inst)
475
475
476 def test_args_kw(self):
476 def test_args_kw(self):
477 class Foo(object):
477 class Foo(object):
478 def __init__(self, c): self.c = c
478 def __init__(self, c): self.c = c
479 class Bar(object): pass
479 class Bar(object): pass
480 class Bah(object):
480 class Bah(object):
481 def __init__(self, c, d):
481 def __init__(self, c, d):
482 self.c = c; self.d = d
482 self.c = c; self.d = d
483
483
484 class A(HasTraitlets):
484 class A(HasTraits):
485 inst = Instance(Foo, (10,))
485 inst = Instance(Foo, (10,))
486 a = A()
486 a = A()
487 self.assertEquals(a.inst.c, 10)
487 self.assertEquals(a.inst.c, 10)
488
488
489 class B(HasTraitlets):
489 class B(HasTraits):
490 inst = Instance(Bah, args=(10,), kw=dict(d=20))
490 inst = Instance(Bah, args=(10,), kw=dict(d=20))
491 b = B()
491 b = B()
492 self.assertEquals(b.inst.c, 10)
492 self.assertEquals(b.inst.c, 10)
493 self.assertEquals(b.inst.d, 20)
493 self.assertEquals(b.inst.d, 20)
494
494
495 class C(HasTraitlets):
495 class C(HasTraits):
496 inst = Instance(Foo)
496 inst = Instance(Foo)
497 c = C()
497 c = C()
498 self.assert_(c.inst is None)
498 self.assert_(c.inst is None)
499
499
500 def test_bad_default(self):
500 def test_bad_default(self):
501 class Foo(object): pass
501 class Foo(object): pass
502
502
503 class A(HasTraitlets):
503 class A(HasTraits):
504 inst = Instance(Foo, allow_none=False)
504 inst = Instance(Foo, allow_none=False)
505
505
506 self.assertRaises(TraitletError, A)
506 self.assertRaises(TraitError, A)
507
507
508 def test_instance(self):
508 def test_instance(self):
509 class Foo(object): pass
509 class Foo(object): pass
510
510
511 def inner():
511 def inner():
512 class A(HasTraitlets):
512 class A(HasTraits):
513 inst = Instance(Foo())
513 inst = Instance(Foo())
514
514
515 self.assertRaises(TraitletError, inner)
515 self.assertRaises(TraitError, inner)
516
516
517
517
518 class TestThis(TestCase):
518 class TestThis(TestCase):
519
519
520 def test_this_class(self):
520 def test_this_class(self):
521 class Foo(HasTraitlets):
521 class Foo(HasTraits):
522 this = This
522 this = This
523
523
524 f = Foo()
524 f = Foo()
525 self.assertEquals(f.this, None)
525 self.assertEquals(f.this, None)
526 g = Foo()
526 g = Foo()
527 f.this = g
527 f.this = g
528 self.assertEquals(f.this, g)
528 self.assertEquals(f.this, g)
529 self.assertRaises(TraitletError, setattr, f, 'this', 10)
529 self.assertRaises(TraitError, setattr, f, 'this', 10)
530
530
531 def test_this_inst(self):
531 def test_this_inst(self):
532 class Foo(HasTraitlets):
532 class Foo(HasTraits):
533 this = This()
533 this = This()
534
534
535 f = Foo()
535 f = Foo()
536 f.this = Foo()
536 f.this = Foo()
537 self.assert_(isinstance(f.this, Foo))
537 self.assert_(isinstance(f.this, Foo))
538
538
539 def test_subclass(self):
539 def test_subclass(self):
540 class Foo(HasTraitlets):
540 class Foo(HasTraits):
541 t = This()
541 t = This()
542 class Bar(Foo):
542 class Bar(Foo):
543 pass
543 pass
544 f = Foo()
544 f = Foo()
545 b = Bar()
545 b = Bar()
546 f.t = b
546 f.t = b
547 b.t = f
547 b.t = f
548 self.assertEquals(f.t, b)
548 self.assertEquals(f.t, b)
549 self.assertEquals(b.t, f)
549 self.assertEquals(b.t, f)
550
550
551 def test_subclass_override(self):
551 def test_subclass_override(self):
552 class Foo(HasTraitlets):
552 class Foo(HasTraits):
553 t = This()
553 t = This()
554 class Bar(Foo):
554 class Bar(Foo):
555 t = This()
555 t = This()
556 f = Foo()
556 f = Foo()
557 b = Bar()
557 b = Bar()
558 f.t = b
558 f.t = b
559 self.assertEquals(f.t, b)
559 self.assertEquals(f.t, b)
560 self.assertRaises(TraitletError, setattr, b, 't', f)
560 self.assertRaises(TraitError, setattr, b, 't', f)
561
561
562 class TraitletTestBase(TestCase):
562 class TraitTestBase(TestCase):
563 """A best testing class for basic traitlet types."""
563 """A best testing class for basic trait types."""
564
564
565 def assign(self, value):
565 def assign(self, value):
566 self.obj.value = value
566 self.obj.value = value
567
567
568 def coerce(self, value):
568 def coerce(self, value):
569 return value
569 return value
570
570
571 def test_good_values(self):
571 def test_good_values(self):
572 if hasattr(self, '_good_values'):
572 if hasattr(self, '_good_values'):
573 for value in self._good_values:
573 for value in self._good_values:
574 self.assign(value)
574 self.assign(value)
575 self.assertEquals(self.obj.value, self.coerce(value))
575 self.assertEquals(self.obj.value, self.coerce(value))
576
576
577 def test_bad_values(self):
577 def test_bad_values(self):
578 if hasattr(self, '_bad_values'):
578 if hasattr(self, '_bad_values'):
579 for value in self._bad_values:
579 for value in self._bad_values:
580 self.assertRaises(TraitletError, self.assign, value)
580 self.assertRaises(TraitError, self.assign, value)
581
581
582 def test_default_value(self):
582 def test_default_value(self):
583 if hasattr(self, '_default_value'):
583 if hasattr(self, '_default_value'):
584 self.assertEquals(self._default_value, self.obj.value)
584 self.assertEquals(self._default_value, self.obj.value)
585
585
586
586
587 class AnyTraitlet(HasTraitlets):
587 class AnyTrait(HasTraits):
588
588
589 value = Any
589 value = Any
590
590
591 class AnyTraitTest(TraitletTestBase):
591 class AnyTraitTest(TraitTestBase):
592
592
593 obj = AnyTraitlet()
593 obj = AnyTrait()
594
594
595 _default_value = None
595 _default_value = None
596 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
596 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
597 _bad_values = []
597 _bad_values = []
598
598
599
599
600 class IntTraitlet(HasTraitlets):
600 class IntTrait(HasTraits):
601
601
602 value = Int(99)
602 value = Int(99)
603
603
604 class TestInt(TraitletTestBase):
604 class TestInt(TraitTestBase):
605
605
606 obj = IntTraitlet()
606 obj = IntTrait()
607 _default_value = 99
607 _default_value = 99
608 _good_values = [10, -10]
608 _good_values = [10, -10]
609 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
609 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
610 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
610 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
611 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
611 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
612
612
613
613
614 class LongTraitlet(HasTraitlets):
614 class LongTrait(HasTraits):
615
615
616 value = Long(99L)
616 value = Long(99L)
617
617
618 class TestLong(TraitletTestBase):
618 class TestLong(TraitTestBase):
619
619
620 obj = LongTraitlet()
620 obj = LongTrait()
621
621
622 _default_value = 99L
622 _default_value = 99L
623 _good_values = [10, -10, 10L, -10L]
623 _good_values = [10, -10, 10L, -10L]
624 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
624 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
625 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
625 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
626 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
626 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
627 u'-10.1']
627 u'-10.1']
628
628
629
629
630 class FloatTraitlet(HasTraitlets):
630 class FloatTrait(HasTraits):
631
631
632 value = Float(99.0)
632 value = Float(99.0)
633
633
634 class TestFloat(TraitletTestBase):
634 class TestFloat(TraitTestBase):
635
635
636 obj = FloatTraitlet()
636 obj = FloatTrait()
637
637
638 _default_value = 99.0
638 _default_value = 99.0
639 _good_values = [10, -10, 10.1, -10.1]
639 _good_values = [10, -10, 10.1, -10.1]
640 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
640 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
641 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
641 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
642 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
642 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
643
643
644
644
645 class ComplexTraitlet(HasTraitlets):
645 class ComplexTrait(HasTraits):
646
646
647 value = Complex(99.0-99.0j)
647 value = Complex(99.0-99.0j)
648
648
649 class TestComplex(TraitletTestBase):
649 class TestComplex(TraitTestBase):
650
650
651 obj = ComplexTraitlet()
651 obj = ComplexTrait()
652
652
653 _default_value = 99.0-99.0j
653 _default_value = 99.0-99.0j
654 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
654 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
655 10.1j, 10.1+10.1j, 10.1-10.1j]
655 10.1j, 10.1+10.1j, 10.1-10.1j]
656 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
656 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
657
657
658
658
659 class StringTraitlet(HasTraitlets):
659 class StringTrait(HasTraits):
660
660
661 value = Str('string')
661 value = Str('string')
662
662
663 class TestString(TraitletTestBase):
663 class TestString(TraitTestBase):
664
664
665 obj = StringTraitlet()
665 obj = StringTrait()
666
666
667 _default_value = 'string'
667 _default_value = 'string'
668 _good_values = ['10', '-10', '10L',
668 _good_values = ['10', '-10', '10L',
669 '-10L', '10.1', '-10.1', 'string']
669 '-10L', '10.1', '-10.1', 'string']
670 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
670 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
671 ['ten'],{'ten': 10},(10,), None, u'string']
671 ['ten'],{'ten': 10},(10,), None, u'string']
672
672
673
673
674 class UnicodeTraitlet(HasTraitlets):
674 class UnicodeTrait(HasTraits):
675
675
676 value = Unicode(u'unicode')
676 value = Unicode(u'unicode')
677
677
678 class TestUnicode(TraitletTestBase):
678 class TestUnicode(TraitTestBase):
679
679
680 obj = UnicodeTraitlet()
680 obj = UnicodeTrait()
681
681
682 _default_value = u'unicode'
682 _default_value = u'unicode'
683 _good_values = ['10', '-10', '10L', '-10L', '10.1',
683 _good_values = ['10', '-10', '10L', '-10L', '10.1',
684 '-10.1', '', u'', 'string', u'string', ]
684 '-10.1', '', u'', 'string', u'string', ]
685 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
685 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
686 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
686 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
@@ -1,1013 +1,1025 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight Traits like module.
4 A lightweight Traits like module.
5
5
6 This is designed to provide a lightweight, simple, pure Python version of
6 This is designed to provide a lightweight, simple, pure Python version of
7 many of the capabilities of enthought.traits. This includes:
7 many of the capabilities of enthought.traits. This includes:
8
8
9 * Validation
9 * Validation
10 * Type specification with defaults
10 * Type specification with defaults
11 * Static and dynamic notification
11 * Static and dynamic notification
12 * Basic predefined types
12 * Basic predefined types
13 * An API that is similar to enthought.traits
13 * An API that is similar to enthought.traits
14
14
15 We don't support:
15 We don't support:
16
16
17 * Delegation
17 * Delegation
18 * Automatic GUI generation
18 * Automatic GUI generation
19 * A full set of trait types. Most importantly, we don't provide container
19 * A full set of trait types. Most importantly, we don't provide container
20 traitlets (list, dict, tuple) that can trigger notifications if their
20 traits (list, dict, tuple) that can trigger notifications if their
21 contents change.
21 contents change.
22 * API compatibility with enthought.traits
22 * API compatibility with enthought.traits
23
23
24 There are also some important difference in our design:
24 There are also some important difference in our design:
25
25
26 * enthought.traits does not validate default values. We do.
26 * enthought.traits does not validate default values. We do.
27
27
28 We choose to create this module because we need these capabilities, but
28 We choose to create this module because we need these capabilities, but
29 we need them to be pure Python so they work in all Python implementations,
29 we need them to be pure Python so they work in all Python implementations,
30 including Jython and IronPython.
30 including Jython and IronPython.
31
31
32 Authors:
32 Authors:
33
33
34 * Brian Granger
34 * Brian Granger
35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
36 and is licensed under the BSD license. Also, many of the ideas also come
36 and is licensed under the BSD license. Also, many of the ideas also come
37 from enthought.traits even though our implementation is very different.
37 from enthought.traits even though our implementation is very different.
38 """
38 """
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Copyright (C) 2008-2009 The IPython Development Team
41 # Copyright (C) 2008-2009 The IPython Development Team
42 #
42 #
43 # Distributed under the terms of the BSD License. The full license is in
43 # Distributed under the terms of the BSD License. The full license is in
44 # the file COPYING, distributed as part of this software.
44 # the file COPYING, distributed as part of this software.
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48 # Imports
48 # Imports
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 import inspect
52 import inspect
53 import sys
53 import sys
54 import types
54 import types
55 from types import (
55 from types import (
56 InstanceType, ClassType, FunctionType,
56 InstanceType, ClassType, FunctionType,
57 ListType, TupleType
57 ListType, TupleType
58 )
58 )
59
59
60 from IPython.utils.importstring import import_item
60 def import_item(name):
61 """Import and return bar given the string foo.bar."""
62 package = '.'.join(name.split('.')[0:-1])
63 obj = name.split('.')[-1]
64 execString = 'from %s import %s' % (package, obj)
65 try:
66 exec execString
67 except SyntaxError:
68 raise ImportError("Invalid class specification: %s" % name)
69 exec 'temp = %s' % obj
70 return temp
71
61
72
62 ClassTypes = (ClassType, type)
73 ClassTypes = (ClassType, type)
63
74
64 SequenceTypes = (ListType, TupleType)
75 SequenceTypes = (ListType, TupleType)
65
76
66 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
67 # Basic classes
78 # Basic classes
68 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
69
80
70
81
71 class NoDefaultSpecified ( object ): pass
82 class NoDefaultSpecified ( object ): pass
72 NoDefaultSpecified = NoDefaultSpecified()
83 NoDefaultSpecified = NoDefaultSpecified()
73
84
74
85
75 class Undefined ( object ): pass
86 class Undefined ( object ): pass
76 Undefined = Undefined()
87 Undefined = Undefined()
77
88
78
89 class TraitError(Exception):
79 class TraitletError(Exception):
80 pass
90 pass
81
91
82
83 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
84 # Utilities
93 # Utilities
85 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
86
95
87
96
88 def class_of ( object ):
97 def class_of ( object ):
89 """ Returns a string containing the class name of an object with the
98 """ Returns a string containing the class name of an object with the
90 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
99 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
91 'a PlotValue').
100 'a PlotValue').
92 """
101 """
93 if isinstance( object, basestring ):
102 if isinstance( object, basestring ):
94 return add_article( object )
103 return add_article( object )
95
104
96 return add_article( object.__class__.__name__ )
105 return add_article( object.__class__.__name__ )
97
106
98
107
99 def add_article ( name ):
108 def add_article ( name ):
100 """ Returns a string containing the correct indefinite article ('a' or 'an')
109 """ Returns a string containing the correct indefinite article ('a' or 'an')
101 prefixed to the specified string.
110 prefixed to the specified string.
102 """
111 """
103 if name[:1].lower() in 'aeiou':
112 if name[:1].lower() in 'aeiou':
104 return 'an ' + name
113 return 'an ' + name
105
114
106 return 'a ' + name
115 return 'a ' + name
107
116
108
117
109 def repr_type(obj):
118 def repr_type(obj):
110 """ Return a string representation of a value and its type for readable
119 """ Return a string representation of a value and its type for readable
111 error messages.
120 error messages.
112 """
121 """
113 the_type = type(obj)
122 the_type = type(obj)
114 if the_type is InstanceType:
123 if the_type is InstanceType:
115 # Old-style class.
124 # Old-style class.
116 the_type = obj.__class__
125 the_type = obj.__class__
117 msg = '%r %r' % (obj, the_type)
126 msg = '%r %r' % (obj, the_type)
118 return msg
127 return msg
119
128
120
129
121 def parse_notifier_name(name):
130 def parse_notifier_name(name):
122 """Convert the name argument to a list of names.
131 """Convert the name argument to a list of names.
123
132
124 Examples
133 Examples
125 --------
134 --------
126
135
127 >>> parse_notifier_name('a')
136 >>> parse_notifier_name('a')
128 ['a']
137 ['a']
129 >>> parse_notifier_name(['a','b'])
138 >>> parse_notifier_name(['a','b'])
130 ['a', 'b']
139 ['a', 'b']
131 >>> parse_notifier_name(None)
140 >>> parse_notifier_name(None)
132 ['anytraitlet']
141 ['anytrait']
133 """
142 """
134 if isinstance(name, str):
143 if isinstance(name, str):
135 return [name]
144 return [name]
136 elif name is None:
145 elif name is None:
137 return ['anytraitlet']
146 return ['anytrait']
138 elif isinstance(name, (list, tuple)):
147 elif isinstance(name, (list, tuple)):
139 for n in name:
148 for n in name:
140 assert isinstance(n, str), "names must be strings"
149 assert isinstance(n, str), "names must be strings"
141 return name
150 return name
142
151
143
152
144 class _SimpleTest:
153 class _SimpleTest:
145 def __init__ ( self, value ): self.value = value
154 def __init__ ( self, value ): self.value = value
146 def __call__ ( self, test ):
155 def __call__ ( self, test ):
147 return test == self.value
156 return test == self.value
148 def __repr__(self):
157 def __repr__(self):
149 return "<SimpleTest(%r)" % self.value
158 return "<SimpleTest(%r)" % self.value
150 def __str__(self):
159 def __str__(self):
151 return self.__repr__()
160 return self.__repr__()
152
161
153
162
154 def getmembers(object, predicate=None):
163 def getmembers(object, predicate=None):
155 """A safe version of inspect.getmembers that handles missing attributes.
164 """A safe version of inspect.getmembers that handles missing attributes.
156
165
157 This is useful when there are descriptor based attributes that for
166 This is useful when there are descriptor based attributes that for
158 some reason raise AttributeError even though they exist. This happens
167 some reason raise AttributeError even though they exist. This happens
159 in zope.inteface with the __provides__ attribute.
168 in zope.inteface with the __provides__ attribute.
160 """
169 """
161 results = []
170 results = []
162 for key in dir(object):
171 for key in dir(object):
163 try:
172 try:
164 value = getattr(object, key)
173 value = getattr(object, key)
165 except AttributeError:
174 except AttributeError:
166 pass
175 pass
167 else:
176 else:
168 if not predicate or predicate(value):
177 if not predicate or predicate(value):
169 results.append((key, value))
178 results.append((key, value))
170 results.sort()
179 results.sort()
171 return results
180 return results
172
181
173
182
174 #-----------------------------------------------------------------------------
183 #-----------------------------------------------------------------------------
175 # Base TraitletType for all traitlets
184 # Base TraitType for all traits
176 #-----------------------------------------------------------------------------
185 #-----------------------------------------------------------------------------
177
186
178
187
179 class TraitletType(object):
188 class TraitType(object):
180 """A base class for all traitlet descriptors.
189 """A base class for all trait descriptors.
181
190
182 Notes
191 Notes
183 -----
192 -----
184 Our implementation of traitlets is based on Python's descriptor
193 Our implementation of traits is based on Python's descriptor
185 prototol. This class is the base class for all such descriptors. The
194 prototol. This class is the base class for all such descriptors. The
186 only magic we use is a custom metaclass for the main :class:`HasTraitlets`
195 only magic we use is a custom metaclass for the main :class:`HasTraits`
187 class that does the following:
196 class that does the following:
188
197
189 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
198 1. Sets the :attr:`name` attribute of every :class:`TraitType`
190 instance in the class dict to the name of the attribute.
199 instance in the class dict to the name of the attribute.
191 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
200 2. Sets the :attr:`this_class` attribute of every :class:`TraitType`
192 instance in the class dict to the *class* that declared the traitlet.
201 instance in the class dict to the *class* that declared the trait.
193 This is used by the :class:`This` traitlet to allow subclasses to
202 This is used by the :class:`This` trait to allow subclasses to
194 accept superclasses for :class:`This` values.
203 accept superclasses for :class:`This` values.
195 """
204 """
196
205
197
206
198 metadata = {}
207 metadata = {}
199 default_value = Undefined
208 default_value = Undefined
200 info_text = 'any value'
209 info_text = 'any value'
201
210
202 def __init__(self, default_value=NoDefaultSpecified, **metadata):
211 def __init__(self, default_value=NoDefaultSpecified, **metadata):
203 """Create a TraitletType.
212 """Create a TraitType.
204 """
213 """
205 if default_value is not NoDefaultSpecified:
214 if default_value is not NoDefaultSpecified:
206 self.default_value = default_value
215 self.default_value = default_value
207
216
208 if len(metadata) > 0:
217 if len(metadata) > 0:
209 if len(self.metadata) > 0:
218 if len(self.metadata) > 0:
210 self._metadata = self.metadata.copy()
219 self._metadata = self.metadata.copy()
211 self._metadata.update(metadata)
220 self._metadata.update(metadata)
212 else:
221 else:
213 self._metadata = metadata
222 self._metadata = metadata
214 else:
223 else:
215 self._metadata = self.metadata
224 self._metadata = self.metadata
216
225
217 self.init()
226 self.init()
218
227
219 def init(self):
228 def init(self):
220 pass
229 pass
221
230
222 def get_default_value(self):
231 def get_default_value(self):
223 """Create a new instance of the default value."""
232 """Create a new instance of the default value."""
224 dv = self.default_value
233 dv = self.default_value
225 return dv
234 return dv
226
235
227 def instance_init(self, obj):
236 def instance_init(self, obj):
228 """This is called by :meth:`HasTraitlets.__new__` to finish init'ing.
237 """This is called by :meth:`HasTraits.__new__` to finish init'ing.
229
238
230 Some stages of initialization must be delayed until the parent
239 Some stages of initialization must be delayed until the parent
231 :class:`HasTraitlets` instance has been created. This method is
240 :class:`HasTraits` instance has been created. This method is
232 called in :meth:`HasTraitlets.__new__` after the instance has been
241 called in :meth:`HasTraits.__new__` after the instance has been
233 created.
242 created.
234
243
235 This method trigger the creation and validation of default values
244 This method trigger the creation and validation of default values
236 and also things like the resolution of str given class names in
245 and also things like the resolution of str given class names in
237 :class:`Type` and :class`Instance`.
246 :class:`Type` and :class`Instance`.
238
247
239 Parameters
248 Parameters
240 ----------
249 ----------
241 obj : :class:`HasTraitlets` instance
250 obj : :class:`HasTraits` instance
242 The parent :class:`HasTraitlets` instance that has just been
251 The parent :class:`HasTraits` instance that has just been
243 created.
252 created.
244 """
253 """
245 self.set_default_value(obj)
254 self.set_default_value(obj)
246
255
247 def set_default_value(self, obj):
256 def set_default_value(self, obj):
248 """Set the default value on a per instance basis.
257 """Set the default value on a per instance basis.
249
258
250 This method is called by :meth:`instance_init` to create and
259 This method is called by :meth:`instance_init` to create and
251 validate the default value. The creation and validation of
260 validate the default value. The creation and validation of
252 default values must be delayed until the parent :class:`HasTraitlets`
261 default values must be delayed until the parent :class:`HasTraits`
253 class has been instantiated.
262 class has been instantiated.
254 """
263 """
255 dv = self.get_default_value()
264 dv = self.get_default_value()
256 newdv = self._validate(obj, dv)
265 newdv = self._validate(obj, dv)
257 obj._traitlet_values[self.name] = newdv
266 obj._trait_values[self.name] = newdv
258
267
259 def __get__(self, obj, cls=None):
268 def __get__(self, obj, cls=None):
260 """Get the value of the traitlet by self.name for the instance.
269 """Get the value of the trait by self.name for the instance.
261
270
262 Default values are instantiated when :meth:`HasTraitlets.__new__`
271 Default values are instantiated when :meth:`HasTraits.__new__`
263 is called. Thus by the time this method gets called either the
272 is called. Thus by the time this method gets called either the
264 default value or a user defined value (they called :meth:`__set__`)
273 default value or a user defined value (they called :meth:`__set__`)
265 is in the :class:`HasTraitlets` instance.
274 is in the :class:`HasTraits` instance.
266 """
275 """
267 if obj is None:
276 if obj is None:
268 return self
277 return self
269 else:
278 else:
270 try:
279 try:
271 value = obj._traitlet_values[self.name]
280 value = obj._trait_values[self.name]
272 except:
281 except:
273 # HasTraitlets should call set_default_value to populate
282 # HasTraits should call set_default_value to populate
274 # this. So this should never be reached.
283 # this. So this should never be reached.
275 raise TraitletError('Unexpected error in TraitletType: '
284 raise TraitError('Unexpected error in TraitType: '
276 'default value not set properly')
285 'default value not set properly')
277 else:
286 else:
278 return value
287 return value
279
288
280 def __set__(self, obj, value):
289 def __set__(self, obj, value):
281 new_value = self._validate(obj, value)
290 new_value = self._validate(obj, value)
282 old_value = self.__get__(obj)
291 old_value = self.__get__(obj)
283 if old_value != new_value:
292 if old_value != new_value:
284 obj._traitlet_values[self.name] = new_value
293 obj._trait_values[self.name] = new_value
285 obj._notify_traitlet(self.name, old_value, new_value)
294 obj._notify_trait(self.name, old_value, new_value)
286
295
287 def _validate(self, obj, value):
296 def _validate(self, obj, value):
288 if hasattr(self, 'validate'):
297 if hasattr(self, 'validate'):
289 return self.validate(obj, value)
298 return self.validate(obj, value)
290 elif hasattr(self, 'is_valid_for'):
299 elif hasattr(self, 'is_valid_for'):
291 valid = self.is_valid_for(value)
300 valid = self.is_valid_for(value)
292 if valid:
301 if valid:
293 return value
302 return value
294 else:
303 else:
295 raise TraitletError('invalid value for type: %r' % value)
304 raise TraitError('invalid value for type: %r' % value)
296 elif hasattr(self, 'value_for'):
305 elif hasattr(self, 'value_for'):
297 return self.value_for(value)
306 return self.value_for(value)
298 else:
307 else:
299 return value
308 return value
300
309
301 def info(self):
310 def info(self):
302 return self.info_text
311 return self.info_text
303
312
304 def error(self, obj, value):
313 def error(self, obj, value):
305 if obj is not None:
314 if obj is not None:
306 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
315 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
307 % (self.name, class_of(obj),
316 % (self.name, class_of(obj),
308 self.info(), repr_type(value))
317 self.info(), repr_type(value))
309 else:
318 else:
310 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
319 e = "The '%s' trait must be %s, but a value of %r was specified." \
311 % (self.name, self.info(), repr_type(value))
320 % (self.name, self.info(), repr_type(value))
312 raise TraitletError(e)
321 raise TraitError(e)
313
322
314 def get_metadata(self, key):
323 def get_metadata(self, key):
315 return getattr(self, '_metadata', {}).get(key, None)
324 return getattr(self, '_metadata', {}).get(key, None)
316
325
317 def set_metadata(self, key, value):
326 def set_metadata(self, key, value):
318 getattr(self, '_metadata', {})[key] = value
327 getattr(self, '_metadata', {})[key] = value
319
328
320
329
321 #-----------------------------------------------------------------------------
330 #-----------------------------------------------------------------------------
322 # The HasTraitlets implementation
331 # The HasTraits implementation
323 #-----------------------------------------------------------------------------
332 #-----------------------------------------------------------------------------
324
333
325
334
326 class MetaHasTraitlets(type):
335 class MetaHasTraits(type):
327 """A metaclass for HasTraitlets.
336 """A metaclass for HasTraits.
328
337
329 This metaclass makes sure that any TraitletType class attributes are
338 This metaclass makes sure that any TraitType class attributes are
330 instantiated and sets their name attribute.
339 instantiated and sets their name attribute.
331 """
340 """
332
341
333 def __new__(mcls, name, bases, classdict):
342 def __new__(mcls, name, bases, classdict):
334 """Create the HasTraitlets class.
343 """Create the HasTraits class.
335
344
336 This instantiates all TraitletTypes in the class dict and sets their
345 This instantiates all TraitTypes in the class dict and sets their
337 :attr:`name` attribute.
346 :attr:`name` attribute.
338 """
347 """
339 # print "MetaHasTraitlets (mcls, name): ", mcls, name
348 # print "MetaHasTraitlets (mcls, name): ", mcls, name
340 # print "MetaHasTraitlets (bases): ", bases
349 # print "MetaHasTraitlets (bases): ", bases
341 # print "MetaHasTraitlets (classdict): ", classdict
350 # print "MetaHasTraitlets (classdict): ", classdict
342 for k,v in classdict.iteritems():
351 for k,v in classdict.iteritems():
343 if isinstance(v, TraitletType):
352 if isinstance(v, TraitType):
344 v.name = k
353 v.name = k
345 elif inspect.isclass(v):
354 elif inspect.isclass(v):
346 if issubclass(v, TraitletType):
355 if issubclass(v, TraitType):
347 vinst = v()
356 vinst = v()
348 vinst.name = k
357 vinst.name = k
349 classdict[k] = vinst
358 classdict[k] = vinst
350 return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict)
359 return super(MetaHasTraits, mcls).__new__(mcls, name, bases, classdict)
351
360
352 def __init__(cls, name, bases, classdict):
361 def __init__(cls, name, bases, classdict):
353 """Finish initializing the HasTraitlets class.
362 """Finish initializing the HasTraits class.
354
363
355 This sets the :attr:`this_class` attribute of each TraitletType in the
364 This sets the :attr:`this_class` attribute of each TraitType in the
356 class dict to the newly created class ``cls``.
365 class dict to the newly created class ``cls``.
357 """
366 """
358 for k, v in classdict.iteritems():
367 for k, v in classdict.iteritems():
359 if isinstance(v, TraitletType):
368 if isinstance(v, TraitType):
360 v.this_class = cls
369 v.this_class = cls
361 super(MetaHasTraitlets, cls).__init__(name, bases, classdict)
370 super(MetaHasTraits, cls).__init__(name, bases, classdict)
362
371
363 class HasTraitlets(object):
372 class HasTraits(object):
364
373
365 __metaclass__ = MetaHasTraitlets
374 __metaclass__ = MetaHasTraits
366
375
367 def __new__(cls, *args, **kw):
376 def __new__(cls, *args, **kw):
368 # This is needed because in Python 2.6 object.__new__ only accepts
377 # This is needed because in Python 2.6 object.__new__ only accepts
369 # the cls argument.
378 # the cls argument.
370 new_meth = super(HasTraitlets, cls).__new__
379 new_meth = super(HasTraits, cls).__new__
371 if new_meth is object.__new__:
380 if new_meth is object.__new__:
372 inst = new_meth(cls)
381 inst = new_meth(cls)
373 else:
382 else:
374 inst = new_meth(cls, *args, **kw)
383 inst = new_meth(cls, *args, **kw)
375 inst._traitlet_values = {}
384 inst._trait_values = {}
376 inst._traitlet_notifiers = {}
385 inst._trait_notifiers = {}
377 # Here we tell all the TraitletType instances to set their default
386 # Here we tell all the TraitType instances to set their default
378 # values on the instance.
387 # values on the instance.
379 for key in dir(cls):
388 for key in dir(cls):
380 # Some descriptors raise AttributeError like zope.interface's
389 # Some descriptors raise AttributeError like zope.interface's
381 # __provides__ attributes even though they exist. This causes
390 # __provides__ attributes even though they exist. This causes
382 # AttributeErrors even though they are listed in dir(cls).
391 # AttributeErrors even though they are listed in dir(cls).
383 try:
392 try:
384 value = getattr(cls, key)
393 value = getattr(cls, key)
385 except AttributeError:
394 except AttributeError:
386 pass
395 pass
387 else:
396 else:
388 if isinstance(value, TraitletType):
397 if isinstance(value, TraitType):
389 value.instance_init(inst)
398 value.instance_init(inst)
399
390 return inst
400 return inst
391
401
392 # def __init__(self):
402 # def __init__(self):
393 # self._traitlet_values = {}
403 # self._trait_values = {}
394 # self._traitlet_notifiers = {}
404 # self._trait_notifiers = {}
395
405
396 def _notify_traitlet(self, name, old_value, new_value):
406 def _notify_trait(self, name, old_value, new_value):
397
407
398 # First dynamic ones
408 # First dynamic ones
399 callables = self._traitlet_notifiers.get(name,[])
409 callables = self._trait_notifiers.get(name,[])
400 more_callables = self._traitlet_notifiers.get('anytraitlet',[])
410 more_callables = self._trait_notifiers.get('anytrait',[])
401 callables.extend(more_callables)
411 callables.extend(more_callables)
402
412
403 # Now static ones
413 # Now static ones
404 try:
414 try:
405 cb = getattr(self, '_%s_changed' % name)
415 cb = getattr(self, '_%s_changed' % name)
406 except:
416 except:
407 pass
417 pass
408 else:
418 else:
409 callables.append(cb)
419 callables.append(cb)
410
420
411 # Call them all now
421 # Call them all now
412 for c in callables:
422 for c in callables:
413 # Traits catches and logs errors here. I allow them to raise
423 # Traits catches and logs errors here. I allow them to raise
414 if callable(c):
424 if callable(c):
415 argspec = inspect.getargspec(c)
425 argspec = inspect.getargspec(c)
416 nargs = len(argspec[0])
426 nargs = len(argspec[0])
417 # Bound methods have an additional 'self' argument
427 # Bound methods have an additional 'self' argument
418 # I don't know how to treat unbound methods, but they
428 # I don't know how to treat unbound methods, but they
419 # can't really be used for callbacks.
429 # can't really be used for callbacks.
420 if isinstance(c, types.MethodType):
430 if isinstance(c, types.MethodType):
421 offset = -1
431 offset = -1
422 else:
432 else:
423 offset = 0
433 offset = 0
424 if nargs + offset == 0:
434 if nargs + offset == 0:
425 c()
435 c()
426 elif nargs + offset == 1:
436 elif nargs + offset == 1:
427 c(name)
437 c(name)
428 elif nargs + offset == 2:
438 elif nargs + offset == 2:
429 c(name, new_value)
439 c(name, new_value)
430 elif nargs + offset == 3:
440 elif nargs + offset == 3:
431 c(name, old_value, new_value)
441 c(name, old_value, new_value)
432 else:
442 else:
433 raise TraitletError('a traitlet changed callback '
443 raise TraitError('a trait changed callback '
434 'must have 0-3 arguments.')
444 'must have 0-3 arguments.')
435 else:
445 else:
436 raise TraitletError('a traitlet changed callback '
446 raise TraitError('a trait changed callback '
437 'must be callable.')
447 'must be callable.')
438
448
439
449
440 def _add_notifiers(self, handler, name):
450 def _add_notifiers(self, handler, name):
441 if not self._traitlet_notifiers.has_key(name):
451 if not self._trait_notifiers.has_key(name):
442 nlist = []
452 nlist = []
443 self._traitlet_notifiers[name] = nlist
453 self._trait_notifiers[name] = nlist
444 else:
454 else:
445 nlist = self._traitlet_notifiers[name]
455 nlist = self._trait_notifiers[name]
446 if handler not in nlist:
456 if handler not in nlist:
447 nlist.append(handler)
457 nlist.append(handler)
448
458
449 def _remove_notifiers(self, handler, name):
459 def _remove_notifiers(self, handler, name):
450 if self._traitlet_notifiers.has_key(name):
460 if self._trait_notifiers.has_key(name):
451 nlist = self._traitlet_notifiers[name]
461 nlist = self._trait_notifiers[name]
452 try:
462 try:
453 index = nlist.index(handler)
463 index = nlist.index(handler)
454 except ValueError:
464 except ValueError:
455 pass
465 pass
456 else:
466 else:
457 del nlist[index]
467 del nlist[index]
458
468
459 def on_traitlet_change(self, handler, name=None, remove=False):
469 def on_trait_change(self, handler, name=None, remove=False):
460 """Setup a handler to be called when a traitlet changes.
470 """Setup a handler to be called when a trait changes.
461
471
462 This is used to setup dynamic notifications of traitlet changes.
472 This is used to setup dynamic notifications of trait changes.
463
473
464 Static handlers can be created by creating methods on a HasTraitlets
474 Static handlers can be created by creating methods on a HasTraits
465 subclass with the naming convention '_[traitletname]_changed'. Thus,
475 subclass with the naming convention '_[traitname]_changed'. Thus,
466 to create static handler for the traitlet 'a', create the method
476 to create static handler for the trait 'a', create the method
467 _a_changed(self, name, old, new) (fewer arguments can be used, see
477 _a_changed(self, name, old, new) (fewer arguments can be used, see
468 below).
478 below).
469
479
470 Parameters
480 Parameters
471 ----------
481 ----------
472 handler : callable
482 handler : callable
473 A callable that is called when a traitlet changes. Its
483 A callable that is called when a trait changes. Its
474 signature can be handler(), handler(name), handler(name, new)
484 signature can be handler(), handler(name), handler(name, new)
475 or handler(name, old, new).
485 or handler(name, old, new).
476 name : list, str, None
486 name : list, str, None
477 If None, the handler will apply to all traitlets. If a list
487 If None, the handler will apply to all traits. If a list
478 of str, handler will apply to all names in the list. If a
488 of str, handler will apply to all names in the list. If a
479 str, the handler will apply just to that name.
489 str, the handler will apply just to that name.
480 remove : bool
490 remove : bool
481 If False (the default), then install the handler. If True
491 If False (the default), then install the handler. If True
482 then unintall it.
492 then unintall it.
483 """
493 """
484 if remove:
494 if remove:
485 names = parse_notifier_name(name)
495 names = parse_notifier_name(name)
486 for n in names:
496 for n in names:
487 self._remove_notifiers(handler, n)
497 self._remove_notifiers(handler, n)
488 else:
498 else:
489 names = parse_notifier_name(name)
499 names = parse_notifier_name(name)
490 for n in names:
500 for n in names:
491 self._add_notifiers(handler, n)
501 self._add_notifiers(handler, n)
492
502
493 def traitlet_names(self, **metadata):
503 def trait_names(self, **metadata):
494 """Get a list of all the names of this classes traitlets."""
504 """Get a list of all the names of this classes traits."""
495 return self.traitlets(**metadata).keys()
505 return self.traits(**metadata).keys()
496
506
497 def traitlets(self, **metadata):
507 def traits(self, **metadata):
498 """Get a list of all the traitlets of this class.
508 """Get a list of all the traits of this class.
499
509
500 The TraitletTypes returned don't know anything about the values
510 The TraitTypes returned don't know anything about the values
501 that the various HasTraitlet's instances are holding.
511 that the various HasTrait's instances are holding.
502
512
503 This follows the same algorithm as traits does and does not allow
513 This follows the same algorithm as traits does and does not allow
504 for any simple way of specifying merely that a metadata name
514 for any simple way of specifying merely that a metadata name
505 exists, but has any value. This is because get_metadata returns
515 exists, but has any value. This is because get_metadata returns
506 None if a metadata key doesn't exist.
516 None if a metadata key doesn't exist.
507 """
517 """
508 traitlets = dict([memb for memb in getmembers(self.__class__) if \
518 traits = dict([memb for memb in getmembers(self.__class__) if \
509 isinstance(memb[1], TraitletType)])
519 isinstance(memb[1], TraitType)])
510
520
511 if len(metadata) == 0:
521 if len(metadata) == 0:
512 return traitlets
522 return traits
513
523
514 for meta_name, meta_eval in metadata.items():
524 for meta_name, meta_eval in metadata.items():
515 if type(meta_eval) is not FunctionType:
525 if type(meta_eval) is not FunctionType:
516 metadata[meta_name] = _SimpleTest(meta_eval)
526 metadata[meta_name] = _SimpleTest(meta_eval)
517
527
518 result = {}
528 result = {}
519 for name, traitlet in traitlets.items():
529 for name, trait in traits.items():
520 for meta_name, meta_eval in metadata.items():
530 for meta_name, meta_eval in metadata.items():
521 if not meta_eval(traitlet.get_metadata(meta_name)):
531 if not meta_eval(trait.get_metadata(meta_name)):
522 break
532 break
523 else:
533 else:
524 result[name] = traitlet
534 result[name] = trait
525
535
526 return result
536 return result
527
537
528 def traitlet_metadata(self, traitletname, key):
538 def trait_metadata(self, traitname, key):
529 """Get metadata values for traitlet by key."""
539 """Get metadata values for trait by key."""
530 try:
540 try:
531 traitlet = getattr(self.__class__, traitletname)
541 trait = getattr(self.__class__, traitname)
532 except AttributeError:
542 except AttributeError:
533 raise TraitletError("Class %s does not have a traitlet named %s" %
543 raise TraitError("Class %s does not have a trait named %s" %
534 (self.__class__.__name__, traitletname))
544 (self.__class__.__name__, traitname))
535 else:
545 else:
536 return traitlet.get_metadata(key)
546 return trait.get_metadata(key)
537
547
538 #-----------------------------------------------------------------------------
548 #-----------------------------------------------------------------------------
539 # Actual TraitletTypes implementations/subclasses
549 # Actual TraitTypes implementations/subclasses
540 #-----------------------------------------------------------------------------
550 #-----------------------------------------------------------------------------
541
551
542 #-----------------------------------------------------------------------------
552 #-----------------------------------------------------------------------------
543 # TraitletTypes subclasses for handling classes and instances of classes
553 # TraitTypes subclasses for handling classes and instances of classes
544 #-----------------------------------------------------------------------------
554 #-----------------------------------------------------------------------------
545
555
546
556
547 class ClassBasedTraitletType(TraitletType):
557 class ClassBasedTraitType(TraitType):
548 """A traitlet with error reporting for Type, Instance and This."""
558 """A trait with error reporting for Type, Instance and This."""
549
559
550 def error(self, obj, value):
560 def error(self, obj, value):
551 kind = type(value)
561 kind = type(value)
552 if kind is InstanceType:
562 if kind is InstanceType:
553 msg = 'class %s' % value.__class__.__name__
563 msg = 'class %s' % value.__class__.__name__
554 else:
564 else:
555 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
565 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
556
566
557 super(ClassBasedTraitletType, self).error(obj, msg)
567 super(ClassBasedTraitType, self).error(obj, msg)
558
568
559
569
560 class Type(ClassBasedTraitletType):
570 class Type(ClassBasedTraitType):
561 """A traitlet whose value must be a subclass of a specified class."""
571 """A trait whose value must be a subclass of a specified class."""
562
572
563 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
573 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
564 """Construct a Type traitlet
574 """Construct a Type trait
565
575
566 A Type traitlet specifies that its values must be subclasses of
576 A Type trait specifies that its values must be subclasses of
567 a particular class.
577 a particular class.
568
578
569 If only ``default_value`` is given, it is used for the ``klass`` as
579 If only ``default_value`` is given, it is used for the ``klass`` as
570 well.
580 well.
571
581
572 Parameters
582 Parameters
573 ----------
583 ----------
574 default_value : class, str or None
584 default_value : class, str or None
575 The default value must be a subclass of klass. If an str,
585 The default value must be a subclass of klass. If an str,
576 the str must be a fully specified class name, like 'foo.bar.Bah'.
586 the str must be a fully specified class name, like 'foo.bar.Bah'.
577 The string is resolved into real class, when the parent
587 The string is resolved into real class, when the parent
578 :class:`HasTraitlets` class is instantiated.
588 :class:`HasTraits` class is instantiated.
579 klass : class, str, None
589 klass : class, str, None
580 Values of this traitlet must be a subclass of klass. The klass
590 Values of this trait must be a subclass of klass. The klass
581 may be specified in a string like: 'foo.bar.MyClass'.
591 may be specified in a string like: 'foo.bar.MyClass'.
582 The string is resolved into real class, when the parent
592 The string is resolved into real class, when the parent
583 :class:`HasTraitlets` class is instantiated.
593 :class:`HasTraits` class is instantiated.
584 allow_none : boolean
594 allow_none : boolean
585 Indicates whether None is allowed as an assignable value. Even if
595 Indicates whether None is allowed as an assignable value. Even if
586 ``False``, the default value may be ``None``.
596 ``False``, the default value may be ``None``.
587 """
597 """
588 if default_value is None:
598 if default_value is None:
589 if klass is None:
599 if klass is None:
590 klass = object
600 klass = object
591 elif klass is None:
601 elif klass is None:
592 klass = default_value
602 klass = default_value
593
603
594 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
604 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
595 raise TraitletError("A Type traitlet must specify a class.")
605 raise TraitError("A Type trait must specify a class.")
596
606
597 self.klass = klass
607 self.klass = klass
598 self._allow_none = allow_none
608 self._allow_none = allow_none
599
609
600 super(Type, self).__init__(default_value, **metadata)
610 super(Type, self).__init__(default_value, **metadata)
601
611
602 def validate(self, obj, value):
612 def validate(self, obj, value):
603 """Validates that the value is a valid object instance."""
613 """Validates that the value is a valid object instance."""
604 try:
614 try:
605 if issubclass(value, self.klass):
615 if issubclass(value, self.klass):
606 return value
616 return value
607 except:
617 except:
608 if (value is None) and (self._allow_none):
618 if (value is None) and (self._allow_none):
609 return value
619 return value
610
620
611 self.error(obj, value)
621 self.error(obj, value)
612
622
613 def info(self):
623 def info(self):
614 """ Returns a description of the trait."""
624 """ Returns a description of the trait."""
615 if isinstance(self.klass, basestring):
625 if isinstance(self.klass, basestring):
616 klass = self.klass
626 klass = self.klass
617 else:
627 else:
618 klass = self.klass.__name__
628 klass = self.klass.__name__
619 result = 'a subclass of ' + klass
629 result = 'a subclass of ' + klass
620 if self._allow_none:
630 if self._allow_none:
621 return result + ' or None'
631 return result + ' or None'
622 return result
632 return result
623
633
624 def instance_init(self, obj):
634 def instance_init(self, obj):
625 self._resolve_classes()
635 self._resolve_classes()
626 super(Type, self).instance_init(obj)
636 super(Type, self).instance_init(obj)
627
637
628 def _resolve_classes(self):
638 def _resolve_classes(self):
629 if isinstance(self.klass, basestring):
639 if isinstance(self.klass, basestring):
630 self.klass = import_item(self.klass)
640 self.klass = import_item(self.klass)
631 if isinstance(self.default_value, basestring):
641 if isinstance(self.default_value, basestring):
632 self.default_value = import_item(self.default_value)
642 self.default_value = import_item(self.default_value)
633
643
634 def get_default_value(self):
644 def get_default_value(self):
635 return self.default_value
645 return self.default_value
636
646
637
647
638 class DefaultValueGenerator(object):
648 class DefaultValueGenerator(object):
639 """A class for generating new default value instances."""
649 """A class for generating new default value instances."""
640
650
641 def __init__(self, *args, **kw):
651 def __init__(self, *args, **kw):
642 self.args = args
652 self.args = args
643 self.kw = kw
653 self.kw = kw
644
654
645 def generate(self, klass):
655 def generate(self, klass):
646 return klass(*self.args, **self.kw)
656 return klass(*self.args, **self.kw)
647
657
648
658
649 class Instance(ClassBasedTraitletType):
659 class Instance(ClassBasedTraitType):
650 """A trait whose value must be an instance of a specified class.
660 """A trait whose value must be an instance of a specified class.
651
661
652 The value can also be an instance of a subclass of the specified class.
662 The value can also be an instance of a subclass of the specified class.
653 """
663 """
654
664
655 def __init__(self, klass=None, args=None, kw=None,
665 def __init__(self, klass=None, args=None, kw=None,
656 allow_none=True, **metadata ):
666 allow_none=True, **metadata ):
657 """Construct an Instance traitlet.
667 """Construct an Instance trait.
658
668
659 This traitlet allows values that are instances of a particular
669 This trait allows values that are instances of a particular
660 class or its sublclasses. Our implementation is quite different
670 class or its sublclasses. Our implementation is quite different
661 from that of enthough.traits as we don't allow instances to be used
671 from that of enthough.traits as we don't allow instances to be used
662 for klass and we handle the ``args`` and ``kw`` arguments differently.
672 for klass and we handle the ``args`` and ``kw`` arguments differently.
663
673
664 Parameters
674 Parameters
665 ----------
675 ----------
666 klass : class, str
676 klass : class, str
667 The class that forms the basis for the traitlet. Class names
677 The class that forms the basis for the trait. Class names
668 can also be specified as strings, like 'foo.bar.Bar'.
678 can also be specified as strings, like 'foo.bar.Bar'.
669 args : tuple
679 args : tuple
670 Positional arguments for generating the default value.
680 Positional arguments for generating the default value.
671 kw : dict
681 kw : dict
672 Keyword arguments for generating the default value.
682 Keyword arguments for generating the default value.
673 allow_none : bool
683 allow_none : bool
674 Indicates whether None is allowed as a value.
684 Indicates whether None is allowed as a value.
675
685
676 Default Value
686 Default Value
677 -------------
687 -------------
678 If both ``args`` and ``kw`` are None, then the default value is None.
688 If both ``args`` and ``kw`` are None, then the default value is None.
679 If ``args`` is a tuple and ``kw`` is a dict, then the default is
689 If ``args`` is a tuple and ``kw`` is a dict, then the default is
680 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
690 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
681 not (but not both), None is replace by ``()`` or ``{}``.
691 not (but not both), None is replace by ``()`` or ``{}``.
682 """
692 """
683
693
684 self._allow_none = allow_none
694 self._allow_none = allow_none
685
695
686 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
696 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
687 raise TraitletError('The klass argument must be a class'
697 raise TraitError('The klass argument must be a class'
688 ' you gave: %r' % klass)
698 ' you gave: %r' % klass)
689 self.klass = klass
699 self.klass = klass
690
700
691 # self.klass is a class, so handle default_value
701 # self.klass is a class, so handle default_value
692 if args is None and kw is None:
702 if args is None and kw is None:
693 default_value = None
703 default_value = None
694 else:
704 else:
695 if args is None:
705 if args is None:
696 # kw is not None
706 # kw is not None
697 args = ()
707 args = ()
698 elif kw is None:
708 elif kw is None:
699 # args is not None
709 # args is not None
700 kw = {}
710 kw = {}
701
711
702 if not isinstance(kw, dict):
712 if not isinstance(kw, dict):
703 raise TraitletError("The 'kw' argument must be a dict or None.")
713 raise TraitError("The 'kw' argument must be a dict or None.")
704 if not isinstance(args, tuple):
714 if not isinstance(args, tuple):
705 raise TraitletError("The 'args' argument must be a tuple or None.")
715 raise TraitError("The 'args' argument must be a tuple or None.")
706
716
707 default_value = DefaultValueGenerator(*args, **kw)
717 default_value = DefaultValueGenerator(*args, **kw)
708
718
709 super(Instance, self).__init__(default_value, **metadata)
719 super(Instance, self).__init__(default_value, **metadata)
710
720
711 def validate(self, obj, value):
721 def validate(self, obj, value):
712 if value is None:
722 if value is None:
713 if self._allow_none:
723 if self._allow_none:
714 return value
724 return value
715 self.error(obj, value)
725 self.error(obj, value)
716
726
717 if isinstance(value, self.klass):
727 if isinstance(value, self.klass):
718 return value
728 return value
719 else:
729 else:
720 self.error(obj, value)
730 self.error(obj, value)
721
731
722 def info(self):
732 def info(self):
723 if isinstance(self.klass, basestring):
733 if isinstance(self.klass, basestring):
724 klass = self.klass
734 klass = self.klass
725 else:
735 else:
726 klass = self.klass.__name__
736 klass = self.klass.__name__
727 result = class_of(klass)
737 result = class_of(klass)
728 if self._allow_none:
738 if self._allow_none:
729 return result + ' or None'
739 return result + ' or None'
730
740
731 return result
741 return result
732
742
733 def instance_init(self, obj):
743 def instance_init(self, obj):
734 self._resolve_classes()
744 self._resolve_classes()
735 super(Instance, self).instance_init(obj)
745 super(Instance, self).instance_init(obj)
736
746
737 def _resolve_classes(self):
747 def _resolve_classes(self):
738 if isinstance(self.klass, basestring):
748 if isinstance(self.klass, basestring):
739 self.klass = import_item(self.klass)
749 self.klass = import_item(self.klass)
740
750
741 def get_default_value(self):
751 def get_default_value(self):
742 """Instantiate a default value instance.
752 """Instantiate a default value instance.
743
753
744 This is called when the containing HasTraitlets classes'
754 This is called when the containing HasTraits classes'
745 :meth:`__new__` method is called to ensure that a unique instance
755 :meth:`__new__` method is called to ensure that a unique instance
746 is created for each HasTraitlets instance.
756 is created for each HasTraits instance.
747 """
757 """
748 dv = self.default_value
758 dv = self.default_value
749 if isinstance(dv, DefaultValueGenerator):
759 if isinstance(dv, DefaultValueGenerator):
750 return dv.generate(self.klass)
760 return dv.generate(self.klass)
751 else:
761 else:
752 return dv
762 return dv
753
763
754
764
755 class This(ClassBasedTraitletType):
765 class This(ClassBasedTraitType):
756 """A traitlet for instances of the class containing this trait.
766 """A trait for instances of the class containing this trait.
757
767
758 Because how how and when class bodies are executed, the ``This``
768 Because how how and when class bodies are executed, the ``This``
759 traitlet can only have a default value of None. This, and because we
769 trait can only have a default value of None. This, and because we
760 always validate default values, ``allow_none`` is *always* true.
770 always validate default values, ``allow_none`` is *always* true.
761 """
771 """
762
772
763 info_text = 'an instance of the same type as the receiver or None'
773 info_text = 'an instance of the same type as the receiver or None'
764
774
765 def __init__(self, **metadata):
775 def __init__(self, **metadata):
766 super(This, self).__init__(None, **metadata)
776 super(This, self).__init__(None, **metadata)
767
777
768 def validate(self, obj, value):
778 def validate(self, obj, value):
769 # What if value is a superclass of obj.__class__? This is
779 # What if value is a superclass of obj.__class__? This is
770 # complicated if it was the superclass that defined the This
780 # complicated if it was the superclass that defined the This
771 # traitlet.
781 # trait.
772 if isinstance(value, self.this_class) or (value is None):
782 if isinstance(value, self.this_class) or (value is None):
773 return value
783 return value
774 else:
784 else:
775 self.error(obj, value)
785 self.error(obj, value)
776
786
777
787
778 #-----------------------------------------------------------------------------
788 #-----------------------------------------------------------------------------
779 # Basic TraitletTypes implementations/subclasses
789 # Basic TraitTypes implementations/subclasses
780 #-----------------------------------------------------------------------------
790 #-----------------------------------------------------------------------------
781
791
782
792
783 class Any(TraitletType):
793 class Any(TraitType):
784 default_value = None
794 default_value = None
785 info_text = 'any value'
795 info_text = 'any value'
786
796
787
797
788 class Int(TraitletType):
798 class Int(TraitType):
789 """A integer traitlet."""
799 """A integer trait."""
790
800
791 evaluate = int
801 evaluate = int
792 default_value = 0
802 default_value = 0
793 info_text = 'an integer'
803 info_text = 'an integer'
794
804
795 def validate(self, obj, value):
805 def validate(self, obj, value):
796 if isinstance(value, int):
806 if isinstance(value, int):
797 return value
807 return value
798 self.error(obj, value)
808 self.error(obj, value)
799
809
800 class CInt(Int):
810 class CInt(Int):
801 """A casting version of the int traitlet."""
811 """A casting version of the int trait."""
802
812
803 def validate(self, obj, value):
813 def validate(self, obj, value):
804 try:
814 try:
805 return int(value)
815 return int(value)
806 except:
816 except:
807 self.error(obj, value)
817 self.error(obj, value)
808
818
809
819
810 class Long(TraitletType):
820 class Long(TraitType):
811 """A long integer traitlet."""
821 """A long integer trait."""
812
822
813 evaluate = long
823 evaluate = long
814 default_value = 0L
824 default_value = 0L
815 info_text = 'a long'
825 info_text = 'a long'
816
826
817 def validate(self, obj, value):
827 def validate(self, obj, value):
818 if isinstance(value, long):
828 if isinstance(value, long):
819 return value
829 return value
820 if isinstance(value, int):
830 if isinstance(value, int):
821 return long(value)
831 return long(value)
822 self.error(obj, value)
832 self.error(obj, value)
823
833
824
834
825 class CLong(Long):
835 class CLong(Long):
826 """A casting version of the long integer traitlet."""
836 """A casting version of the long integer trait."""
827
837
828 def validate(self, obj, value):
838 def validate(self, obj, value):
829 try:
839 try:
830 return long(value)
840 return long(value)
831 except:
841 except:
832 self.error(obj, value)
842 self.error(obj, value)
833
843
834
844
835 class Float(TraitletType):
845 class Float(TraitType):
836 """A float traitlet."""
846 """A float trait."""
837
847
838 evaluate = float
848 evaluate = float
839 default_value = 0.0
849 default_value = 0.0
840 info_text = 'a float'
850 info_text = 'a float'
841
851
842 def validate(self, obj, value):
852 def validate(self, obj, value):
843 if isinstance(value, float):
853 if isinstance(value, float):
844 return value
854 return value
845 if isinstance(value, int):
855 if isinstance(value, int):
846 return float(value)
856 return float(value)
847 self.error(obj, value)
857 self.error(obj, value)
848
858
849
859
850 class CFloat(Float):
860 class CFloat(Float):
851 """A casting version of the float traitlet."""
861 """A casting version of the float trait."""
852
862
853 def validate(self, obj, value):
863 def validate(self, obj, value):
854 try:
864 try:
855 return float(value)
865 return float(value)
856 except:
866 except:
857 self.error(obj, value)
867 self.error(obj, value)
858
868
859 class Complex(TraitletType):
869 class Complex(TraitType):
860 """A traitlet for complex numbers."""
870 """A trait for complex numbers."""
861
871
862 evaluate = complex
872 evaluate = complex
863 default_value = 0.0 + 0.0j
873 default_value = 0.0 + 0.0j
864 info_text = 'a complex number'
874 info_text = 'a complex number'
865
875
866 def validate(self, obj, value):
876 def validate(self, obj, value):
867 if isinstance(value, complex):
877 if isinstance(value, complex):
868 return value
878 return value
869 if isinstance(value, (float, int)):
879 if isinstance(value, (float, int)):
870 return complex(value)
880 return complex(value)
871 self.error(obj, value)
881 self.error(obj, value)
872
882
873
883
874 class CComplex(Complex):
884 class CComplex(Complex):
875 """A casting version of the complex number traitlet."""
885 """A casting version of the complex number trait."""
876
886
877 def validate (self, obj, value):
887 def validate (self, obj, value):
878 try:
888 try:
879 return complex(value)
889 return complex(value)
880 except:
890 except:
881 self.error(obj, value)
891 self.error(obj, value)
882
892
883
893
884 class Str(TraitletType):
894 class Str(TraitType):
885 """A traitlet for strings."""
895 """A trait for strings."""
886
896
887 evaluate = lambda x: x
897 evaluate = lambda x: x
888 default_value = ''
898 default_value = ''
889 info_text = 'a string'
899 info_text = 'a string'
890
900
891 def validate(self, obj, value):
901 def validate(self, obj, value):
892 if isinstance(value, str):
902 if isinstance(value, str):
893 return value
903 return value
894 self.error(obj, value)
904 self.error(obj, value)
895
905
896
906
897 class CStr(Str):
907 class CStr(Str):
898 """A casting version of the string traitlet."""
908 """A casting version of the string trait."""
899
909
900 def validate(self, obj, value):
910 def validate(self, obj, value):
901 try:
911 try:
902 return str(value)
912 return str(value)
903 except:
913 except:
904 try:
914 try:
905 return unicode(value)
915 return unicode(value)
906 except:
916 except:
907 self.error(obj, value)
917 self.error(obj, value)
908
918
909
919
910 class Unicode(TraitletType):
920 class Unicode(TraitType):
911 """A traitlet for unicode strings."""
921 """A trait for unicode strings."""
912
922
913 evaluate = unicode
923 evaluate = unicode
914 default_value = u''
924 default_value = u''
915 info_text = 'a unicode string'
925 info_text = 'a unicode string'
916
926
917 def validate(self, obj, value):
927 def validate(self, obj, value):
918 if isinstance(value, unicode):
928 if isinstance(value, unicode):
919 return value
929 return value
920 if isinstance(value, str):
930 if isinstance(value, str):
921 return unicode(value)
931 return unicode(value)
922 self.error(obj, value)
932 self.error(obj, value)
923
933
924
934
925 class CUnicode(Unicode):
935 class CUnicode(Unicode):
926 """A casting version of the unicode traitlet."""
936 """A casting version of the unicode trait."""
927
937
928 def validate(self, obj, value):
938 def validate(self, obj, value):
929 try:
939 try:
930 return unicode(value)
940 return unicode(value)
931 except:
941 except:
932 self.error(obj, value)
942 self.error(obj, value)
933
943
934
944
935 class Bool(TraitletType):
945 class Bool(TraitType):
936 """A boolean (True, False) traitlet."""
946 """A boolean (True, False) trait."""
937 evaluate = bool
947 evaluate = bool
938 default_value = False
948 default_value = False
939 info_text = 'a boolean'
949 info_text = 'a boolean'
940
950
941 def validate(self, obj, value):
951 def validate(self, obj, value):
942 if isinstance(value, bool):
952 if isinstance(value, bool):
943 return value
953 return value
944 self.error(obj, value)
954 self.error(obj, value)
945
955
946
956
947 class CBool(Bool):
957 class CBool(Bool):
948 """A casting version of the boolean traitlet."""
958 """A casting version of the boolean trait."""
949
959
950 def validate(self, obj, value):
960 def validate(self, obj, value):
951 try:
961 try:
952 return bool(value)
962 return bool(value)
953 except:
963 except:
954 self.error(obj, value)
964 self.error(obj, value)
955
965
956
966
957 class Enum(TraitletType):
967 class Enum(TraitType):
958 """An enum that whose value must be in a given sequence."""
968 """An enum that whose value must be in a given sequence."""
959
969
960 def __init__(self, values, default_value=None, allow_none=True, **metadata):
970 def __init__(self, values, default_value=None, allow_none=True, **metadata):
961 self.values = values
971 self.values = values
962 self._allow_none = allow_none
972 self._allow_none = allow_none
963 super(Enum, self).__init__(default_value, **metadata)
973 super(Enum, self).__init__(default_value, **metadata)
964
974
965 def validate(self, obj, value):
975 def validate(self, obj, value):
966 if value is None:
976 if value is None:
967 if self._allow_none:
977 if self._allow_none:
968 return value
978 return value
969
979
970 if value in self.values:
980 if value in self.values:
971 return value
981 return value
972 self.error(obj, value)
982 self.error(obj, value)
973
983
974 def info(self):
984 def info(self):
975 """ Returns a description of the trait."""
985 """ Returns a description of the trait."""
976 result = 'any of ' + repr(self.values)
986 result = 'any of ' + repr(self.values)
977 if self._allow_none:
987 if self._allow_none:
978 return result + ' or None'
988 return result + ' or None'
979 return result
989 return result
980
990
981 class CaselessStrEnum(Enum):
991 class CaselessStrEnum(Enum):
982 """An enum of strings that are caseless in validate."""
992 """An enum of strings that are caseless in validate."""
983
993
984 def validate(self, obj, value):
994 def validate(self, obj, value):
985 if value is None:
995 if value is None:
986 if self._allow_none:
996 if self._allow_none:
987 return value
997 return value
988
998
989 if not isinstance(value, str):
999 if not isinstance(value, str):
990 self.error(obj, value)
1000 self.error(obj, value)
991
1001
992 for v in self.values:
1002 for v in self.values:
993 if v.lower() == value.lower():
1003 if v.lower() == value.lower():
994 return v
1004 return v
995 self.error(obj, value)
1005 self.error(obj, value)
996
1006
997
1007
998 class List(Instance):
1008 class List(Instance):
999 """An instance of a Python list."""
1009 """An instance of a Python list."""
1000
1010
1001 def __init__(self, default_value=None, allow_none=True, **metadata):
1011 def __init__(self, default_value=None, allow_none=True, **metadata):
1002 """Create a list traitlet type from a list or tuple.
1012 """Create a list trait type from a list or tuple.
1003
1013
1004 The default value is created by doing ``list(default_value)``,
1014 The default value is created by doing ``list(default_value)``,
1005 which creates a copy of the ``default_value``.
1015 which creates a copy of the ``default_value``.
1006 """
1016 """
1007 if default_value is None:
1017 if default_value is None:
1008 args = ((),)
1018 args = ((),)
1009 elif isinstance(default_value, SequenceTypes):
1019 elif isinstance(default_value, SequenceTypes):
1010 args = (default_value,)
1020 args = (default_value,)
1021 else:
1022 raise TypeError('default value of List was %s' % default_value)
1011
1023
1012 super(List,self).__init__(klass=list, args=args,
1024 super(List,self).__init__(klass=list, args=args,
1013 allow_none=allow_none, **metadata)
1025 allow_none=allow_none, **metadata)
@@ -1,331 +1,331 b''
1 .. _config_overview:
1 .. _config_overview:
2
2
3 ============================================
3 ============================================
4 Overview of the IPython configuration system
4 Overview of the IPython configuration system
5 ============================================
5 ============================================
6
6
7 This section describes the IPython configuration system. Starting with version
7 This section describes the IPython configuration system. Starting with version
8 0.11, IPython has a completely new configuration system that is quite
8 0.11, IPython has a completely new configuration system that is quite
9 different from the older :file:`ipythonrc` or :file:`ipy_user_conf.py`
9 different from the older :file:`ipythonrc` or :file:`ipy_user_conf.py`
10 approaches. The new configuration system was designed from scratch to address
10 approaches. The new configuration system was designed from scratch to address
11 the particular configuration needs of IPython. While there are many
11 the particular configuration needs of IPython. While there are many
12 other excellent configuration systems out there, we found that none of them
12 other excellent configuration systems out there, we found that none of them
13 met our requirements.
13 met our requirements.
14
14
15 .. warning::
15 .. warning::
16
16
17 If you are upgrading to version 0.11 of IPython, you will need to migrate
17 If you are upgrading to version 0.11 of IPython, you will need to migrate
18 your old :file:`ipythonrc` or :file:`ipy_user_conf.py` configuration files
18 your old :file:`ipythonrc` or :file:`ipy_user_conf.py` configuration files
19 to the new system. Read on for information on how to do this.
19 to the new system. Read on for information on how to do this.
20
20
21 The discussion that follows is focused on teaching user's how to configure
21 The discussion that follows is focused on teaching user's how to configure
22 IPython to their liking. Developer's who want to know more about how they
22 IPython to their liking. Developer's who want to know more about how they
23 can enable their objects to take advantage of the configuration system
23 can enable their objects to take advantage of the configuration system
24 should consult our :ref:`developer guide <developer_guide>`
24 should consult our :ref:`developer guide <developer_guide>`
25
25
26 The main concepts
26 The main concepts
27 =================
27 =================
28
28
29 There are a number of abstractions that the IPython configuration system uses.
29 There are a number of abstractions that the IPython configuration system uses.
30 Each of these abstractions is represented by a Python class.
30 Each of these abstractions is represented by a Python class.
31
31
32 Configuration object: :class:`~IPython.config.loader.Config`
32 Configuration object: :class:`~IPython.config.loader.Config`
33 A configuration object is a simple dictionary-like class that holds
33 A configuration object is a simple dictionary-like class that holds
34 configuration attributes and sub-configuration objects. These classes
34 configuration attributes and sub-configuration objects. These classes
35 support dotted attribute style access (``Foo.bar``) in addition to the
35 support dotted attribute style access (``Foo.bar``) in addition to the
36 regular dictionary style access (``Foo['bar']``). Configuration objects
36 regular dictionary style access (``Foo['bar']``). Configuration objects
37 are smart. They know how to merge themselves with other configuration
37 are smart. They know how to merge themselves with other configuration
38 objects and they automatically create sub-configuration objects.
38 objects and they automatically create sub-configuration objects.
39
39
40 Application: :class:`~IPython.core.application.Application`
40 Application: :class:`~IPython.core.application.Application`
41 An application is a process that does a specific job. The most obvious
41 An application is a process that does a specific job. The most obvious
42 application is the :command:`ipython` command line program. Each
42 application is the :command:`ipython` command line program. Each
43 application reads a *single* configuration file and command line options
43 application reads a *single* configuration file and command line options
44 and then produces a master configuration object for the application. This
44 and then produces a master configuration object for the application. This
45 configuration object is then passed to the components that the application
45 configuration object is then passed to the components that the application
46 creates. Components implement the actual logic of the application and know
46 creates. Components implement the actual logic of the application and know
47 how to configure themselves given the configuration object.
47 how to configure themselves given the configuration object.
48
48
49 Component: :class:`~IPython.core.component.Component`
49 Component: :class:`~IPython.core.component.Component`
50 A component is a regular Python class that serves as a base class for all
50 A component is a regular Python class that serves as a base class for all
51 main classes in an application. The
51 main classes in an application. The
52 :class:`~IPython.core.component.Component` base class is lightweight and
52 :class:`~IPython.core.component.Component` base class is lightweight and
53 only does two main things.
53 only does two main things.
54
54
55 First, it keeps track of all instances of itself and provides an
55 First, it keeps track of all instances of itself and provides an
56 interfaces for querying those instances. This enables components to get
56 interfaces for querying those instances. This enables components to get
57 references to other components, even though they are not "nearby" in the
57 references to other components, even though they are not "nearby" in the
58 runtime object graph.
58 runtime object graph.
59
59
60 Second, it declares what class attributes are configurable and specifies
60 Second, it declares what class attributes are configurable and specifies
61 the default types and values of those attributes. This information is used
61 the default types and values of those attributes. This information is used
62 to automatically configure instances given the applications configuration
62 to automatically configure instances given the applications configuration
63 object.
63 object.
64
64
65 Developers create :class:`~IPython.core.component.Component` subclasses
65 Developers create :class:`~IPython.core.component.Component` subclasses
66 that implement all of the logic in the application. Each of these
66 that implement all of the logic in the application. Each of these
67 subclasses has its own configuration information that controls how
67 subclasses has its own configuration information that controls how
68 instances are created.
68 instances are created.
69
69
70 Having described these main concepts, we can now state the main idea in our
70 Having described these main concepts, we can now state the main idea in our
71 configuration system: *"configuration" allows the default values of class
71 configuration system: *"configuration" allows the default values of class
72 attributes to be controlled on a class by class basis*. Thus all instances of
72 attributes to be controlled on a class by class basis*. Thus all instances of
73 a given class are configured in the same way. Furthermore, if two instances
73 a given class are configured in the same way. Furthermore, if two instances
74 need to be configured differently, they need to be instances of two different
74 need to be configured differently, they need to be instances of two different
75 classes. While this model may seem a bit restrictive, we have found that it
75 classes. While this model may seem a bit restrictive, we have found that it
76 expresses most things that need to be configured extremely well.
76 expresses most things that need to be configured extremely well.
77
77
78 Now, we show what our configuration objects and files look like.
78 Now, we show what our configuration objects and files look like.
79
79
80 Configuration objects and files
80 Configuration objects and files
81 ===============================
81 ===============================
82
82
83 A configuration file is simply a pure Python file that sets the attributes
83 A configuration file is simply a pure Python file that sets the attributes
84 of a global, pre-created configuration object. This configuration object is a
84 of a global, pre-created configuration object. This configuration object is a
85 :class:`~IPython.config.loader.Config` instance. While in a configuration
85 :class:`~IPython.config.loader.Config` instance. While in a configuration
86 file, to get a reference to this object, simply call the :func:`get_config`
86 file, to get a reference to this object, simply call the :func:`get_config`
87 function. We inject this function into the global namespace that the
87 function. We inject this function into the global namespace that the
88 configuration file is executed in.
88 configuration file is executed in.
89
89
90 Here is an example of a super simple configuration file that does nothing::
90 Here is an example of a super simple configuration file that does nothing::
91
91
92 c = get_config()
92 c = get_config()
93
93
94 Once you get a reference to the configuration object, you simply set
94 Once you get a reference to the configuration object, you simply set
95 attributes on it. All you have to know is:
95 attributes on it. All you have to know is:
96
96
97 * The name of each attribute.
97 * The name of each attribute.
98 * The type of each attribute.
98 * The type of each attribute.
99
99
100 The answers to these two questions are provided by the various
100 The answers to these two questions are provided by the various
101 :class:`~IPython.core.component.Component` subclasses that an application
101 :class:`~IPython.core.component.Component` subclasses that an application
102 uses. Let's look at how this would work for a simple component subclass::
102 uses. Let's look at how this would work for a simple component subclass::
103
103
104 # Sample component that can be configured.
104 # Sample component that can be configured.
105 from IPython.core.component import Component
105 from IPython.core.component import Component
106 from IPython.utils.traitlets import Int, Float, Str, Bool
106 from IPython.utils.traitlets import Int, Float, Str, Bool
107
107
108 class MyComponent(Component):
108 class MyComponent(Component):
109 name = Str('defaultname', config=True)
109 name = Str('defaultname', config=True)
110 ranking = Int(0, config=True)
110 ranking = Int(0, config=True)
111 value = Float(99.0)
111 value = Float(99.0)
112 # The rest of the class implementation would go here..
112 # The rest of the class implementation would go here..
113
113
114 In this example, we see that :class:`MyComponent` has three attributes, two
114 In this example, we see that :class:`MyComponent` has three attributes, two
115 of whom (``name``, ``ranking``) can be configured. All of the attributes
115 of whom (``name``, ``ranking``) can be configured. All of the attributes
116 are given types and default values. If a :class:`MyComponent` is instantiated,
116 are given types and default values. If a :class:`MyComponent` is instantiated,
117 but not configured, these default values will be used. But let's see how
117 but not configured, these default values will be used. But let's see how
118 to configure this class in a configuration file::
118 to configure this class in a configuration file::
119
119
120 # Sample config file
120 # Sample config file
121 c = get_config()
121 c = get_config()
122
122
123 c.MyComponent.name = 'coolname'
123 c.MyComponent.name = 'coolname'
124 c.MyComponent.ranking = 10
124 c.MyComponent.ranking = 10
125
125
126 After this configuration file is loaded, the values set in it will override
126 After this configuration file is loaded, the values set in it will override
127 the class defaults anytime a :class:`MyComponent` is created. Furthermore,
127 the class defaults anytime a :class:`MyComponent` is created. Furthermore,
128 these attributes will be type checked and validated anytime they are set.
128 these attributes will be type checked and validated anytime they are set.
129 This type checking is handled by the :mod:`IPython.utils.traitlets` module,
129 This type checking is handled by the :mod:`IPython.utils.traitlets` module,
130 which provides the :class:`Str`, :class:`Int` and :class:`Float` types. In
130 which provides the :class:`Str`, :class:`Int` and :class:`Float` types. In
131 addition to these traitlets, the :mod:`IPython.utils.traitlets` provides
131 addition to these traitlets, the :mod:`IPython.utils.traitlets` provides
132 traitlets for a number of other types.
132 traitlets for a number of other types.
133
133
134 .. note::
134 .. note::
135
135
136 Underneath the hood, the :class:`Component` base class is a subclass of
136 Underneath the hood, the :class:`Component` base class is a subclass of
137 :class:`IPython.utils.traitlets.HasTraitlets`. The
137 :class:`IPython.utils.traitlets.HasTraits`. The
138 :mod:`IPython.utils.traitlets` module is a lightweight version of
138 :mod:`IPython.utils.traitlets` module is a lightweight version of
139 :mod:`enthought.traits`. Our implementation is a pure Python subset
139 :mod:`enthought.traits`. Our implementation is a pure Python subset
140 (mostly API compatible) of :mod:`enthought.traits` that does not have any
140 (mostly API compatible) of :mod:`enthought.traits` that does not have any
141 of the automatic GUI generation capabilities. Our plan is to achieve 100%
141 of the automatic GUI generation capabilities. Our plan is to achieve 100%
142 API compatibility to enable the actual :mod:`enthought.traits` to
142 API compatibility to enable the actual :mod:`enthought.traits` to
143 eventually be used instead. Currently, we cannot use
143 eventually be used instead. Currently, we cannot use
144 :mod:`enthought.traits` as we are committed to the core of IPython being
144 :mod:`enthought.traits` as we are committed to the core of IPython being
145 pure Python.
145 pure Python.
146
146
147 It should be very clear at this point what the naming convention is for
147 It should be very clear at this point what the naming convention is for
148 configuration attributes::
148 configuration attributes::
149
149
150 c.ClassName.attribute_name = attribute_value
150 c.ClassName.attribute_name = attribute_value
151
151
152 Here, ``ClassName`` is the name of the class whose configuration attribute you
152 Here, ``ClassName`` is the name of the class whose configuration attribute you
153 want to set, ``attribute_name`` is the name of the attribute you want to set
153 want to set, ``attribute_name`` is the name of the attribute you want to set
154 and ``attribute_value`` the the value you want it to have. The ``ClassName``
154 and ``attribute_value`` the the value you want it to have. The ``ClassName``
155 attribute of ``c`` is not the actual class, but instead is another
155 attribute of ``c`` is not the actual class, but instead is another
156 :class:`~IPython.config.loader.Config` instance.
156 :class:`~IPython.config.loader.Config` instance.
157
157
158 .. note::
158 .. note::
159
159
160 The careful reader may wonder how the ``ClassName`` (``MyComponent`` in
160 The careful reader may wonder how the ``ClassName`` (``MyComponent`` in
161 the above example) attribute of the configuration object ``c`` gets
161 the above example) attribute of the configuration object ``c`` gets
162 created. These attributes are created on the fly by the
162 created. These attributes are created on the fly by the
163 :class:`~IPython.config.loader.Config` instance, using a simple naming
163 :class:`~IPython.config.loader.Config` instance, using a simple naming
164 convention. Any attribute of a :class:`~IPython.config.loader.Config`
164 convention. Any attribute of a :class:`~IPython.config.loader.Config`
165 instance whose name begins with an uppercase character is assumed to be a
165 instance whose name begins with an uppercase character is assumed to be a
166 sub-configuration and a new empty :class:`~IPython.config.loader.Config`
166 sub-configuration and a new empty :class:`~IPython.config.loader.Config`
167 instance is dynamically created for that attribute. This allows deeply
167 instance is dynamically created for that attribute. This allows deeply
168 hierarchical information created easily (``c.Foo.Bar.value``) on the
168 hierarchical information created easily (``c.Foo.Bar.value``) on the
169 fly.
169 fly.
170
170
171 Configuration files inheritance
171 Configuration files inheritance
172 ===============================
172 ===============================
173
173
174 Let's say you want to have different configuration files for various purposes.
174 Let's say you want to have different configuration files for various purposes.
175 Our configuration system makes it easy for one configuration file to inherit
175 Our configuration system makes it easy for one configuration file to inherit
176 the information in another configuration file. The :func:`load_subconfig`
176 the information in another configuration file. The :func:`load_subconfig`
177 command can be used in a configuration file for this purpose. Here is a simple
177 command can be used in a configuration file for this purpose. Here is a simple
178 example that loads all of the values from the file :file:`base_config.py`::
178 example that loads all of the values from the file :file:`base_config.py`::
179
179
180 # base_config.py
180 # base_config.py
181 c = get_config()
181 c = get_config()
182 c.MyComponent.name = 'coolname'
182 c.MyComponent.name = 'coolname'
183 c.MyComponent.ranking = 100
183 c.MyComponent.ranking = 100
184
184
185 into the configuration file :file:`main_config.py`::
185 into the configuration file :file:`main_config.py`::
186
186
187 # main_config.py
187 # main_config.py
188 c = get_config()
188 c = get_config()
189
189
190 # Load everything from base_config.py
190 # Load everything from base_config.py
191 load_subconfig('base_config.py')
191 load_subconfig('base_config.py')
192
192
193 # Now override one of the values
193 # Now override one of the values
194 c.MyComponent.name = 'bettername'
194 c.MyComponent.name = 'bettername'
195
195
196 In a situation like this the :func:`load_subconfig` makes sure that the
196 In a situation like this the :func:`load_subconfig` makes sure that the
197 search path for sub-configuration files is inherited from that of the parent.
197 search path for sub-configuration files is inherited from that of the parent.
198 Thus, you can typically put the two in the same directory and everything will
198 Thus, you can typically put the two in the same directory and everything will
199 just work.
199 just work.
200
200
201 Class based configuration inheritance
201 Class based configuration inheritance
202 =====================================
202 =====================================
203
203
204 There is another aspect of configuration where inheritance comes into play.
204 There is another aspect of configuration where inheritance comes into play.
205 Sometimes, your classes will have an inheritance hierarchy that you want
205 Sometimes, your classes will have an inheritance hierarchy that you want
206 to be reflected in the configuration system. Here is a simple example::
206 to be reflected in the configuration system. Here is a simple example::
207
207
208 from IPython.core.component import Component
208 from IPython.core.component import Component
209 from IPython.utils.traitlets import Int, Float, Str, Bool
209 from IPython.utils.traitlets import Int, Float, Str, Bool
210
210
211 class Foo(Component):
211 class Foo(Component):
212 name = Str('fooname', config=True)
212 name = Str('fooname', config=True)
213 value = Float(100.0, config=True)
213 value = Float(100.0, config=True)
214
214
215 class Bar(Foo):
215 class Bar(Foo):
216 name = Str('barname', config=True)
216 name = Str('barname', config=True)
217 othervalue = Int(0, config=True)
217 othervalue = Int(0, config=True)
218
218
219 Now, we can create a configuration file to configure instances of :class:`Foo`
219 Now, we can create a configuration file to configure instances of :class:`Foo`
220 and :class:`Bar`::
220 and :class:`Bar`::
221
221
222 # config file
222 # config file
223 c = get_config()
223 c = get_config()
224
224
225 c.Foo.name = 'bestname'
225 c.Foo.name = 'bestname'
226 c.Bar.othervalue = 10
226 c.Bar.othervalue = 10
227
227
228 This class hierarchy and configuration file accomplishes the following:
228 This class hierarchy and configuration file accomplishes the following:
229
229
230 * The default value for :attr:`Foo.name` and :attr:`Bar.name` will be
230 * The default value for :attr:`Foo.name` and :attr:`Bar.name` will be
231 'bestname'. Because :class:`Bar` is a :class:`Foo` subclass it also
231 'bestname'. Because :class:`Bar` is a :class:`Foo` subclass it also
232 picks up the configuration information for :class:`Foo`.
232 picks up the configuration information for :class:`Foo`.
233 * The default value for :attr:`Foo.value` and :attr:`Bar.value` will be
233 * The default value for :attr:`Foo.value` and :attr:`Bar.value` will be
234 ``100.0``, which is the value specified as the class default.
234 ``100.0``, which is the value specified as the class default.
235 * The default value for :attr:`Bar.othervalue` will be 10 as set in the
235 * The default value for :attr:`Bar.othervalue` will be 10 as set in the
236 configuration file. Because :class:`Foo` is the parent of :class:`Bar`
236 configuration file. Because :class:`Foo` is the parent of :class:`Bar`
237 it doesn't know anything about the :attr:`othervalue` attribute.
237 it doesn't know anything about the :attr:`othervalue` attribute.
238
238
239 Configuration file location
239 Configuration file location
240 ===========================
240 ===========================
241
241
242 So where should you put your configuration files? By default, all IPython
242 So where should you put your configuration files? By default, all IPython
243 applications look in the so called "IPython directory". The location of
243 applications look in the so called "IPython directory". The location of
244 this directory is determined by the following algorithm:
244 this directory is determined by the following algorithm:
245
245
246 * If the ``--ipython-dir`` command line flag is given, its value is used.
246 * If the ``--ipython-dir`` command line flag is given, its value is used.
247
247
248 * If not, the value returned by :func:`IPython.utils.path.get_ipython_dir`
248 * If not, the value returned by :func:`IPython.utils.path.get_ipython_dir`
249 is used. This function will first look at the :envvar:`IPYTHON_DIR`
249 is used. This function will first look at the :envvar:`IPYTHON_DIR`
250 environment variable and then default to the directory
250 environment variable and then default to the directory
251 :file:`$HOME/.ipython`.
251 :file:`$HOME/.ipython`.
252
252
253 For most users, the default value will simply be something like
253 For most users, the default value will simply be something like
254 :file:`$HOME/.ipython`.
254 :file:`$HOME/.ipython`.
255
255
256 Once the location of the IPython directory has been determined, you need to
256 Once the location of the IPython directory has been determined, you need to
257 know what filename to use for the configuration file. The basic idea is that
257 know what filename to use for the configuration file. The basic idea is that
258 each application has its own default configuration filename. The default named
258 each application has its own default configuration filename. The default named
259 used by the :command:`ipython` command line program is
259 used by the :command:`ipython` command line program is
260 :file:`ipython_config.py`. This value can be overriden by the ``-config_file``
260 :file:`ipython_config.py`. This value can be overriden by the ``-config_file``
261 command line flag. A sample :file:`ipython_config.py` file can be found
261 command line flag. A sample :file:`ipython_config.py` file can be found
262 in :mod:`IPython.config.default.ipython_config.py`. Simple copy it to your
262 in :mod:`IPython.config.default.ipython_config.py`. Simple copy it to your
263 IPython directory to begin using it.
263 IPython directory to begin using it.
264
264
265 .. _Profiles:
265 .. _Profiles:
266
266
267 Profiles
267 Profiles
268 ========
268 ========
269
269
270 A profile is simply a configuration file that follows a simple naming
270 A profile is simply a configuration file that follows a simple naming
271 convention and can be loaded using a simplified syntax. The idea is
271 convention and can be loaded using a simplified syntax. The idea is
272 that users often want to maintain a set of configuration files for different
272 that users often want to maintain a set of configuration files for different
273 purposes: one for doing numerical computing with NumPy and SciPy and
273 purposes: one for doing numerical computing with NumPy and SciPy and
274 another for doing symbolic computing with SymPy. Profiles make it easy
274 another for doing symbolic computing with SymPy. Profiles make it easy
275 to keep a separate configuration file for each of these purposes.
275 to keep a separate configuration file for each of these purposes.
276
276
277 Let's start by showing how a profile is used:
277 Let's start by showing how a profile is used:
278
278
279 .. code-block:: bash
279 .. code-block:: bash
280
280
281 $ ipython -p sympy
281 $ ipython -p sympy
282
282
283 This tells the :command:`ipython` command line program to get its
283 This tells the :command:`ipython` command line program to get its
284 configuration from the "sympy" profile. The search path for profiles is the
284 configuration from the "sympy" profile. The search path for profiles is the
285 same as that of regular configuration files. The only difference is that
285 same as that of regular configuration files. The only difference is that
286 profiles are named in a special way. In the case above, the "sympy" profile
286 profiles are named in a special way. In the case above, the "sympy" profile
287 would need to have the name :file:`ipython_config_sympy.py`.
287 would need to have the name :file:`ipython_config_sympy.py`.
288
288
289 The general pattern is this: simply add ``_profilename`` to the end of the
289 The general pattern is this: simply add ``_profilename`` to the end of the
290 normal configuration file name. Then load the profile by adding ``-p
290 normal configuration file name. Then load the profile by adding ``-p
291 profilename`` to your command line options.
291 profilename`` to your command line options.
292
292
293 IPython ships with some sample profiles in :mod:`IPython.config.profile`.
293 IPython ships with some sample profiles in :mod:`IPython.config.profile`.
294 Simply copy these to your IPython directory to begin using them.
294 Simply copy these to your IPython directory to begin using them.
295
295
296 Design requirements
296 Design requirements
297 ===================
297 ===================
298
298
299 Here are the main requirements we wanted our configuration system to have:
299 Here are the main requirements we wanted our configuration system to have:
300
300
301 * Support for hierarchical configuration information.
301 * Support for hierarchical configuration information.
302
302
303 * Full integration with command line option parsers. Often, you want to read
303 * Full integration with command line option parsers. Often, you want to read
304 a configuration file, but then override some of the values with command line
304 a configuration file, but then override some of the values with command line
305 options. Our configuration system automates this process and allows each
305 options. Our configuration system automates this process and allows each
306 command line option to be linked to a particular attribute in the
306 command line option to be linked to a particular attribute in the
307 configuration hierarchy that it will override.
307 configuration hierarchy that it will override.
308
308
309 * Configuration files that are themselves valid Python code. This accomplishes
309 * Configuration files that are themselves valid Python code. This accomplishes
310 many things. First, it becomes possible to put logic in your configuration
310 many things. First, it becomes possible to put logic in your configuration
311 files that sets attributes based on your operating system, network setup,
311 files that sets attributes based on your operating system, network setup,
312 Python version, etc. Second, Python has a super simple syntax for accessing
312 Python version, etc. Second, Python has a super simple syntax for accessing
313 hierarchical data structures, namely regular attribute access
313 hierarchical data structures, namely regular attribute access
314 (``Foo.Bar.Bam.name``). Third, using Python makes it easy for users to
314 (``Foo.Bar.Bam.name``). Third, using Python makes it easy for users to
315 import configuration attributes from one configuration file to another.
315 import configuration attributes from one configuration file to another.
316 Forth, even though Python is dynamically typed, it does have types that can
316 Forth, even though Python is dynamically typed, it does have types that can
317 be checked at runtime. Thus, a ``1`` in a config file is the integer '1',
317 be checked at runtime. Thus, a ``1`` in a config file is the integer '1',
318 while a ``'1'`` is a string.
318 while a ``'1'`` is a string.
319
319
320 * A fully automated method for getting the configuration information to the
320 * A fully automated method for getting the configuration information to the
321 classes that need it at runtime. Writing code that walks a configuration
321 classes that need it at runtime. Writing code that walks a configuration
322 hierarchy to extract a particular attribute is painful. When you have
322 hierarchy to extract a particular attribute is painful. When you have
323 complex configuration information with hundreds of attributes, this makes
323 complex configuration information with hundreds of attributes, this makes
324 you want to cry.
324 you want to cry.
325
325
326 * Type checking and validation that doesn't require the entire configuration
326 * Type checking and validation that doesn't require the entire configuration
327 hierarchy to be specified statically before runtime. Python is a very
327 hierarchy to be specified statically before runtime. Python is a very
328 dynamic language and you don't always know everything that needs to be
328 dynamic language and you don't always know everything that needs to be
329 configured when a program starts.
329 configured when a program starts.
330
330
331
331
General Comments 0
You need to be logged in to leave comments. Login now