##// END OF EJS Templates
Final changes traitlet -> trait for review
Dav Clark -
Show More
@@ -1,325 +1,325 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 A lightweight component system for IPython.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from copy import deepcopy
24 24 import datetime
25 25 from weakref import WeakValueDictionary
26 26
27 27 from IPython.utils.importstring import import_item
28 28 from IPython.config.loader import Config
29 29 from IPython.utils.traitlets import (
30 HasTraits, TraitletError, MetaHasTraits, Instance, This
30 HasTraits, TraitError, MetaHasTraits, Instance, This
31 31 )
32 32
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Helper classes for Components
36 36 #-----------------------------------------------------------------------------
37 37
38 38
39 39 class ComponentError(Exception):
40 40 pass
41 41
42 42 class MetaComponentTracker(type):
43 43 """A metaclass that tracks instances of Components and its subclasses."""
44 44
45 45 def __init__(cls, name, bases, d):
46 46 super(MetaComponentTracker, cls).__init__(name, bases, d)
47 47 cls.__instance_refs = WeakValueDictionary()
48 48 cls.__numcreated = 0
49 49
50 50 def __call__(cls, *args, **kw):
51 51 """Called when a class is called (instantiated)!!!
52 52
53 53 When a Component or subclass is instantiated, this is called and
54 54 the instance is saved in a WeakValueDictionary for tracking.
55 55 """
56 56 instance = cls.__new__(cls, *args, **kw)
57 57
58 58 # Register the instance before __init__ is called so get_instances
59 59 # works inside __init__ methods!
60 60 indices = cls.register_instance(instance)
61 61
62 62 # This is in a try/except because of the __init__ method fails, the
63 63 # instance is discarded and shouldn't be tracked.
64 64 try:
65 65 if isinstance(instance, cls):
66 66 cls.__init__(instance, *args, **kw)
67 67 except:
68 68 # Unregister the instance because __init__ failed!
69 69 cls.unregister_instances(indices)
70 70 raise
71 71 else:
72 72 return instance
73 73
74 74 def register_instance(cls, instance):
75 75 """Register instance with cls and its subclasses."""
76 76 # indices is a list of the keys used to register the instance
77 77 # with. This list is needed if the instance needs to be unregistered.
78 78 indices = []
79 79 for c in cls.__mro__:
80 80 if issubclass(cls, c) and issubclass(c, Component):
81 81 c.__numcreated += 1
82 82 indices.append(c.__numcreated)
83 83 c.__instance_refs[c.__numcreated] = instance
84 84 else:
85 85 break
86 86 return indices
87 87
88 88 def unregister_instances(cls, indices):
89 89 """Unregister instance with cls and its subclasses."""
90 90 for c, index in zip(cls.__mro__, indices):
91 91 try:
92 92 del c.__instance_refs[index]
93 93 except KeyError:
94 94 pass
95 95
96 96 def clear_instances(cls):
97 97 """Clear all instances tracked by cls."""
98 98 cls.__instance_refs.clear()
99 99 cls.__numcreated = 0
100 100
101 101 def get_instances(cls, name=None, root=None, klass=None):
102 102 """Get all instances of cls and its subclasses.
103 103
104 104 Parameters
105 105 ----------
106 106 name : str
107 107 Limit to components with this name.
108 108 root : Component or subclass
109 109 Limit to components having this root.
110 110 klass : class or str
111 111 Limits to instances of the class or its subclasses. If a str
112 112 is given ut must be in the form 'foo.bar.MyClass'. The str
113 113 form of this argument is useful for forward declarations.
114 114 """
115 115 if klass is not None:
116 116 if isinstance(klass, basestring):
117 117 klass = import_item(klass)
118 118 # Limit search to instances of klass for performance
119 119 if issubclass(klass, Component):
120 120 return klass.get_instances(name=name, root=root)
121 121 instances = cls.__instance_refs.values()
122 122 if name is not None:
123 123 instances = [i for i in instances if i.name == name]
124 124 if klass is not None:
125 125 instances = [i for i in instances if isinstance(i, klass)]
126 126 if root is not None:
127 127 instances = [i for i in instances if i.root == root]
128 128 return instances
129 129
130 130 def get_instances_by_condition(cls, call, name=None, root=None,
131 131 klass=None):
132 132 """Get all instances of cls, i such that call(i)==True.
133 133
134 134 This also takes the ``name`` and ``root`` and ``classname``
135 135 arguments of :meth:`get_instance`
136 136 """
137 137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
138 138
139 139
140 140 def masquerade_as(instance, cls):
141 141 """Let instance masquerade as an instance of cls.
142 142
143 143 Sometimes, such as in testing code, it is useful to let a class
144 144 masquerade as another. Python, being duck typed, allows this by
145 145 default. But, instances of components are tracked by their class type.
146 146
147 147 After calling this, ``cls.get_instances()`` will return ``instance``. This
148 148 does not, however, cause ``isinstance(instance, cls)`` to return ``True``.
149 149
150 150 Parameters
151 151 ----------
152 152 instance : an instance of a Component or Component subclass
153 153 The instance that will pretend to be a cls.
154 154 cls : subclass of Component
155 155 The Component subclass that instance will pretend to be.
156 156 """
157 157 cls.register_instance(instance)
158 158
159 159
160 160 class ComponentNameGenerator(object):
161 161 """A Singleton to generate unique component names."""
162 162
163 163 def __init__(self, prefix):
164 164 self.prefix = prefix
165 165 self.i = 0
166 166
167 167 def __call__(self):
168 168 count = self.i
169 169 self.i += 1
170 170 return "%s%s" % (self.prefix, count)
171 171
172 172
173 173 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
174 174
175 175
176 176 class MetaComponent(MetaHasTraits, MetaComponentTracker):
177 177 pass
178 178
179 179
180 180 #-----------------------------------------------------------------------------
181 181 # Component implementation
182 182 #-----------------------------------------------------------------------------
183 183
184 184
185 185 class Component(HasTraits):
186 186
187 187 __metaclass__ = MetaComponent
188 188
189 # Traitlets are fun!
189 # Traits are fun!
190 190 config = Instance(Config,(),{})
191 191 parent = This()
192 192 root = This()
193 193 created = None
194 194
195 195 def __init__(self, parent, name=None, config=None):
196 196 """Create a component given a parent and possibly and name and config.
197 197
198 198 Parameters
199 199 ----------
200 200 parent : Component subclass
201 201 The parent in the component graph. The parent is used
202 202 to get the root of the component graph.
203 203 name : str
204 204 The unique name of the component. If empty, then a unique
205 205 one will be autogenerated.
206 206 config : Config
207 207 If this is empty, self.config = parent.config, otherwise
208 208 self.config = config and root.config is ignored. This argument
209 209 should only be used to *override* the automatic inheritance of
210 210 parent.config. If a caller wants to modify parent.config
211 211 (not override), the caller should make a copy and change
212 212 attributes and then pass the copy to this argument.
213 213
214 214 Notes
215 215 -----
216 216 Subclasses of Component must call the :meth:`__init__` method of
217 217 :class:`Component` *before* doing anything else and using
218 218 :func:`super`::
219 219
220 220 class MyComponent(Component):
221 221 def __init__(self, parent, name=None, config=None):
222 222 super(MyComponent, self).__init__(parent, name, config)
223 223 # Then any other code you need to finish initialization.
224 224
225 225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
226 226 attributes are handled properly.
227 227 """
228 228 super(Component, self).__init__()
229 229 self._children = []
230 230 if name is None:
231 231 self.name = ComponentNameGenerator()
232 232 else:
233 233 self.name = name
234 234 self.root = self # This is the default, it is set when parent is set
235 235 self.parent = parent
236 236 if config is not None:
237 237 self.config = config
238 238 # We used to deepcopy, but for now we are trying to just save
239 239 # by reference. This *could* have side effects as all components
240 240 # will share config.
241 241 # self.config = deepcopy(config)
242 242 else:
243 243 if self.parent is not None:
244 244 self.config = self.parent.config
245 245 # We used to deepcopy, but for now we are trying to just save
246 246 # by reference. This *could* have side effects as all components
247 247 # will share config.
248 248 # self.config = deepcopy(self.parent.config)
249 249
250 250 self.created = datetime.datetime.now()
251 251
252 252 #-------------------------------------------------------------------------
253 # Static traitlet notifiations
253 # Static trait notifiations
254 254 #-------------------------------------------------------------------------
255 255
256 256 def _parent_changed(self, name, old, new):
257 257 if old is not None:
258 258 old._remove_child(self)
259 259 if new is not None:
260 260 new._add_child(self)
261 261
262 262 if new is None:
263 263 self.root = self
264 264 else:
265 265 self.root = new.root
266 266
267 267 def _root_changed(self, name, old, new):
268 268 if self.parent is None:
269 269 if not (new is self):
270 270 raise ComponentError("Root not self, but parent is None.")
271 271 else:
272 272 if not self.parent.root is new:
273 273 raise ComponentError("Error in setting the root attribute: "
274 274 "root != parent.root")
275 275
276 276 def _config_changed(self, name, old, new):
277 277 """Update all the class traits having ``config=True`` as metadata.
278 278
279 For any class traitlet with a ``config`` metadata attribute that is
280 ``True``, we update the traitlet with the value of the corresponding
279 For any class trait with a ``config`` metadata attribute that is
280 ``True``, we update the trait with the value of the corresponding
281 281 config entry.
282 282 """
283 # Get all traitlets with a config metadata entry that is True
284 traitlets = self.traits(config=True)
283 # Get all traits with a config metadata entry that is True
284 traits = self.traits(config=True)
285 285
286 286 # We auto-load config section for this class as well as any parent
287 287 # classes that are Component subclasses. This starts with Component
288 288 # and works down the mro loading the config for each section.
289 289 section_names = [cls.__name__ for cls in \
290 290 reversed(self.__class__.__mro__) if
291 291 issubclass(cls, Component) and issubclass(self.__class__, cls)]
292 292
293 293 for sname in section_names:
294 294 # Don't do a blind getattr as that would cause the config to
295 295 # dynamically create the section with name self.__class__.__name__.
296 296 if new._has_section(sname):
297 297 my_config = new[sname]
298 for k, v in traitlets.items():
298 for k, v in traits.items():
299 299 try:
300 300 config_value = my_config[k]
301 301 except KeyError:
302 302 pass
303 303 else:
304 304 # print "Setting %s.%s from %s.%s=%r" % \
305 305 # (self.__class__.__name__,k,sname,k,config_value)
306 306 setattr(self, k, config_value)
307 307
308 308 @property
309 309 def children(self):
310 310 """A list of all my child components."""
311 311 return self._children
312 312
313 313 def _remove_child(self, child):
314 314 """A private method for removing children components."""
315 315 if child in self._children:
316 316 index = self._children.index(child)
317 317 del self._children[index]
318 318
319 319 def _add_child(self, child):
320 320 """A private method for adding children components."""
321 321 if child not in self._children:
322 322 self._children.append(child)
323 323
324 324 def __repr__(self):
325 325 return "<%s('%s')>" % (self.__class__.__name__, self.name)
@@ -1,2470 +1,2470 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Main IPython Component
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 9 # Copyright (C) 2008-2009 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from __future__ import with_statement
20 20
21 21 import __builtin__
22 22 import StringIO
23 23 import bdb
24 24 import codeop
25 25 import exceptions
26 26 import new
27 27 import os
28 28 import re
29 29 import string
30 30 import sys
31 31 import tempfile
32 32 from contextlib import nested
33 33
34 34 from IPython.core import ultratb
35 35 from IPython.core import debugger, oinspect
36 36 from IPython.core import shadowns
37 37 from IPython.core import history as ipcorehist
38 38 from IPython.core import prefilter
39 39 from IPython.core.alias import AliasManager
40 40 from IPython.core.builtin_trap import BuiltinTrap
41 41 from IPython.core.display_trap import DisplayTrap
42 42 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
43 43 from IPython.core.logger import Logger
44 44 from IPython.core.magic import Magic
45 45 from IPython.core.prompts import CachedOutput
46 46 from IPython.core.prefilter import PrefilterManager
47 47 from IPython.core.component import Component
48 48 from IPython.core.usage import interactive_usage, default_banner
49 49 from IPython.core.error import TryNext, UsageError
50 50
51 51 from IPython.utils import pickleshare
52 52 from IPython.external.Itpl import ItplNS
53 53 from IPython.lib.backgroundjobs import BackgroundJobManager
54 54 from IPython.utils.ipstruct import Struct
55 55 from IPython.utils import PyColorize
56 56 from IPython.utils.genutils import *
57 57 from IPython.utils.genutils import get_ipython_dir
58 58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
59 59 from IPython.utils.strdispatch import StrDispatch
60 60 from IPython.utils.syspathcontext import prepended_to_syspath
61 61
62 62 # from IPython.utils import growl
63 63 # growl.start("IPython")
64 64
65 65 from IPython.utils.traitlets import (
66 66 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
67 67 )
68 68
69 69 #-----------------------------------------------------------------------------
70 70 # Globals
71 71 #-----------------------------------------------------------------------------
72 72
73 73
74 74 # store the builtin raw_input globally, and use this always, in case user code
75 75 # overwrites it (like wx.py.PyShell does)
76 76 raw_input_original = raw_input
77 77
78 78 # compiled regexps for autoindent management
79 79 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
80 80
81 81
82 82 #-----------------------------------------------------------------------------
83 83 # Utilities
84 84 #-----------------------------------------------------------------------------
85 85
86 86
87 87 ini_spaces_re = re.compile(r'^(\s+)')
88 88
89 89
90 90 def num_ini_spaces(strng):
91 91 """Return the number of initial spaces in a string"""
92 92
93 93 ini_spaces = ini_spaces_re.match(strng)
94 94 if ini_spaces:
95 95 return ini_spaces.end()
96 96 else:
97 97 return 0
98 98
99 99
100 100 def softspace(file, newvalue):
101 101 """Copied from code.py, to remove the dependency"""
102 102
103 103 oldvalue = 0
104 104 try:
105 105 oldvalue = file.softspace
106 106 except AttributeError:
107 107 pass
108 108 try:
109 109 file.softspace = newvalue
110 110 except (AttributeError, TypeError):
111 111 # "attribute-less object" or "read-only attributes"
112 112 pass
113 113 return oldvalue
114 114
115 115
116 116 class SpaceInInput(exceptions.Exception): pass
117 117
118 118 class Bunch: pass
119 119
120 120 class InputList(list):
121 121 """Class to store user input.
122 122
123 123 It's basically a list, but slices return a string instead of a list, thus
124 124 allowing things like (assuming 'In' is an instance):
125 125
126 126 exec In[4:7]
127 127
128 128 or
129 129
130 130 exec In[5:9] + In[14] + In[21:25]"""
131 131
132 132 def __getslice__(self,i,j):
133 133 return ''.join(list.__getslice__(self,i,j))
134 134
135 135
136 136 class SyntaxTB(ultratb.ListTB):
137 137 """Extension which holds some state: the last exception value"""
138 138
139 139 def __init__(self,color_scheme = 'NoColor'):
140 140 ultratb.ListTB.__init__(self,color_scheme)
141 141 self.last_syntax_error = None
142 142
143 143 def __call__(self, etype, value, elist):
144 144 self.last_syntax_error = value
145 145 ultratb.ListTB.__call__(self,etype,value,elist)
146 146
147 147 def clear_err_state(self):
148 148 """Return the current error state and clear it"""
149 149 e = self.last_syntax_error
150 150 self.last_syntax_error = None
151 151 return e
152 152
153 153
154 154 def get_default_editor():
155 155 try:
156 156 ed = os.environ['EDITOR']
157 157 except KeyError:
158 158 if os.name == 'posix':
159 159 ed = 'vi' # the only one guaranteed to be there!
160 160 else:
161 161 ed = 'notepad' # same in Windows!
162 162 return ed
163 163
164 164
165 165 class SeparateStr(Str):
166 166 """A Str subclass to validate separate_in, separate_out, etc.
167 167
168 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
168 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
169 169 """
170 170
171 171 def validate(self, obj, value):
172 172 if value == '0': value = ''
173 173 value = value.replace('\\n','\n')
174 174 return super(SeparateStr, self).validate(obj, value)
175 175
176 176
177 177 #-----------------------------------------------------------------------------
178 178 # Main IPython class
179 179 #-----------------------------------------------------------------------------
180 180
181 181
182 182 class InteractiveShell(Component, Magic):
183 183 """An enhanced, interactive shell for Python."""
184 184
185 185 autocall = Enum((0,1,2), config=True)
186 186 autoedit_syntax = CBool(False, config=True)
187 187 autoindent = CBool(True, config=True)
188 188 automagic = CBool(True, config=True)
189 189 banner = Str('')
190 190 banner1 = Str(default_banner, config=True)
191 191 banner2 = Str('', config=True)
192 192 cache_size = Int(1000, config=True)
193 193 color_info = CBool(True, config=True)
194 194 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
195 195 default_value='LightBG', config=True)
196 196 confirm_exit = CBool(True, config=True)
197 197 debug = CBool(False, config=True)
198 198 deep_reload = CBool(False, config=True)
199 199 # This display_banner only controls whether or not self.show_banner()
200 200 # is called when mainloop/interact are called. The default is False
201 201 # because for the terminal based application, the banner behavior
202 202 # is controlled by Global.display_banner, which IPythonApp looks at
203 203 # to determine if *it* should call show_banner() by hand or not.
204 204 display_banner = CBool(False) # This isn't configurable!
205 205 embedded = CBool(False)
206 206 embedded_active = CBool(False)
207 207 editor = Str(get_default_editor(), config=True)
208 208 filename = Str("<ipython console>")
209 209 ipythondir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
210 210 logstart = CBool(False, config=True)
211 211 logfile = Str('', config=True)
212 212 logappend = Str('', config=True)
213 213 object_info_string_level = Enum((0,1,2), default_value=0,
214 214 config=True)
215 215 pager = Str('less', config=True)
216 216 pdb = CBool(False, config=True)
217 217 pprint = CBool(True, config=True)
218 218 profile = Str('', config=True)
219 219 prompt_in1 = Str('In [\\#]: ', config=True)
220 220 prompt_in2 = Str(' .\\D.: ', config=True)
221 221 prompt_out = Str('Out[\\#]: ', config=True)
222 222 prompts_pad_left = CBool(True, config=True)
223 223 quiet = CBool(False, config=True)
224 224
225 225 readline_use = CBool(True, config=True)
226 226 readline_merge_completions = CBool(True, config=True)
227 227 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
228 228 readline_remove_delims = Str('-/~', config=True)
229 229 readline_parse_and_bind = List([
230 230 'tab: complete',
231 231 '"\C-l": possible-completions',
232 232 'set show-all-if-ambiguous on',
233 233 '"\C-o": tab-insert',
234 234 '"\M-i": " "',
235 235 '"\M-o": "\d\d\d\d"',
236 236 '"\M-I": "\d\d\d\d"',
237 237 '"\C-r": reverse-search-history',
238 238 '"\C-s": forward-search-history',
239 239 '"\C-p": history-search-backward',
240 240 '"\C-n": history-search-forward',
241 241 '"\e[A": history-search-backward',
242 242 '"\e[B": history-search-forward',
243 243 '"\C-k": kill-line',
244 244 '"\C-u": unix-line-discard',
245 245 ], allow_none=False, config=True)
246 246
247 247 screen_length = Int(0, config=True)
248 248
249 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
249 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
250 250 separate_in = SeparateStr('\n', config=True)
251 251 separate_out = SeparateStr('', config=True)
252 252 separate_out2 = SeparateStr('', config=True)
253 253
254 254 system_header = Str('IPython system call: ', config=True)
255 255 system_verbose = CBool(False, config=True)
256 256 term_title = CBool(False, config=True)
257 257 wildcards_case_sensitive = CBool(True, config=True)
258 258 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
259 259 default_value='Context', config=True)
260 260
261 261 autoexec = List(allow_none=False)
262 262
263 263 # class attribute to indicate whether the class supports threads or not.
264 264 # Subclasses with thread support should override this as needed.
265 265 isthreaded = False
266 266
267 267 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
268 268 user_ns=None, user_global_ns=None,
269 269 banner1=None, banner2=None, display_banner=None,
270 270 custom_exceptions=((),None)):
271 271
272 # This is where traitlets with a config_key argument are updated
272 # This is where traits with a config_key argument are updated
273 273 # from the values on config.
274 274 super(InteractiveShell, self).__init__(parent, config=config)
275 275
276 276 # These are relatively independent and stateless
277 277 self.init_ipythondir(ipythondir)
278 278 self.init_instance_attrs()
279 279 self.init_term_title()
280 280 self.init_usage(usage)
281 281 self.init_banner(banner1, banner2, display_banner)
282 282
283 283 # Create namespaces (user_ns, user_global_ns, etc.)
284 284 self.init_create_namespaces(user_ns, user_global_ns)
285 285 # This has to be done after init_create_namespaces because it uses
286 286 # something in self.user_ns, but before init_sys_modules, which
287 287 # is the first thing to modify sys.
288 288 self.save_sys_module_state()
289 289 self.init_sys_modules()
290 290
291 291 self.init_history()
292 292 self.init_encoding()
293 293 self.init_prefilter()
294 294
295 295 Magic.__init__(self, self)
296 296
297 297 self.init_syntax_highlighting()
298 298 self.init_hooks()
299 299 self.init_pushd_popd_magic()
300 300 self.init_traceback_handlers(custom_exceptions)
301 301 self.init_user_ns()
302 302 self.init_logger()
303 303 self.init_alias()
304 304 self.init_builtins()
305 305
306 306 # pre_config_initialization
307 307 self.init_shadow_hist()
308 308
309 309 # The next section should contain averything that was in ipmaker.
310 310 self.init_logstart()
311 311
312 312 # The following was in post_config_initialization
313 313 self.init_inspector()
314 314 self.init_readline()
315 315 self.init_prompts()
316 316 self.init_displayhook()
317 317 self.init_reload_doctest()
318 318 self.init_magics()
319 319 self.init_pdb()
320 320 self.hooks.late_startup_hook()
321 321
322 322 def get_ipython(self):
323 323 return self
324 324
325 325 #-------------------------------------------------------------------------
326 # Traitlet changed handlers
326 # Trait changed handlers
327 327 #-------------------------------------------------------------------------
328 328
329 329 def _banner1_changed(self):
330 330 self.compute_banner()
331 331
332 332 def _banner2_changed(self):
333 333 self.compute_banner()
334 334
335 335 def _ipythondir_changed(self, name, new):
336 336 if not os.path.isdir(new):
337 337 os.makedirs(new, mode = 0777)
338 338 if not os.path.isdir(self.ipython_extension_dir):
339 339 os.makedirs(self.ipython_extension_dir, mode = 0777)
340 340
341 341 @property
342 342 def ipython_extension_dir(self):
343 343 return os.path.join(self.ipythondir, 'extensions')
344 344
345 345 @property
346 346 def usable_screen_length(self):
347 347 if self.screen_length == 0:
348 348 return 0
349 349 else:
350 350 num_lines_bot = self.separate_in.count('\n')+1
351 351 return self.screen_length - num_lines_bot
352 352
353 353 def _term_title_changed(self, name, new_value):
354 354 self.init_term_title()
355 355
356 356 def set_autoindent(self,value=None):
357 357 """Set the autoindent flag, checking for readline support.
358 358
359 359 If called with no arguments, it acts as a toggle."""
360 360
361 361 if not self.has_readline:
362 362 if os.name == 'posix':
363 363 warn("The auto-indent feature requires the readline library")
364 364 self.autoindent = 0
365 365 return
366 366 if value is None:
367 367 self.autoindent = not self.autoindent
368 368 else:
369 369 self.autoindent = value
370 370
371 371 #-------------------------------------------------------------------------
372 372 # init_* methods called by __init__
373 373 #-------------------------------------------------------------------------
374 374
375 375 def init_ipythondir(self, ipythondir):
376 376 if ipythondir is not None:
377 377 self.ipythondir = ipythondir
378 378 self.config.Global.ipythondir = self.ipythondir
379 379 return
380 380
381 381 if hasattr(self.config.Global, 'ipythondir'):
382 382 self.ipythondir = self.config.Global.ipythondir
383 383 else:
384 384 self.ipythondir = get_ipython_dir()
385 385
386 386 # All children can just read this
387 387 self.config.Global.ipythondir = self.ipythondir
388 388
389 389 def init_instance_attrs(self):
390 390 self.jobs = BackgroundJobManager()
391 391 self.more = False
392 392
393 393 # command compiler
394 394 self.compile = codeop.CommandCompiler()
395 395
396 396 # User input buffer
397 397 self.buffer = []
398 398
399 399 # Make an empty namespace, which extension writers can rely on both
400 400 # existing and NEVER being used by ipython itself. This gives them a
401 401 # convenient location for storing additional information and state
402 402 # their extensions may require, without fear of collisions with other
403 403 # ipython names that may develop later.
404 404 self.meta = Struct()
405 405
406 406 # Object variable to store code object waiting execution. This is
407 407 # used mainly by the multithreaded shells, but it can come in handy in
408 408 # other situations. No need to use a Queue here, since it's a single
409 409 # item which gets cleared once run.
410 410 self.code_to_run = None
411 411
412 412 # Flag to mark unconditional exit
413 413 self.exit_now = False
414 414
415 415 # Temporary files used for various purposes. Deleted at exit.
416 416 self.tempfiles = []
417 417
418 418 # Keep track of readline usage (later set by init_readline)
419 419 self.has_readline = False
420 420
421 421 # keep track of where we started running (mainly for crash post-mortem)
422 422 # This is not being used anywhere currently.
423 423 self.starting_dir = os.getcwd()
424 424
425 425 # Indentation management
426 426 self.indent_current_nsp = 0
427 427
428 428 def init_term_title(self):
429 429 # Enable or disable the terminal title.
430 430 if self.term_title:
431 431 toggle_set_term_title(True)
432 432 set_term_title('IPython: ' + abbrev_cwd())
433 433 else:
434 434 toggle_set_term_title(False)
435 435
436 436 def init_usage(self, usage=None):
437 437 if usage is None:
438 438 self.usage = interactive_usage
439 439 else:
440 440 self.usage = usage
441 441
442 442 def init_encoding(self):
443 443 # Get system encoding at startup time. Certain terminals (like Emacs
444 444 # under Win32 have it set to None, and we need to have a known valid
445 445 # encoding to use in the raw_input() method
446 446 try:
447 447 self.stdin_encoding = sys.stdin.encoding or 'ascii'
448 448 except AttributeError:
449 449 self.stdin_encoding = 'ascii'
450 450
451 451 def init_syntax_highlighting(self):
452 452 # Python source parser/formatter for syntax highlighting
453 453 pyformat = PyColorize.Parser().format
454 454 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
455 455
456 456 def init_pushd_popd_magic(self):
457 457 # for pushd/popd management
458 458 try:
459 459 self.home_dir = get_home_dir()
460 460 except HomeDirError, msg:
461 461 fatal(msg)
462 462
463 463 self.dir_stack = []
464 464
465 465 def init_logger(self):
466 466 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
467 467 # local shortcut, this is used a LOT
468 468 self.log = self.logger.log
469 469
470 470 def init_logstart(self):
471 471 if self.logappend:
472 472 self.magic_logstart(self.logappend + ' append')
473 473 elif self.logfile:
474 474 self.magic_logstart(self.logfile)
475 475 elif self.logstart:
476 476 self.magic_logstart()
477 477
478 478 def init_builtins(self):
479 479 self.builtin_trap = BuiltinTrap(self)
480 480
481 481 def init_inspector(self):
482 482 # Object inspector
483 483 self.inspector = oinspect.Inspector(oinspect.InspectColors,
484 484 PyColorize.ANSICodeColors,
485 485 'NoColor',
486 486 self.object_info_string_level)
487 487
488 488 def init_prompts(self):
489 489 # Initialize cache, set in/out prompts and printing system
490 490 self.outputcache = CachedOutput(self,
491 491 self.cache_size,
492 492 self.pprint,
493 493 input_sep = self.separate_in,
494 494 output_sep = self.separate_out,
495 495 output_sep2 = self.separate_out2,
496 496 ps1 = self.prompt_in1,
497 497 ps2 = self.prompt_in2,
498 498 ps_out = self.prompt_out,
499 499 pad_left = self.prompts_pad_left)
500 500
501 501 # user may have over-ridden the default print hook:
502 502 try:
503 503 self.outputcache.__class__.display = self.hooks.display
504 504 except AttributeError:
505 505 pass
506 506
507 507 def init_displayhook(self):
508 508 self.display_trap = DisplayTrap(self, self.outputcache)
509 509
510 510 def init_reload_doctest(self):
511 511 # Do a proper resetting of doctest, including the necessary displayhook
512 512 # monkeypatching
513 513 try:
514 514 doctest_reload()
515 515 except ImportError:
516 516 warn("doctest module does not exist.")
517 517
518 518 #-------------------------------------------------------------------------
519 519 # Things related to the banner
520 520 #-------------------------------------------------------------------------
521 521
522 522 def init_banner(self, banner1, banner2, display_banner):
523 523 if banner1 is not None:
524 524 self.banner1 = banner1
525 525 if banner2 is not None:
526 526 self.banner2 = banner2
527 527 if display_banner is not None:
528 528 self.display_banner = display_banner
529 529 self.compute_banner()
530 530
531 531 def show_banner(self, banner=None):
532 532 if banner is None:
533 533 banner = self.banner
534 534 self.write(banner)
535 535
536 536 def compute_banner(self):
537 537 self.banner = self.banner1 + '\n'
538 538 if self.profile:
539 539 self.banner += '\nIPython profile: %s\n' % self.profile
540 540 if self.banner2:
541 541 self.banner += '\n' + self.banner2 + '\n'
542 542
543 543 #-------------------------------------------------------------------------
544 544 # Things related to injections into the sys module
545 545 #-------------------------------------------------------------------------
546 546
547 547 def save_sys_module_state(self):
548 548 """Save the state of hooks in the sys module.
549 549
550 550 This has to be called after self.user_ns is created.
551 551 """
552 552 self._orig_sys_module_state = {}
553 553 self._orig_sys_module_state['stdin'] = sys.stdin
554 554 self._orig_sys_module_state['stdout'] = sys.stdout
555 555 self._orig_sys_module_state['stderr'] = sys.stderr
556 556 self._orig_sys_module_state['excepthook'] = sys.excepthook
557 557 try:
558 558 self._orig_sys_modules_main_name = self.user_ns['__name__']
559 559 except KeyError:
560 560 pass
561 561
562 562 def restore_sys_module_state(self):
563 563 """Restore the state of the sys module."""
564 564 try:
565 565 for k, v in self._orig_sys_module_state.items():
566 566 setattr(sys, k, v)
567 567 except AttributeError:
568 568 pass
569 569 try:
570 570 delattr(sys, 'ipcompleter')
571 571 except AttributeError:
572 572 pass
573 573 # Reset what what done in self.init_sys_modules
574 574 try:
575 575 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
576 576 except (AttributeError, KeyError):
577 577 pass
578 578
579 579 #-------------------------------------------------------------------------
580 580 # Things related to hooks
581 581 #-------------------------------------------------------------------------
582 582
583 583 def init_hooks(self):
584 584 # hooks holds pointers used for user-side customizations
585 585 self.hooks = Struct()
586 586
587 587 self.strdispatchers = {}
588 588
589 589 # Set all default hooks, defined in the IPython.hooks module.
590 590 import IPython.core.hooks
591 591 hooks = IPython.core.hooks
592 592 for hook_name in hooks.__all__:
593 593 # default hooks have priority 100, i.e. low; user hooks should have
594 594 # 0-100 priority
595 595 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
596 596
597 597 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
598 598 """set_hook(name,hook) -> sets an internal IPython hook.
599 599
600 600 IPython exposes some of its internal API as user-modifiable hooks. By
601 601 adding your function to one of these hooks, you can modify IPython's
602 602 behavior to call at runtime your own routines."""
603 603
604 604 # At some point in the future, this should validate the hook before it
605 605 # accepts it. Probably at least check that the hook takes the number
606 606 # of args it's supposed to.
607 607
608 608 f = new.instancemethod(hook,self,self.__class__)
609 609
610 610 # check if the hook is for strdispatcher first
611 611 if str_key is not None:
612 612 sdp = self.strdispatchers.get(name, StrDispatch())
613 613 sdp.add_s(str_key, f, priority )
614 614 self.strdispatchers[name] = sdp
615 615 return
616 616 if re_key is not None:
617 617 sdp = self.strdispatchers.get(name, StrDispatch())
618 618 sdp.add_re(re.compile(re_key), f, priority )
619 619 self.strdispatchers[name] = sdp
620 620 return
621 621
622 622 dp = getattr(self.hooks, name, None)
623 623 if name not in IPython.core.hooks.__all__:
624 624 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
625 625 if not dp:
626 626 dp = IPython.core.hooks.CommandChainDispatcher()
627 627
628 628 try:
629 629 dp.add(f,priority)
630 630 except AttributeError:
631 631 # it was not commandchain, plain old func - replace
632 632 dp = f
633 633
634 634 setattr(self.hooks,name, dp)
635 635
636 636 #-------------------------------------------------------------------------
637 637 # Things related to the "main" module
638 638 #-------------------------------------------------------------------------
639 639
640 640 def new_main_mod(self,ns=None):
641 641 """Return a new 'main' module object for user code execution.
642 642 """
643 643 main_mod = self._user_main_module
644 644 init_fakemod_dict(main_mod,ns)
645 645 return main_mod
646 646
647 647 def cache_main_mod(self,ns,fname):
648 648 """Cache a main module's namespace.
649 649
650 650 When scripts are executed via %run, we must keep a reference to the
651 651 namespace of their __main__ module (a FakeModule instance) around so
652 652 that Python doesn't clear it, rendering objects defined therein
653 653 useless.
654 654
655 655 This method keeps said reference in a private dict, keyed by the
656 656 absolute path of the module object (which corresponds to the script
657 657 path). This way, for multiple executions of the same script we only
658 658 keep one copy of the namespace (the last one), thus preventing memory
659 659 leaks from old references while allowing the objects from the last
660 660 execution to be accessible.
661 661
662 662 Note: we can not allow the actual FakeModule instances to be deleted,
663 663 because of how Python tears down modules (it hard-sets all their
664 664 references to None without regard for reference counts). This method
665 665 must therefore make a *copy* of the given namespace, to allow the
666 666 original module's __dict__ to be cleared and reused.
667 667
668 668
669 669 Parameters
670 670 ----------
671 671 ns : a namespace (a dict, typically)
672 672
673 673 fname : str
674 674 Filename associated with the namespace.
675 675
676 676 Examples
677 677 --------
678 678
679 679 In [10]: import IPython
680 680
681 681 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
682 682
683 683 In [12]: IPython.__file__ in _ip._main_ns_cache
684 684 Out[12]: True
685 685 """
686 686 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
687 687
688 688 def clear_main_mod_cache(self):
689 689 """Clear the cache of main modules.
690 690
691 691 Mainly for use by utilities like %reset.
692 692
693 693 Examples
694 694 --------
695 695
696 696 In [15]: import IPython
697 697
698 698 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
699 699
700 700 In [17]: len(_ip._main_ns_cache) > 0
701 701 Out[17]: True
702 702
703 703 In [18]: _ip.clear_main_mod_cache()
704 704
705 705 In [19]: len(_ip._main_ns_cache) == 0
706 706 Out[19]: True
707 707 """
708 708 self._main_ns_cache.clear()
709 709
710 710 #-------------------------------------------------------------------------
711 711 # Things related to debugging
712 712 #-------------------------------------------------------------------------
713 713
714 714 def init_pdb(self):
715 715 # Set calling of pdb on exceptions
716 716 # self.call_pdb is a property
717 717 self.call_pdb = self.pdb
718 718
719 719 def _get_call_pdb(self):
720 720 return self._call_pdb
721 721
722 722 def _set_call_pdb(self,val):
723 723
724 724 if val not in (0,1,False,True):
725 725 raise ValueError,'new call_pdb value must be boolean'
726 726
727 727 # store value in instance
728 728 self._call_pdb = val
729 729
730 730 # notify the actual exception handlers
731 731 self.InteractiveTB.call_pdb = val
732 732 if self.isthreaded:
733 733 try:
734 734 self.sys_excepthook.call_pdb = val
735 735 except:
736 736 warn('Failed to activate pdb for threaded exception handler')
737 737
738 738 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
739 739 'Control auto-activation of pdb at exceptions')
740 740
741 741 def debugger(self,force=False):
742 742 """Call the pydb/pdb debugger.
743 743
744 744 Keywords:
745 745
746 746 - force(False): by default, this routine checks the instance call_pdb
747 747 flag and does not actually invoke the debugger if the flag is false.
748 748 The 'force' option forces the debugger to activate even if the flag
749 749 is false.
750 750 """
751 751
752 752 if not (force or self.call_pdb):
753 753 return
754 754
755 755 if not hasattr(sys,'last_traceback'):
756 756 error('No traceback has been produced, nothing to debug.')
757 757 return
758 758
759 759 # use pydb if available
760 760 if debugger.has_pydb:
761 761 from pydb import pm
762 762 else:
763 763 # fallback to our internal debugger
764 764 pm = lambda : self.InteractiveTB.debugger(force=True)
765 765 self.history_saving_wrapper(pm)()
766 766
767 767 #-------------------------------------------------------------------------
768 768 # Things related to IPython's various namespaces
769 769 #-------------------------------------------------------------------------
770 770
771 771 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
772 772 # Create the namespace where the user will operate. user_ns is
773 773 # normally the only one used, and it is passed to the exec calls as
774 774 # the locals argument. But we do carry a user_global_ns namespace
775 775 # given as the exec 'globals' argument, This is useful in embedding
776 776 # situations where the ipython shell opens in a context where the
777 777 # distinction between locals and globals is meaningful. For
778 778 # non-embedded contexts, it is just the same object as the user_ns dict.
779 779
780 780 # FIXME. For some strange reason, __builtins__ is showing up at user
781 781 # level as a dict instead of a module. This is a manual fix, but I
782 782 # should really track down where the problem is coming from. Alex
783 783 # Schmolck reported this problem first.
784 784
785 785 # A useful post by Alex Martelli on this topic:
786 786 # Re: inconsistent value from __builtins__
787 787 # Von: Alex Martelli <aleaxit@yahoo.com>
788 788 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
789 789 # Gruppen: comp.lang.python
790 790
791 791 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
792 792 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
793 793 # > <type 'dict'>
794 794 # > >>> print type(__builtins__)
795 795 # > <type 'module'>
796 796 # > Is this difference in return value intentional?
797 797
798 798 # Well, it's documented that '__builtins__' can be either a dictionary
799 799 # or a module, and it's been that way for a long time. Whether it's
800 800 # intentional (or sensible), I don't know. In any case, the idea is
801 801 # that if you need to access the built-in namespace directly, you
802 802 # should start with "import __builtin__" (note, no 's') which will
803 803 # definitely give you a module. Yeah, it's somewhat confusing:-(.
804 804
805 805 # These routines return properly built dicts as needed by the rest of
806 806 # the code, and can also be used by extension writers to generate
807 807 # properly initialized namespaces.
808 808 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
809 809 user_global_ns)
810 810
811 811 # Assign namespaces
812 812 # This is the namespace where all normal user variables live
813 813 self.user_ns = user_ns
814 814 self.user_global_ns = user_global_ns
815 815
816 816 # An auxiliary namespace that checks what parts of the user_ns were
817 817 # loaded at startup, so we can list later only variables defined in
818 818 # actual interactive use. Since it is always a subset of user_ns, it
819 819 # doesn't need to be seaparately tracked in the ns_table
820 820 self.user_config_ns = {}
821 821
822 822 # A namespace to keep track of internal data structures to prevent
823 823 # them from cluttering user-visible stuff. Will be updated later
824 824 self.internal_ns = {}
825 825
826 826 # Now that FakeModule produces a real module, we've run into a nasty
827 827 # problem: after script execution (via %run), the module where the user
828 828 # code ran is deleted. Now that this object is a true module (needed
829 829 # so docetst and other tools work correctly), the Python module
830 830 # teardown mechanism runs over it, and sets to None every variable
831 831 # present in that module. Top-level references to objects from the
832 832 # script survive, because the user_ns is updated with them. However,
833 833 # calling functions defined in the script that use other things from
834 834 # the script will fail, because the function's closure had references
835 835 # to the original objects, which are now all None. So we must protect
836 836 # these modules from deletion by keeping a cache.
837 837 #
838 838 # To avoid keeping stale modules around (we only need the one from the
839 839 # last run), we use a dict keyed with the full path to the script, so
840 840 # only the last version of the module is held in the cache. Note,
841 841 # however, that we must cache the module *namespace contents* (their
842 842 # __dict__). Because if we try to cache the actual modules, old ones
843 843 # (uncached) could be destroyed while still holding references (such as
844 844 # those held by GUI objects that tend to be long-lived)>
845 845 #
846 846 # The %reset command will flush this cache. See the cache_main_mod()
847 847 # and clear_main_mod_cache() methods for details on use.
848 848
849 849 # This is the cache used for 'main' namespaces
850 850 self._main_ns_cache = {}
851 851 # And this is the single instance of FakeModule whose __dict__ we keep
852 852 # copying and clearing for reuse on each %run
853 853 self._user_main_module = FakeModule()
854 854
855 855 # A table holding all the namespaces IPython deals with, so that
856 856 # introspection facilities can search easily.
857 857 self.ns_table = {'user':user_ns,
858 858 'user_global':user_global_ns,
859 859 'internal':self.internal_ns,
860 860 'builtin':__builtin__.__dict__
861 861 }
862 862
863 863 # Similarly, track all namespaces where references can be held and that
864 864 # we can safely clear (so it can NOT include builtin). This one can be
865 865 # a simple list.
866 866 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
867 867 self.internal_ns, self._main_ns_cache ]
868 868
869 869 def init_sys_modules(self):
870 870 # We need to insert into sys.modules something that looks like a
871 871 # module but which accesses the IPython namespace, for shelve and
872 872 # pickle to work interactively. Normally they rely on getting
873 873 # everything out of __main__, but for embedding purposes each IPython
874 874 # instance has its own private namespace, so we can't go shoving
875 875 # everything into __main__.
876 876
877 877 # note, however, that we should only do this for non-embedded
878 878 # ipythons, which really mimic the __main__.__dict__ with their own
879 879 # namespace. Embedded instances, on the other hand, should not do
880 880 # this because they need to manage the user local/global namespaces
881 881 # only, but they live within a 'normal' __main__ (meaning, they
882 882 # shouldn't overtake the execution environment of the script they're
883 883 # embedded in).
884 884
885 885 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
886 886
887 887 try:
888 888 main_name = self.user_ns['__name__']
889 889 except KeyError:
890 890 raise KeyError('user_ns dictionary MUST have a "__name__" key')
891 891 else:
892 892 sys.modules[main_name] = FakeModule(self.user_ns)
893 893
894 894 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
895 895 """Return a valid local and global user interactive namespaces.
896 896
897 897 This builds a dict with the minimal information needed to operate as a
898 898 valid IPython user namespace, which you can pass to the various
899 899 embedding classes in ipython. The default implementation returns the
900 900 same dict for both the locals and the globals to allow functions to
901 901 refer to variables in the namespace. Customized implementations can
902 902 return different dicts. The locals dictionary can actually be anything
903 903 following the basic mapping protocol of a dict, but the globals dict
904 904 must be a true dict, not even a subclass. It is recommended that any
905 905 custom object for the locals namespace synchronize with the globals
906 906 dict somehow.
907 907
908 908 Raises TypeError if the provided globals namespace is not a true dict.
909 909
910 910 :Parameters:
911 911 user_ns : dict-like, optional
912 912 The current user namespace. The items in this namespace should
913 913 be included in the output. If None, an appropriate blank
914 914 namespace should be created.
915 915 user_global_ns : dict, optional
916 916 The current user global namespace. The items in this namespace
917 917 should be included in the output. If None, an appropriate
918 918 blank namespace should be created.
919 919
920 920 :Returns:
921 921 A tuple pair of dictionary-like object to be used as the local namespace
922 922 of the interpreter and a dict to be used as the global namespace.
923 923 """
924 924
925 925 if user_ns is None:
926 926 # Set __name__ to __main__ to better match the behavior of the
927 927 # normal interpreter.
928 928 user_ns = {'__name__' :'__main__',
929 929 '__builtins__' : __builtin__,
930 930 }
931 931 else:
932 932 user_ns.setdefault('__name__','__main__')
933 933 user_ns.setdefault('__builtins__',__builtin__)
934 934
935 935 if user_global_ns is None:
936 936 user_global_ns = user_ns
937 937 if type(user_global_ns) is not dict:
938 938 raise TypeError("user_global_ns must be a true dict; got %r"
939 939 % type(user_global_ns))
940 940
941 941 return user_ns, user_global_ns
942 942
943 943 def init_user_ns(self):
944 944 """Initialize all user-visible namespaces to their minimum defaults.
945 945
946 946 Certain history lists are also initialized here, as they effectively
947 947 act as user namespaces.
948 948
949 949 Notes
950 950 -----
951 951 All data structures here are only filled in, they are NOT reset by this
952 952 method. If they were not empty before, data will simply be added to
953 953 therm.
954 954 """
955 955 # Store myself as the public api!!!
956 956 self.user_ns['get_ipython'] = self.get_ipython
957 957
958 958 # make global variables for user access to the histories
959 959 self.user_ns['_ih'] = self.input_hist
960 960 self.user_ns['_oh'] = self.output_hist
961 961 self.user_ns['_dh'] = self.dir_hist
962 962
963 963 # user aliases to input and output histories
964 964 self.user_ns['In'] = self.input_hist
965 965 self.user_ns['Out'] = self.output_hist
966 966
967 967 self.user_ns['_sh'] = shadowns
968 968
969 969 # Put 'help' in the user namespace
970 970 try:
971 971 from site import _Helper
972 972 self.user_ns['help'] = _Helper()
973 973 except ImportError:
974 974 warn('help() not available - check site.py')
975 975
976 976 def reset(self):
977 977 """Clear all internal namespaces.
978 978
979 979 Note that this is much more aggressive than %reset, since it clears
980 980 fully all namespaces, as well as all input/output lists.
981 981 """
982 982 for ns in self.ns_refs_table:
983 983 ns.clear()
984 984
985 985 self.alias_manager.clear_aliases()
986 986
987 987 # Clear input and output histories
988 988 self.input_hist[:] = []
989 989 self.input_hist_raw[:] = []
990 990 self.output_hist.clear()
991 991
992 992 # Restore the user namespaces to minimal usability
993 993 self.init_user_ns()
994 994
995 995 # Restore the default and user aliases
996 996 self.alias_manager.init_aliases()
997 997
998 998 def push(self, variables, interactive=True):
999 999 """Inject a group of variables into the IPython user namespace.
1000 1000
1001 1001 Parameters
1002 1002 ----------
1003 1003 variables : dict, str or list/tuple of str
1004 1004 The variables to inject into the user's namespace. If a dict,
1005 1005 a simple update is done. If a str, the string is assumed to
1006 1006 have variable names separated by spaces. A list/tuple of str
1007 1007 can also be used to give the variable names. If just the variable
1008 1008 names are give (list/tuple/str) then the variable values looked
1009 1009 up in the callers frame.
1010 1010 interactive : bool
1011 1011 If True (default), the variables will be listed with the ``who``
1012 1012 magic.
1013 1013 """
1014 1014 vdict = None
1015 1015
1016 1016 # We need a dict of name/value pairs to do namespace updates.
1017 1017 if isinstance(variables, dict):
1018 1018 vdict = variables
1019 1019 elif isinstance(variables, (basestring, list, tuple)):
1020 1020 if isinstance(variables, basestring):
1021 1021 vlist = variables.split()
1022 1022 else:
1023 1023 vlist = variables
1024 1024 vdict = {}
1025 1025 cf = sys._getframe(1)
1026 1026 for name in vlist:
1027 1027 try:
1028 1028 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1029 1029 except:
1030 1030 print ('Could not get variable %s from %s' %
1031 1031 (name,cf.f_code.co_name))
1032 1032 else:
1033 1033 raise ValueError('variables must be a dict/str/list/tuple')
1034 1034
1035 1035 # Propagate variables to user namespace
1036 1036 self.user_ns.update(vdict)
1037 1037
1038 1038 # And configure interactive visibility
1039 1039 config_ns = self.user_config_ns
1040 1040 if interactive:
1041 1041 for name, val in vdict.iteritems():
1042 1042 config_ns.pop(name, None)
1043 1043 else:
1044 1044 for name,val in vdict.iteritems():
1045 1045 config_ns[name] = val
1046 1046
1047 1047 #-------------------------------------------------------------------------
1048 1048 # Things related to history management
1049 1049 #-------------------------------------------------------------------------
1050 1050
1051 1051 def init_history(self):
1052 1052 # List of input with multi-line handling.
1053 1053 self.input_hist = InputList()
1054 1054 # This one will hold the 'raw' input history, without any
1055 1055 # pre-processing. This will allow users to retrieve the input just as
1056 1056 # it was exactly typed in by the user, with %hist -r.
1057 1057 self.input_hist_raw = InputList()
1058 1058
1059 1059 # list of visited directories
1060 1060 try:
1061 1061 self.dir_hist = [os.getcwd()]
1062 1062 except OSError:
1063 1063 self.dir_hist = []
1064 1064
1065 1065 # dict of output history
1066 1066 self.output_hist = {}
1067 1067
1068 1068 # Now the history file
1069 1069 if self.profile:
1070 1070 histfname = 'history-%s' % self.profile
1071 1071 else:
1072 1072 histfname = 'history'
1073 1073 self.histfile = os.path.join(self.ipythondir, histfname)
1074 1074
1075 1075 # Fill the history zero entry, user counter starts at 1
1076 1076 self.input_hist.append('\n')
1077 1077 self.input_hist_raw.append('\n')
1078 1078
1079 1079 def init_shadow_hist(self):
1080 1080 try:
1081 1081 self.db = pickleshare.PickleShareDB(self.ipythondir + "/db")
1082 1082 except exceptions.UnicodeDecodeError:
1083 1083 print "Your ipythondir can't be decoded to unicode!"
1084 1084 print "Please set HOME environment variable to something that"
1085 1085 print r"only has ASCII characters, e.g. c:\home"
1086 1086 print "Now it is", self.ipythondir
1087 1087 sys.exit()
1088 1088 self.shadowhist = ipcorehist.ShadowHist(self.db)
1089 1089
1090 1090 def savehist(self):
1091 1091 """Save input history to a file (via readline library)."""
1092 1092
1093 1093 if not self.has_readline:
1094 1094 return
1095 1095
1096 1096 try:
1097 1097 self.readline.write_history_file(self.histfile)
1098 1098 except:
1099 1099 print 'Unable to save IPython command history to file: ' + \
1100 1100 `self.histfile`
1101 1101
1102 1102 def reloadhist(self):
1103 1103 """Reload the input history from disk file."""
1104 1104
1105 1105 if self.has_readline:
1106 1106 try:
1107 1107 self.readline.clear_history()
1108 1108 self.readline.read_history_file(self.shell.histfile)
1109 1109 except AttributeError:
1110 1110 pass
1111 1111
1112 1112 def history_saving_wrapper(self, func):
1113 1113 """ Wrap func for readline history saving
1114 1114
1115 1115 Convert func into callable that saves & restores
1116 1116 history around the call """
1117 1117
1118 1118 if not self.has_readline:
1119 1119 return func
1120 1120
1121 1121 def wrapper():
1122 1122 self.savehist()
1123 1123 try:
1124 1124 func()
1125 1125 finally:
1126 1126 readline.read_history_file(self.histfile)
1127 1127 return wrapper
1128 1128
1129 1129 #-------------------------------------------------------------------------
1130 1130 # Things related to exception handling and tracebacks (not debugging)
1131 1131 #-------------------------------------------------------------------------
1132 1132
1133 1133 def init_traceback_handlers(self, custom_exceptions):
1134 1134 # Syntax error handler.
1135 1135 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1136 1136
1137 1137 # The interactive one is initialized with an offset, meaning we always
1138 1138 # want to remove the topmost item in the traceback, which is our own
1139 1139 # internal code. Valid modes: ['Plain','Context','Verbose']
1140 1140 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1141 1141 color_scheme='NoColor',
1142 1142 tb_offset = 1)
1143 1143
1144 1144 # IPython itself shouldn't crash. This will produce a detailed
1145 1145 # post-mortem if it does. But we only install the crash handler for
1146 1146 # non-threaded shells, the threaded ones use a normal verbose reporter
1147 1147 # and lose the crash handler. This is because exceptions in the main
1148 1148 # thread (such as in GUI code) propagate directly to sys.excepthook,
1149 1149 # and there's no point in printing crash dumps for every user exception.
1150 1150 if self.isthreaded:
1151 1151 ipCrashHandler = ultratb.FormattedTB()
1152 1152 else:
1153 1153 from IPython.core import crashhandler
1154 1154 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1155 1155 self.set_crash_handler(ipCrashHandler)
1156 1156
1157 1157 # and add any custom exception handlers the user may have specified
1158 1158 self.set_custom_exc(*custom_exceptions)
1159 1159
1160 1160 def set_crash_handler(self, crashHandler):
1161 1161 """Set the IPython crash handler.
1162 1162
1163 1163 This must be a callable with a signature suitable for use as
1164 1164 sys.excepthook."""
1165 1165
1166 1166 # Install the given crash handler as the Python exception hook
1167 1167 sys.excepthook = crashHandler
1168 1168
1169 1169 # The instance will store a pointer to this, so that runtime code
1170 1170 # (such as magics) can access it. This is because during the
1171 1171 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1172 1172 # frameworks).
1173 1173 self.sys_excepthook = sys.excepthook
1174 1174
1175 1175 def set_custom_exc(self,exc_tuple,handler):
1176 1176 """set_custom_exc(exc_tuple,handler)
1177 1177
1178 1178 Set a custom exception handler, which will be called if any of the
1179 1179 exceptions in exc_tuple occur in the mainloop (specifically, in the
1180 1180 runcode() method.
1181 1181
1182 1182 Inputs:
1183 1183
1184 1184 - exc_tuple: a *tuple* of valid exceptions to call the defined
1185 1185 handler for. It is very important that you use a tuple, and NOT A
1186 1186 LIST here, because of the way Python's except statement works. If
1187 1187 you only want to trap a single exception, use a singleton tuple:
1188 1188
1189 1189 exc_tuple == (MyCustomException,)
1190 1190
1191 1191 - handler: this must be defined as a function with the following
1192 1192 basic interface: def my_handler(self,etype,value,tb).
1193 1193
1194 1194 This will be made into an instance method (via new.instancemethod)
1195 1195 of IPython itself, and it will be called if any of the exceptions
1196 1196 listed in the exc_tuple are caught. If the handler is None, an
1197 1197 internal basic one is used, which just prints basic info.
1198 1198
1199 1199 WARNING: by putting in your own exception handler into IPython's main
1200 1200 execution loop, you run a very good chance of nasty crashes. This
1201 1201 facility should only be used if you really know what you are doing."""
1202 1202
1203 1203 assert type(exc_tuple)==type(()) , \
1204 1204 "The custom exceptions must be given AS A TUPLE."
1205 1205
1206 1206 def dummy_handler(self,etype,value,tb):
1207 1207 print '*** Simple custom exception handler ***'
1208 1208 print 'Exception type :',etype
1209 1209 print 'Exception value:',value
1210 1210 print 'Traceback :',tb
1211 1211 print 'Source code :','\n'.join(self.buffer)
1212 1212
1213 1213 if handler is None: handler = dummy_handler
1214 1214
1215 1215 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1216 1216 self.custom_exceptions = exc_tuple
1217 1217
1218 1218 def excepthook(self, etype, value, tb):
1219 1219 """One more defense for GUI apps that call sys.excepthook.
1220 1220
1221 1221 GUI frameworks like wxPython trap exceptions and call
1222 1222 sys.excepthook themselves. I guess this is a feature that
1223 1223 enables them to keep running after exceptions that would
1224 1224 otherwise kill their mainloop. This is a bother for IPython
1225 1225 which excepts to catch all of the program exceptions with a try:
1226 1226 except: statement.
1227 1227
1228 1228 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1229 1229 any app directly invokes sys.excepthook, it will look to the user like
1230 1230 IPython crashed. In order to work around this, we can disable the
1231 1231 CrashHandler and replace it with this excepthook instead, which prints a
1232 1232 regular traceback using our InteractiveTB. In this fashion, apps which
1233 1233 call sys.excepthook will generate a regular-looking exception from
1234 1234 IPython, and the CrashHandler will only be triggered by real IPython
1235 1235 crashes.
1236 1236
1237 1237 This hook should be used sparingly, only in places which are not likely
1238 1238 to be true IPython errors.
1239 1239 """
1240 1240 self.showtraceback((etype,value,tb),tb_offset=0)
1241 1241
1242 1242 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1243 1243 """Display the exception that just occurred.
1244 1244
1245 1245 If nothing is known about the exception, this is the method which
1246 1246 should be used throughout the code for presenting user tracebacks,
1247 1247 rather than directly invoking the InteractiveTB object.
1248 1248
1249 1249 A specific showsyntaxerror() also exists, but this method can take
1250 1250 care of calling it if needed, so unless you are explicitly catching a
1251 1251 SyntaxError exception, don't try to analyze the stack manually and
1252 1252 simply call this method."""
1253 1253
1254 1254
1255 1255 # Though this won't be called by syntax errors in the input line,
1256 1256 # there may be SyntaxError cases whith imported code.
1257 1257
1258 1258 try:
1259 1259 if exc_tuple is None:
1260 1260 etype, value, tb = sys.exc_info()
1261 1261 else:
1262 1262 etype, value, tb = exc_tuple
1263 1263
1264 1264 if etype is SyntaxError:
1265 1265 self.showsyntaxerror(filename)
1266 1266 elif etype is UsageError:
1267 1267 print "UsageError:", value
1268 1268 else:
1269 1269 # WARNING: these variables are somewhat deprecated and not
1270 1270 # necessarily safe to use in a threaded environment, but tools
1271 1271 # like pdb depend on their existence, so let's set them. If we
1272 1272 # find problems in the field, we'll need to revisit their use.
1273 1273 sys.last_type = etype
1274 1274 sys.last_value = value
1275 1275 sys.last_traceback = tb
1276 1276
1277 1277 if etype in self.custom_exceptions:
1278 1278 self.CustomTB(etype,value,tb)
1279 1279 else:
1280 1280 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1281 1281 if self.InteractiveTB.call_pdb and self.has_readline:
1282 1282 # pdb mucks up readline, fix it back
1283 1283 self.set_completer()
1284 1284 except KeyboardInterrupt:
1285 1285 self.write("\nKeyboardInterrupt\n")
1286 1286
1287 1287 def showsyntaxerror(self, filename=None):
1288 1288 """Display the syntax error that just occurred.
1289 1289
1290 1290 This doesn't display a stack trace because there isn't one.
1291 1291
1292 1292 If a filename is given, it is stuffed in the exception instead
1293 1293 of what was there before (because Python's parser always uses
1294 1294 "<string>" when reading from a string).
1295 1295 """
1296 1296 etype, value, last_traceback = sys.exc_info()
1297 1297
1298 1298 # See note about these variables in showtraceback() below
1299 1299 sys.last_type = etype
1300 1300 sys.last_value = value
1301 1301 sys.last_traceback = last_traceback
1302 1302
1303 1303 if filename and etype is SyntaxError:
1304 1304 # Work hard to stuff the correct filename in the exception
1305 1305 try:
1306 1306 msg, (dummy_filename, lineno, offset, line) = value
1307 1307 except:
1308 1308 # Not the format we expect; leave it alone
1309 1309 pass
1310 1310 else:
1311 1311 # Stuff in the right filename
1312 1312 try:
1313 1313 # Assume SyntaxError is a class exception
1314 1314 value = SyntaxError(msg, (filename, lineno, offset, line))
1315 1315 except:
1316 1316 # If that failed, assume SyntaxError is a string
1317 1317 value = msg, (filename, lineno, offset, line)
1318 1318 self.SyntaxTB(etype,value,[])
1319 1319
1320 1320 def edit_syntax_error(self):
1321 1321 """The bottom half of the syntax error handler called in the main loop.
1322 1322
1323 1323 Loop until syntax error is fixed or user cancels.
1324 1324 """
1325 1325
1326 1326 while self.SyntaxTB.last_syntax_error:
1327 1327 # copy and clear last_syntax_error
1328 1328 err = self.SyntaxTB.clear_err_state()
1329 1329 if not self._should_recompile(err):
1330 1330 return
1331 1331 try:
1332 1332 # may set last_syntax_error again if a SyntaxError is raised
1333 1333 self.safe_execfile(err.filename,self.user_ns)
1334 1334 except:
1335 1335 self.showtraceback()
1336 1336 else:
1337 1337 try:
1338 1338 f = file(err.filename)
1339 1339 try:
1340 1340 # This should be inside a display_trap block and I
1341 1341 # think it is.
1342 1342 sys.displayhook(f.read())
1343 1343 finally:
1344 1344 f.close()
1345 1345 except:
1346 1346 self.showtraceback()
1347 1347
1348 1348 def _should_recompile(self,e):
1349 1349 """Utility routine for edit_syntax_error"""
1350 1350
1351 1351 if e.filename in ('<ipython console>','<input>','<string>',
1352 1352 '<console>','<BackgroundJob compilation>',
1353 1353 None):
1354 1354
1355 1355 return False
1356 1356 try:
1357 1357 if (self.autoedit_syntax and
1358 1358 not self.ask_yes_no('Return to editor to correct syntax error? '
1359 1359 '[Y/n] ','y')):
1360 1360 return False
1361 1361 except EOFError:
1362 1362 return False
1363 1363
1364 1364 def int0(x):
1365 1365 try:
1366 1366 return int(x)
1367 1367 except TypeError:
1368 1368 return 0
1369 1369 # always pass integer line and offset values to editor hook
1370 1370 try:
1371 1371 self.hooks.fix_error_editor(e.filename,
1372 1372 int0(e.lineno),int0(e.offset),e.msg)
1373 1373 except TryNext:
1374 1374 warn('Could not open editor')
1375 1375 return False
1376 1376 return True
1377 1377
1378 1378 #-------------------------------------------------------------------------
1379 1379 # Things related to tab completion
1380 1380 #-------------------------------------------------------------------------
1381 1381
1382 1382 def complete(self, text):
1383 1383 """Return a sorted list of all possible completions on text.
1384 1384
1385 1385 Inputs:
1386 1386
1387 1387 - text: a string of text to be completed on.
1388 1388
1389 1389 This is a wrapper around the completion mechanism, similar to what
1390 1390 readline does at the command line when the TAB key is hit. By
1391 1391 exposing it as a method, it can be used by other non-readline
1392 1392 environments (such as GUIs) for text completion.
1393 1393
1394 1394 Simple usage example:
1395 1395
1396 1396 In [7]: x = 'hello'
1397 1397
1398 1398 In [8]: x
1399 1399 Out[8]: 'hello'
1400 1400
1401 1401 In [9]: print x
1402 1402 hello
1403 1403
1404 1404 In [10]: _ip.complete('x.l')
1405 1405 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1406 1406 """
1407 1407
1408 1408 # Inject names into __builtin__ so we can complete on the added names.
1409 1409 with self.builtin_trap:
1410 1410 complete = self.Completer.complete
1411 1411 state = 0
1412 1412 # use a dict so we get unique keys, since ipyhton's multiple
1413 1413 # completers can return duplicates. When we make 2.4 a requirement,
1414 1414 # start using sets instead, which are faster.
1415 1415 comps = {}
1416 1416 while True:
1417 1417 newcomp = complete(text,state,line_buffer=text)
1418 1418 if newcomp is None:
1419 1419 break
1420 1420 comps[newcomp] = 1
1421 1421 state += 1
1422 1422 outcomps = comps.keys()
1423 1423 outcomps.sort()
1424 1424 #print "T:",text,"OC:",outcomps # dbg
1425 1425 #print "vars:",self.user_ns.keys()
1426 1426 return outcomps
1427 1427
1428 1428 def set_custom_completer(self,completer,pos=0):
1429 1429 """set_custom_completer(completer,pos=0)
1430 1430
1431 1431 Adds a new custom completer function.
1432 1432
1433 1433 The position argument (defaults to 0) is the index in the completers
1434 1434 list where you want the completer to be inserted."""
1435 1435
1436 1436 newcomp = new.instancemethod(completer,self.Completer,
1437 1437 self.Completer.__class__)
1438 1438 self.Completer.matchers.insert(pos,newcomp)
1439 1439
1440 1440 def set_completer(self):
1441 1441 """reset readline's completer to be our own."""
1442 1442 self.readline.set_completer(self.Completer.complete)
1443 1443
1444 1444 #-------------------------------------------------------------------------
1445 1445 # Things related to readline
1446 1446 #-------------------------------------------------------------------------
1447 1447
1448 1448 def init_readline(self):
1449 1449 """Command history completion/saving/reloading."""
1450 1450
1451 1451 self.rl_next_input = None
1452 1452 self.rl_do_indent = False
1453 1453
1454 1454 if not self.readline_use:
1455 1455 return
1456 1456
1457 1457 import IPython.utils.rlineimpl as readline
1458 1458
1459 1459 if not readline.have_readline:
1460 1460 self.has_readline = 0
1461 1461 self.readline = None
1462 1462 # no point in bugging windows users with this every time:
1463 1463 warn('Readline services not available on this platform.')
1464 1464 else:
1465 1465 sys.modules['readline'] = readline
1466 1466 import atexit
1467 1467 from IPython.core.completer import IPCompleter
1468 1468 self.Completer = IPCompleter(self,
1469 1469 self.user_ns,
1470 1470 self.user_global_ns,
1471 1471 self.readline_omit__names,
1472 1472 self.alias_manager.alias_table)
1473 1473 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1474 1474 self.strdispatchers['complete_command'] = sdisp
1475 1475 self.Completer.custom_completers = sdisp
1476 1476 # Platform-specific configuration
1477 1477 if os.name == 'nt':
1478 1478 self.readline_startup_hook = readline.set_pre_input_hook
1479 1479 else:
1480 1480 self.readline_startup_hook = readline.set_startup_hook
1481 1481
1482 1482 # Load user's initrc file (readline config)
1483 1483 # Or if libedit is used, load editrc.
1484 1484 inputrc_name = os.environ.get('INPUTRC')
1485 1485 if inputrc_name is None:
1486 1486 home_dir = get_home_dir()
1487 1487 if home_dir is not None:
1488 1488 inputrc_name = '.inputrc'
1489 1489 if readline.uses_libedit:
1490 1490 inputrc_name = '.editrc'
1491 1491 inputrc_name = os.path.join(home_dir, inputrc_name)
1492 1492 if os.path.isfile(inputrc_name):
1493 1493 try:
1494 1494 readline.read_init_file(inputrc_name)
1495 1495 except:
1496 1496 warn('Problems reading readline initialization file <%s>'
1497 1497 % inputrc_name)
1498 1498
1499 1499 self.has_readline = 1
1500 1500 self.readline = readline
1501 1501 # save this in sys so embedded copies can restore it properly
1502 1502 sys.ipcompleter = self.Completer.complete
1503 1503 self.set_completer()
1504 1504
1505 1505 # Configure readline according to user's prefs
1506 1506 # This is only done if GNU readline is being used. If libedit
1507 1507 # is being used (as on Leopard) the readline config is
1508 1508 # not run as the syntax for libedit is different.
1509 1509 if not readline.uses_libedit:
1510 1510 for rlcommand in self.readline_parse_and_bind:
1511 1511 #print "loading rl:",rlcommand # dbg
1512 1512 readline.parse_and_bind(rlcommand)
1513 1513
1514 1514 # Remove some chars from the delimiters list. If we encounter
1515 1515 # unicode chars, discard them.
1516 1516 delims = readline.get_completer_delims().encode("ascii", "ignore")
1517 1517 delims = delims.translate(string._idmap,
1518 1518 self.readline_remove_delims)
1519 1519 readline.set_completer_delims(delims)
1520 1520 # otherwise we end up with a monster history after a while:
1521 1521 readline.set_history_length(1000)
1522 1522 try:
1523 1523 #print '*** Reading readline history' # dbg
1524 1524 readline.read_history_file(self.histfile)
1525 1525 except IOError:
1526 1526 pass # It doesn't exist yet.
1527 1527
1528 1528 atexit.register(self.atexit_operations)
1529 1529 del atexit
1530 1530
1531 1531 # Configure auto-indent for all platforms
1532 1532 self.set_autoindent(self.autoindent)
1533 1533
1534 1534 def set_next_input(self, s):
1535 1535 """ Sets the 'default' input string for the next command line.
1536 1536
1537 1537 Requires readline.
1538 1538
1539 1539 Example:
1540 1540
1541 1541 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1542 1542 [D:\ipython]|2> Hello Word_ # cursor is here
1543 1543 """
1544 1544
1545 1545 self.rl_next_input = s
1546 1546
1547 1547 def pre_readline(self):
1548 1548 """readline hook to be used at the start of each line.
1549 1549
1550 1550 Currently it handles auto-indent only."""
1551 1551
1552 1552 #debugx('self.indent_current_nsp','pre_readline:')
1553 1553
1554 1554 if self.rl_do_indent:
1555 1555 self.readline.insert_text(self._indent_current_str())
1556 1556 if self.rl_next_input is not None:
1557 1557 self.readline.insert_text(self.rl_next_input)
1558 1558 self.rl_next_input = None
1559 1559
1560 1560 def _indent_current_str(self):
1561 1561 """return the current level of indentation as a string"""
1562 1562 return self.indent_current_nsp * ' '
1563 1563
1564 1564 #-------------------------------------------------------------------------
1565 1565 # Things related to magics
1566 1566 #-------------------------------------------------------------------------
1567 1567
1568 1568 def init_magics(self):
1569 1569 # Set user colors (don't do it in the constructor above so that it
1570 1570 # doesn't crash if colors option is invalid)
1571 1571 self.magic_colors(self.colors)
1572 1572
1573 1573 def magic(self,arg_s):
1574 1574 """Call a magic function by name.
1575 1575
1576 1576 Input: a string containing the name of the magic function to call and any
1577 1577 additional arguments to be passed to the magic.
1578 1578
1579 1579 magic('name -opt foo bar') is equivalent to typing at the ipython
1580 1580 prompt:
1581 1581
1582 1582 In[1]: %name -opt foo bar
1583 1583
1584 1584 To call a magic without arguments, simply use magic('name').
1585 1585
1586 1586 This provides a proper Python function to call IPython's magics in any
1587 1587 valid Python code you can type at the interpreter, including loops and
1588 1588 compound statements.
1589 1589 """
1590 1590
1591 1591 args = arg_s.split(' ',1)
1592 1592 magic_name = args[0]
1593 1593 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1594 1594
1595 1595 try:
1596 1596 magic_args = args[1]
1597 1597 except IndexError:
1598 1598 magic_args = ''
1599 1599 fn = getattr(self,'magic_'+magic_name,None)
1600 1600 if fn is None:
1601 1601 error("Magic function `%s` not found." % magic_name)
1602 1602 else:
1603 1603 magic_args = self.var_expand(magic_args,1)
1604 1604 with nested(self.builtin_trap,):
1605 1605 result = fn(magic_args)
1606 1606 return result
1607 1607
1608 1608 def define_magic(self, magicname, func):
1609 1609 """Expose own function as magic function for ipython
1610 1610
1611 1611 def foo_impl(self,parameter_s=''):
1612 1612 'My very own magic!. (Use docstrings, IPython reads them).'
1613 1613 print 'Magic function. Passed parameter is between < >:'
1614 1614 print '<%s>' % parameter_s
1615 1615 print 'The self object is:',self
1616 1616
1617 1617 self.define_magic('foo',foo_impl)
1618 1618 """
1619 1619
1620 1620 import new
1621 1621 im = new.instancemethod(func,self, self.__class__)
1622 1622 old = getattr(self, "magic_" + magicname, None)
1623 1623 setattr(self, "magic_" + magicname, im)
1624 1624 return old
1625 1625
1626 1626 #-------------------------------------------------------------------------
1627 1627 # Things related to macros
1628 1628 #-------------------------------------------------------------------------
1629 1629
1630 1630 def define_macro(self, name, themacro):
1631 1631 """Define a new macro
1632 1632
1633 1633 Parameters
1634 1634 ----------
1635 1635 name : str
1636 1636 The name of the macro.
1637 1637 themacro : str or Macro
1638 1638 The action to do upon invoking the macro. If a string, a new
1639 1639 Macro object is created by passing the string to it.
1640 1640 """
1641 1641
1642 1642 from IPython.core import macro
1643 1643
1644 1644 if isinstance(themacro, basestring):
1645 1645 themacro = macro.Macro(themacro)
1646 1646 if not isinstance(themacro, macro.Macro):
1647 1647 raise ValueError('A macro must be a string or a Macro instance.')
1648 1648 self.user_ns[name] = themacro
1649 1649
1650 1650 #-------------------------------------------------------------------------
1651 1651 # Things related to the running of system commands
1652 1652 #-------------------------------------------------------------------------
1653 1653
1654 1654 def system(self, cmd):
1655 1655 """Make a system call, using IPython."""
1656 1656 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1657 1657
1658 1658 #-------------------------------------------------------------------------
1659 1659 # Things related to aliases
1660 1660 #-------------------------------------------------------------------------
1661 1661
1662 1662 def init_alias(self):
1663 1663 self.alias_manager = AliasManager(self, config=self.config)
1664 1664 self.ns_table['alias'] = self.alias_manager.alias_table,
1665 1665
1666 1666 #-------------------------------------------------------------------------
1667 1667 # Things related to the running of code
1668 1668 #-------------------------------------------------------------------------
1669 1669
1670 1670 def ex(self, cmd):
1671 1671 """Execute a normal python statement in user namespace."""
1672 1672 with nested(self.builtin_trap,):
1673 1673 exec cmd in self.user_global_ns, self.user_ns
1674 1674
1675 1675 def ev(self, expr):
1676 1676 """Evaluate python expression expr in user namespace.
1677 1677
1678 1678 Returns the result of evaluation
1679 1679 """
1680 1680 with nested(self.builtin_trap,):
1681 1681 return eval(expr, self.user_global_ns, self.user_ns)
1682 1682
1683 1683 def mainloop(self, display_banner=None):
1684 1684 """Start the mainloop.
1685 1685
1686 1686 If an optional banner argument is given, it will override the
1687 1687 internally created default banner.
1688 1688 """
1689 1689
1690 1690 with nested(self.builtin_trap, self.display_trap):
1691 1691
1692 1692 # if you run stuff with -c <cmd>, raw hist is not updated
1693 1693 # ensure that it's in sync
1694 1694 if len(self.input_hist) != len (self.input_hist_raw):
1695 1695 self.input_hist_raw = InputList(self.input_hist)
1696 1696
1697 1697 while 1:
1698 1698 try:
1699 1699 self.interact(display_banner=display_banner)
1700 1700 #self.interact_with_readline()
1701 1701 # XXX for testing of a readline-decoupled repl loop, call
1702 1702 # interact_with_readline above
1703 1703 break
1704 1704 except KeyboardInterrupt:
1705 1705 # this should not be necessary, but KeyboardInterrupt
1706 1706 # handling seems rather unpredictable...
1707 1707 self.write("\nKeyboardInterrupt in interact()\n")
1708 1708
1709 1709 def interact_prompt(self):
1710 1710 """ Print the prompt (in read-eval-print loop)
1711 1711
1712 1712 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1713 1713 used in standard IPython flow.
1714 1714 """
1715 1715 if self.more:
1716 1716 try:
1717 1717 prompt = self.hooks.generate_prompt(True)
1718 1718 except:
1719 1719 self.showtraceback()
1720 1720 if self.autoindent:
1721 1721 self.rl_do_indent = True
1722 1722
1723 1723 else:
1724 1724 try:
1725 1725 prompt = self.hooks.generate_prompt(False)
1726 1726 except:
1727 1727 self.showtraceback()
1728 1728 self.write(prompt)
1729 1729
1730 1730 def interact_handle_input(self,line):
1731 1731 """ Handle the input line (in read-eval-print loop)
1732 1732
1733 1733 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1734 1734 used in standard IPython flow.
1735 1735 """
1736 1736 if line.lstrip() == line:
1737 1737 self.shadowhist.add(line.strip())
1738 1738 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1739 1739
1740 1740 if line.strip():
1741 1741 if self.more:
1742 1742 self.input_hist_raw[-1] += '%s\n' % line
1743 1743 else:
1744 1744 self.input_hist_raw.append('%s\n' % line)
1745 1745
1746 1746
1747 1747 self.more = self.push_line(lineout)
1748 1748 if (self.SyntaxTB.last_syntax_error and
1749 1749 self.autoedit_syntax):
1750 1750 self.edit_syntax_error()
1751 1751
1752 1752 def interact_with_readline(self):
1753 1753 """ Demo of using interact_handle_input, interact_prompt
1754 1754
1755 1755 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1756 1756 it should work like this.
1757 1757 """
1758 1758 self.readline_startup_hook(self.pre_readline)
1759 1759 while not self.exit_now:
1760 1760 self.interact_prompt()
1761 1761 if self.more:
1762 1762 self.rl_do_indent = True
1763 1763 else:
1764 1764 self.rl_do_indent = False
1765 1765 line = raw_input_original().decode(self.stdin_encoding)
1766 1766 self.interact_handle_input(line)
1767 1767
1768 1768 def interact(self, display_banner=None):
1769 1769 """Closely emulate the interactive Python console."""
1770 1770
1771 1771 # batch run -> do not interact
1772 1772 if self.exit_now:
1773 1773 return
1774 1774
1775 1775 if display_banner is None:
1776 1776 display_banner = self.display_banner
1777 1777 if display_banner:
1778 1778 self.show_banner()
1779 1779
1780 1780 more = 0
1781 1781
1782 1782 # Mark activity in the builtins
1783 1783 __builtin__.__dict__['__IPYTHON__active'] += 1
1784 1784
1785 1785 if self.has_readline:
1786 1786 self.readline_startup_hook(self.pre_readline)
1787 1787 # exit_now is set by a call to %Exit or %Quit, through the
1788 1788 # ask_exit callback.
1789 1789
1790 1790 while not self.exit_now:
1791 1791 self.hooks.pre_prompt_hook()
1792 1792 if more:
1793 1793 try:
1794 1794 prompt = self.hooks.generate_prompt(True)
1795 1795 except:
1796 1796 self.showtraceback()
1797 1797 if self.autoindent:
1798 1798 self.rl_do_indent = True
1799 1799
1800 1800 else:
1801 1801 try:
1802 1802 prompt = self.hooks.generate_prompt(False)
1803 1803 except:
1804 1804 self.showtraceback()
1805 1805 try:
1806 1806 line = self.raw_input(prompt, more)
1807 1807 if self.exit_now:
1808 1808 # quick exit on sys.std[in|out] close
1809 1809 break
1810 1810 if self.autoindent:
1811 1811 self.rl_do_indent = False
1812 1812
1813 1813 except KeyboardInterrupt:
1814 1814 #double-guard against keyboardinterrupts during kbdint handling
1815 1815 try:
1816 1816 self.write('\nKeyboardInterrupt\n')
1817 1817 self.resetbuffer()
1818 1818 # keep cache in sync with the prompt counter:
1819 1819 self.outputcache.prompt_count -= 1
1820 1820
1821 1821 if self.autoindent:
1822 1822 self.indent_current_nsp = 0
1823 1823 more = 0
1824 1824 except KeyboardInterrupt:
1825 1825 pass
1826 1826 except EOFError:
1827 1827 if self.autoindent:
1828 1828 self.rl_do_indent = False
1829 1829 self.readline_startup_hook(None)
1830 1830 self.write('\n')
1831 1831 self.exit()
1832 1832 except bdb.BdbQuit:
1833 1833 warn('The Python debugger has exited with a BdbQuit exception.\n'
1834 1834 'Because of how pdb handles the stack, it is impossible\n'
1835 1835 'for IPython to properly format this particular exception.\n'
1836 1836 'IPython will resume normal operation.')
1837 1837 except:
1838 1838 # exceptions here are VERY RARE, but they can be triggered
1839 1839 # asynchronously by signal handlers, for example.
1840 1840 self.showtraceback()
1841 1841 else:
1842 1842 more = self.push_line(line)
1843 1843 if (self.SyntaxTB.last_syntax_error and
1844 1844 self.autoedit_syntax):
1845 1845 self.edit_syntax_error()
1846 1846
1847 1847 # We are off again...
1848 1848 __builtin__.__dict__['__IPYTHON__active'] -= 1
1849 1849
1850 1850 def safe_execfile(self, fname, *where, **kw):
1851 1851 """A safe version of the builtin execfile().
1852 1852
1853 1853 This version will never throw an exception, but instead print
1854 1854 helpful error messages to the screen. This only works on pure
1855 1855 Python files with the .py extension.
1856 1856
1857 1857 Parameters
1858 1858 ----------
1859 1859 fname : string
1860 1860 The name of the file to be executed.
1861 1861 where : tuple
1862 1862 One or two namespaces, passed to execfile() as (globals,locals).
1863 1863 If only one is given, it is passed as both.
1864 1864 exit_ignore : bool (False)
1865 1865 If True, then don't print errors for non-zero exit statuses.
1866 1866 """
1867 1867 kw.setdefault('exit_ignore', False)
1868 1868
1869 1869 fname = os.path.abspath(os.path.expanduser(fname))
1870 1870
1871 1871 # Make sure we have a .py file
1872 1872 if not fname.endswith('.py'):
1873 1873 warn('File must end with .py to be run using execfile: <%s>' % fname)
1874 1874
1875 1875 # Make sure we can open the file
1876 1876 try:
1877 1877 with open(fname) as thefile:
1878 1878 pass
1879 1879 except:
1880 1880 warn('Could not open file <%s> for safe execution.' % fname)
1881 1881 return
1882 1882
1883 1883 # Find things also in current directory. This is needed to mimic the
1884 1884 # behavior of running a script from the system command line, where
1885 1885 # Python inserts the script's directory into sys.path
1886 1886 dname = os.path.dirname(fname)
1887 1887
1888 1888 with prepended_to_syspath(dname):
1889 1889 try:
1890 1890 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1891 1891 # Work around a bug in Python for Windows. The bug was
1892 1892 # fixed in in Python 2.5 r54159 and 54158, but that's still
1893 1893 # SVN Python as of March/07. For details, see:
1894 1894 # http://projects.scipy.org/ipython/ipython/ticket/123
1895 1895 try:
1896 1896 globs,locs = where[0:2]
1897 1897 except:
1898 1898 try:
1899 1899 globs = locs = where[0]
1900 1900 except:
1901 1901 globs = locs = globals()
1902 1902 exec file(fname) in globs,locs
1903 1903 else:
1904 1904 execfile(fname,*where)
1905 1905 except SyntaxError:
1906 1906 self.showsyntaxerror()
1907 1907 warn('Failure executing file: <%s>' % fname)
1908 1908 except SystemExit, status:
1909 1909 # Code that correctly sets the exit status flag to success (0)
1910 1910 # shouldn't be bothered with a traceback. Note that a plain
1911 1911 # sys.exit() does NOT set the message to 0 (it's empty) so that
1912 1912 # will still get a traceback. Note that the structure of the
1913 1913 # SystemExit exception changed between Python 2.4 and 2.5, so
1914 1914 # the checks must be done in a version-dependent way.
1915 1915 show = False
1916 1916 if status.message!=0 and not kw['exit_ignore']:
1917 1917 show = True
1918 1918 if show:
1919 1919 self.showtraceback()
1920 1920 warn('Failure executing file: <%s>' % fname)
1921 1921 except:
1922 1922 self.showtraceback()
1923 1923 warn('Failure executing file: <%s>' % fname)
1924 1924
1925 1925 def safe_execfile_ipy(self, fname):
1926 1926 """Like safe_execfile, but for .ipy files with IPython syntax.
1927 1927
1928 1928 Parameters
1929 1929 ----------
1930 1930 fname : str
1931 1931 The name of the file to execute. The filename must have a
1932 1932 .ipy extension.
1933 1933 """
1934 1934 fname = os.path.abspath(os.path.expanduser(fname))
1935 1935
1936 1936 # Make sure we have a .py file
1937 1937 if not fname.endswith('.ipy'):
1938 1938 warn('File must end with .py to be run using execfile: <%s>' % fname)
1939 1939
1940 1940 # Make sure we can open the file
1941 1941 try:
1942 1942 with open(fname) as thefile:
1943 1943 pass
1944 1944 except:
1945 1945 warn('Could not open file <%s> for safe execution.' % fname)
1946 1946 return
1947 1947
1948 1948 # Find things also in current directory. This is needed to mimic the
1949 1949 # behavior of running a script from the system command line, where
1950 1950 # Python inserts the script's directory into sys.path
1951 1951 dname = os.path.dirname(fname)
1952 1952
1953 1953 with prepended_to_syspath(dname):
1954 1954 try:
1955 1955 with open(fname) as thefile:
1956 1956 script = thefile.read()
1957 1957 # self.runlines currently captures all exceptions
1958 1958 # raise in user code. It would be nice if there were
1959 1959 # versions of runlines, execfile that did raise, so
1960 1960 # we could catch the errors.
1961 1961 self.runlines(script, clean=True)
1962 1962 except:
1963 1963 self.showtraceback()
1964 1964 warn('Unknown failure executing file: <%s>' % fname)
1965 1965
1966 1966 def _is_secondary_block_start(self, s):
1967 1967 if not s.endswith(':'):
1968 1968 return False
1969 1969 if (s.startswith('elif') or
1970 1970 s.startswith('else') or
1971 1971 s.startswith('except') or
1972 1972 s.startswith('finally')):
1973 1973 return True
1974 1974
1975 1975 def cleanup_ipy_script(self, script):
1976 1976 """Make a script safe for self.runlines()
1977 1977
1978 1978 Currently, IPython is lines based, with blocks being detected by
1979 1979 empty lines. This is a problem for block based scripts that may
1980 1980 not have empty lines after blocks. This script adds those empty
1981 1981 lines to make scripts safe for running in the current line based
1982 1982 IPython.
1983 1983 """
1984 1984 res = []
1985 1985 lines = script.splitlines()
1986 1986 level = 0
1987 1987
1988 1988 for l in lines:
1989 1989 lstripped = l.lstrip()
1990 1990 stripped = l.strip()
1991 1991 if not stripped:
1992 1992 continue
1993 1993 newlevel = len(l) - len(lstripped)
1994 1994 if level > 0 and newlevel == 0 and \
1995 1995 not self._is_secondary_block_start(stripped):
1996 1996 # add empty line
1997 1997 res.append('')
1998 1998 res.append(l)
1999 1999 level = newlevel
2000 2000
2001 2001 return '\n'.join(res) + '\n'
2002 2002
2003 2003 def runlines(self, lines, clean=False):
2004 2004 """Run a string of one or more lines of source.
2005 2005
2006 2006 This method is capable of running a string containing multiple source
2007 2007 lines, as if they had been entered at the IPython prompt. Since it
2008 2008 exposes IPython's processing machinery, the given strings can contain
2009 2009 magic calls (%magic), special shell access (!cmd), etc.
2010 2010 """
2011 2011
2012 2012 if isinstance(lines, (list, tuple)):
2013 2013 lines = '\n'.join(lines)
2014 2014
2015 2015 if clean:
2016 2016 lines = self.cleanup_ipy_script(lines)
2017 2017
2018 2018 # We must start with a clean buffer, in case this is run from an
2019 2019 # interactive IPython session (via a magic, for example).
2020 2020 self.resetbuffer()
2021 2021 lines = lines.splitlines()
2022 2022 more = 0
2023 2023
2024 2024 with nested(self.builtin_trap, self.display_trap):
2025 2025 for line in lines:
2026 2026 # skip blank lines so we don't mess up the prompt counter, but do
2027 2027 # NOT skip even a blank line if we are in a code block (more is
2028 2028 # true)
2029 2029
2030 2030 if line or more:
2031 2031 # push to raw history, so hist line numbers stay in sync
2032 2032 self.input_hist_raw.append("# " + line + "\n")
2033 2033 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2034 2034 more = self.push_line(prefiltered)
2035 2035 # IPython's runsource returns None if there was an error
2036 2036 # compiling the code. This allows us to stop processing right
2037 2037 # away, so the user gets the error message at the right place.
2038 2038 if more is None:
2039 2039 break
2040 2040 else:
2041 2041 self.input_hist_raw.append("\n")
2042 2042 # final newline in case the input didn't have it, so that the code
2043 2043 # actually does get executed
2044 2044 if more:
2045 2045 self.push_line('\n')
2046 2046
2047 2047 def runsource(self, source, filename='<input>', symbol='single'):
2048 2048 """Compile and run some source in the interpreter.
2049 2049
2050 2050 Arguments are as for compile_command().
2051 2051
2052 2052 One several things can happen:
2053 2053
2054 2054 1) The input is incorrect; compile_command() raised an
2055 2055 exception (SyntaxError or OverflowError). A syntax traceback
2056 2056 will be printed by calling the showsyntaxerror() method.
2057 2057
2058 2058 2) The input is incomplete, and more input is required;
2059 2059 compile_command() returned None. Nothing happens.
2060 2060
2061 2061 3) The input is complete; compile_command() returned a code
2062 2062 object. The code is executed by calling self.runcode() (which
2063 2063 also handles run-time exceptions, except for SystemExit).
2064 2064
2065 2065 The return value is:
2066 2066
2067 2067 - True in case 2
2068 2068
2069 2069 - False in the other cases, unless an exception is raised, where
2070 2070 None is returned instead. This can be used by external callers to
2071 2071 know whether to continue feeding input or not.
2072 2072
2073 2073 The return value can be used to decide whether to use sys.ps1 or
2074 2074 sys.ps2 to prompt the next line."""
2075 2075
2076 2076 # if the source code has leading blanks, add 'if 1:\n' to it
2077 2077 # this allows execution of indented pasted code. It is tempting
2078 2078 # to add '\n' at the end of source to run commands like ' a=1'
2079 2079 # directly, but this fails for more complicated scenarios
2080 2080 source=source.encode(self.stdin_encoding)
2081 2081 if source[:1] in [' ', '\t']:
2082 2082 source = 'if 1:\n%s' % source
2083 2083
2084 2084 try:
2085 2085 code = self.compile(source,filename,symbol)
2086 2086 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2087 2087 # Case 1
2088 2088 self.showsyntaxerror(filename)
2089 2089 return None
2090 2090
2091 2091 if code is None:
2092 2092 # Case 2
2093 2093 return True
2094 2094
2095 2095 # Case 3
2096 2096 # We store the code object so that threaded shells and
2097 2097 # custom exception handlers can access all this info if needed.
2098 2098 # The source corresponding to this can be obtained from the
2099 2099 # buffer attribute as '\n'.join(self.buffer).
2100 2100 self.code_to_run = code
2101 2101 # now actually execute the code object
2102 2102 if self.runcode(code) == 0:
2103 2103 return False
2104 2104 else:
2105 2105 return None
2106 2106
2107 2107 def runcode(self,code_obj):
2108 2108 """Execute a code object.
2109 2109
2110 2110 When an exception occurs, self.showtraceback() is called to display a
2111 2111 traceback.
2112 2112
2113 2113 Return value: a flag indicating whether the code to be run completed
2114 2114 successfully:
2115 2115
2116 2116 - 0: successful execution.
2117 2117 - 1: an error occurred.
2118 2118 """
2119 2119
2120 2120 # Set our own excepthook in case the user code tries to call it
2121 2121 # directly, so that the IPython crash handler doesn't get triggered
2122 2122 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2123 2123
2124 2124 # we save the original sys.excepthook in the instance, in case config
2125 2125 # code (such as magics) needs access to it.
2126 2126 self.sys_excepthook = old_excepthook
2127 2127 outflag = 1 # happens in more places, so it's easier as default
2128 2128 try:
2129 2129 try:
2130 2130 self.hooks.pre_runcode_hook()
2131 2131 exec code_obj in self.user_global_ns, self.user_ns
2132 2132 finally:
2133 2133 # Reset our crash handler in place
2134 2134 sys.excepthook = old_excepthook
2135 2135 except SystemExit:
2136 2136 self.resetbuffer()
2137 2137 self.showtraceback()
2138 2138 warn("Type %exit or %quit to exit IPython "
2139 2139 "(%Exit or %Quit do so unconditionally).",level=1)
2140 2140 except self.custom_exceptions:
2141 2141 etype,value,tb = sys.exc_info()
2142 2142 self.CustomTB(etype,value,tb)
2143 2143 except:
2144 2144 self.showtraceback()
2145 2145 else:
2146 2146 outflag = 0
2147 2147 if softspace(sys.stdout, 0):
2148 2148 print
2149 2149 # Flush out code object which has been run (and source)
2150 2150 self.code_to_run = None
2151 2151 return outflag
2152 2152
2153 2153 def push_line(self, line):
2154 2154 """Push a line to the interpreter.
2155 2155
2156 2156 The line should not have a trailing newline; it may have
2157 2157 internal newlines. The line is appended to a buffer and the
2158 2158 interpreter's runsource() method is called with the
2159 2159 concatenated contents of the buffer as source. If this
2160 2160 indicates that the command was executed or invalid, the buffer
2161 2161 is reset; otherwise, the command is incomplete, and the buffer
2162 2162 is left as it was after the line was appended. The return
2163 2163 value is 1 if more input is required, 0 if the line was dealt
2164 2164 with in some way (this is the same as runsource()).
2165 2165 """
2166 2166
2167 2167 # autoindent management should be done here, and not in the
2168 2168 # interactive loop, since that one is only seen by keyboard input. We
2169 2169 # need this done correctly even for code run via runlines (which uses
2170 2170 # push).
2171 2171
2172 2172 #print 'push line: <%s>' % line # dbg
2173 2173 for subline in line.splitlines():
2174 2174 self._autoindent_update(subline)
2175 2175 self.buffer.append(line)
2176 2176 more = self.runsource('\n'.join(self.buffer), self.filename)
2177 2177 if not more:
2178 2178 self.resetbuffer()
2179 2179 return more
2180 2180
2181 2181 def _autoindent_update(self,line):
2182 2182 """Keep track of the indent level."""
2183 2183
2184 2184 #debugx('line')
2185 2185 #debugx('self.indent_current_nsp')
2186 2186 if self.autoindent:
2187 2187 if line:
2188 2188 inisp = num_ini_spaces(line)
2189 2189 if inisp < self.indent_current_nsp:
2190 2190 self.indent_current_nsp = inisp
2191 2191
2192 2192 if line[-1] == ':':
2193 2193 self.indent_current_nsp += 4
2194 2194 elif dedent_re.match(line):
2195 2195 self.indent_current_nsp -= 4
2196 2196 else:
2197 2197 self.indent_current_nsp = 0
2198 2198
2199 2199 def resetbuffer(self):
2200 2200 """Reset the input buffer."""
2201 2201 self.buffer[:] = []
2202 2202
2203 2203 def raw_input(self,prompt='',continue_prompt=False):
2204 2204 """Write a prompt and read a line.
2205 2205
2206 2206 The returned line does not include the trailing newline.
2207 2207 When the user enters the EOF key sequence, EOFError is raised.
2208 2208
2209 2209 Optional inputs:
2210 2210
2211 2211 - prompt(''): a string to be printed to prompt the user.
2212 2212
2213 2213 - continue_prompt(False): whether this line is the first one or a
2214 2214 continuation in a sequence of inputs.
2215 2215 """
2216 2216 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2217 2217
2218 2218 # Code run by the user may have modified the readline completer state.
2219 2219 # We must ensure that our completer is back in place.
2220 2220
2221 2221 if self.has_readline:
2222 2222 self.set_completer()
2223 2223
2224 2224 try:
2225 2225 line = raw_input_original(prompt).decode(self.stdin_encoding)
2226 2226 except ValueError:
2227 2227 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2228 2228 " or sys.stdout.close()!\nExiting IPython!")
2229 2229 self.ask_exit()
2230 2230 return ""
2231 2231
2232 2232 # Try to be reasonably smart about not re-indenting pasted input more
2233 2233 # than necessary. We do this by trimming out the auto-indent initial
2234 2234 # spaces, if the user's actual input started itself with whitespace.
2235 2235 #debugx('self.buffer[-1]')
2236 2236
2237 2237 if self.autoindent:
2238 2238 if num_ini_spaces(line) > self.indent_current_nsp:
2239 2239 line = line[self.indent_current_nsp:]
2240 2240 self.indent_current_nsp = 0
2241 2241
2242 2242 # store the unfiltered input before the user has any chance to modify
2243 2243 # it.
2244 2244 if line.strip():
2245 2245 if continue_prompt:
2246 2246 self.input_hist_raw[-1] += '%s\n' % line
2247 2247 if self.has_readline and self.readline_use:
2248 2248 try:
2249 2249 histlen = self.readline.get_current_history_length()
2250 2250 if histlen > 1:
2251 2251 newhist = self.input_hist_raw[-1].rstrip()
2252 2252 self.readline.remove_history_item(histlen-1)
2253 2253 self.readline.replace_history_item(histlen-2,
2254 2254 newhist.encode(self.stdin_encoding))
2255 2255 except AttributeError:
2256 2256 pass # re{move,place}_history_item are new in 2.4.
2257 2257 else:
2258 2258 self.input_hist_raw.append('%s\n' % line)
2259 2259 # only entries starting at first column go to shadow history
2260 2260 if line.lstrip() == line:
2261 2261 self.shadowhist.add(line.strip())
2262 2262 elif not continue_prompt:
2263 2263 self.input_hist_raw.append('\n')
2264 2264 try:
2265 2265 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2266 2266 except:
2267 2267 # blanket except, in case a user-defined prefilter crashes, so it
2268 2268 # can't take all of ipython with it.
2269 2269 self.showtraceback()
2270 2270 return ''
2271 2271 else:
2272 2272 return lineout
2273 2273
2274 2274 #-------------------------------------------------------------------------
2275 2275 # Working with components
2276 2276 #-------------------------------------------------------------------------
2277 2277
2278 2278 def get_component(self, name=None, klass=None):
2279 2279 """Fetch a component by name and klass in my tree."""
2280 2280 c = Component.get_instances(root=self, name=name, klass=klass)
2281 2281 if len(c) == 1:
2282 2282 return c[0]
2283 2283 else:
2284 2284 return c
2285 2285
2286 2286 #-------------------------------------------------------------------------
2287 2287 # IPython extensions
2288 2288 #-------------------------------------------------------------------------
2289 2289
2290 2290 def load_extension(self, module_str):
2291 2291 """Load an IPython extension by its module name.
2292 2292
2293 2293 An IPython extension is an importable Python module that has
2294 2294 a function with the signature::
2295 2295
2296 2296 def load_ipython_extension(ipython):
2297 2297 # Do things with ipython
2298 2298
2299 2299 This function is called after your extension is imported and the
2300 2300 currently active :class:`InteractiveShell` instance is passed as
2301 2301 the only argument. You can do anything you want with IPython at
2302 2302 that point, including defining new magic and aliases, adding new
2303 2303 components, etc.
2304 2304
2305 2305 The :func:`load_ipython_extension` will be called again is you
2306 2306 load or reload the extension again. It is up to the extension
2307 2307 author to add code to manage that.
2308 2308
2309 2309 You can put your extension modules anywhere you want, as long as
2310 2310 they can be imported by Python's standard import mechanism. However,
2311 2311 to make it easy to write extensions, you can also put your extensions
2312 2312 in ``os.path.join(self.ipythondir, 'extensions')``. This directory
2313 2313 is added to ``sys.path`` automatically.
2314 2314 """
2315 2315 from IPython.utils.syspathcontext import prepended_to_syspath
2316 2316
2317 2317 if module_str not in sys.modules:
2318 2318 with prepended_to_syspath(self.ipython_extension_dir):
2319 2319 __import__(module_str)
2320 2320 mod = sys.modules[module_str]
2321 2321 self._call_load_ipython_extension(mod)
2322 2322
2323 2323 def unload_extension(self, module_str):
2324 2324 """Unload an IPython extension by its module name.
2325 2325
2326 2326 This function looks up the extension's name in ``sys.modules`` and
2327 2327 simply calls ``mod.unload_ipython_extension(self)``.
2328 2328 """
2329 2329 if module_str in sys.modules:
2330 2330 mod = sys.modules[module_str]
2331 2331 self._call_unload_ipython_extension(mod)
2332 2332
2333 2333 def reload_extension(self, module_str):
2334 2334 """Reload an IPython extension by calling reload.
2335 2335
2336 2336 If the module has not been loaded before,
2337 2337 :meth:`InteractiveShell.load_extension` is called. Otherwise
2338 2338 :func:`reload` is called and then the :func:`load_ipython_extension`
2339 2339 function of the module, if it exists is called.
2340 2340 """
2341 2341 from IPython.utils.syspathcontext import prepended_to_syspath
2342 2342
2343 2343 with prepended_to_syspath(self.ipython_extension_dir):
2344 2344 if module_str in sys.modules:
2345 2345 mod = sys.modules[module_str]
2346 2346 reload(mod)
2347 2347 self._call_load_ipython_extension(mod)
2348 2348 else:
2349 2349 self.load_extension(module_str)
2350 2350
2351 2351 def _call_load_ipython_extension(self, mod):
2352 2352 if hasattr(mod, 'load_ipython_extension'):
2353 2353 mod.load_ipython_extension(self)
2354 2354
2355 2355 def _call_unload_ipython_extension(self, mod):
2356 2356 if hasattr(mod, 'unload_ipython_extension'):
2357 2357 mod.unload_ipython_extension(self)
2358 2358
2359 2359 #-------------------------------------------------------------------------
2360 2360 # Things related to the prefilter
2361 2361 #-------------------------------------------------------------------------
2362 2362
2363 2363 def init_prefilter(self):
2364 2364 self.prefilter_manager = PrefilterManager(self, config=self.config)
2365 2365
2366 2366 #-------------------------------------------------------------------------
2367 2367 # Utilities
2368 2368 #-------------------------------------------------------------------------
2369 2369
2370 2370 def getoutput(self, cmd):
2371 2371 return getoutput(self.var_expand(cmd,depth=2),
2372 2372 header=self.system_header,
2373 2373 verbose=self.system_verbose)
2374 2374
2375 2375 def getoutputerror(self, cmd):
2376 2376 return getoutputerror(self.var_expand(cmd,depth=2),
2377 2377 header=self.system_header,
2378 2378 verbose=self.system_verbose)
2379 2379
2380 2380 def var_expand(self,cmd,depth=0):
2381 2381 """Expand python variables in a string.
2382 2382
2383 2383 The depth argument indicates how many frames above the caller should
2384 2384 be walked to look for the local namespace where to expand variables.
2385 2385
2386 2386 The global namespace for expansion is always the user's interactive
2387 2387 namespace.
2388 2388 """
2389 2389
2390 2390 return str(ItplNS(cmd,
2391 2391 self.user_ns, # globals
2392 2392 # Skip our own frame in searching for locals:
2393 2393 sys._getframe(depth+1).f_locals # locals
2394 2394 ))
2395 2395
2396 2396 def mktempfile(self,data=None):
2397 2397 """Make a new tempfile and return its filename.
2398 2398
2399 2399 This makes a call to tempfile.mktemp, but it registers the created
2400 2400 filename internally so ipython cleans it up at exit time.
2401 2401
2402 2402 Optional inputs:
2403 2403
2404 2404 - data(None): if data is given, it gets written out to the temp file
2405 2405 immediately, and the file is closed again."""
2406 2406
2407 2407 filename = tempfile.mktemp('.py','ipython_edit_')
2408 2408 self.tempfiles.append(filename)
2409 2409
2410 2410 if data:
2411 2411 tmp_file = open(filename,'w')
2412 2412 tmp_file.write(data)
2413 2413 tmp_file.close()
2414 2414 return filename
2415 2415
2416 2416 def write(self,data):
2417 2417 """Write a string to the default output"""
2418 2418 Term.cout.write(data)
2419 2419
2420 2420 def write_err(self,data):
2421 2421 """Write a string to the default error output"""
2422 2422 Term.cerr.write(data)
2423 2423
2424 2424 def ask_yes_no(self,prompt,default=True):
2425 2425 if self.quiet:
2426 2426 return True
2427 2427 return ask_yes_no(prompt,default)
2428 2428
2429 2429 #-------------------------------------------------------------------------
2430 2430 # Things related to IPython exiting
2431 2431 #-------------------------------------------------------------------------
2432 2432
2433 2433 def ask_exit(self):
2434 2434 """ Call for exiting. Can be overiden and used as a callback. """
2435 2435 self.exit_now = True
2436 2436
2437 2437 def exit(self):
2438 2438 """Handle interactive exit.
2439 2439
2440 2440 This method calls the ask_exit callback."""
2441 2441 if self.confirm_exit:
2442 2442 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2443 2443 self.ask_exit()
2444 2444 else:
2445 2445 self.ask_exit()
2446 2446
2447 2447 def atexit_operations(self):
2448 2448 """This will be executed at the time of exit.
2449 2449
2450 2450 Saving of persistent data should be performed here.
2451 2451 """
2452 2452 self.savehist()
2453 2453
2454 2454 # Cleanup all tempfiles left around
2455 2455 for tfile in self.tempfiles:
2456 2456 try:
2457 2457 os.unlink(tfile)
2458 2458 except OSError:
2459 2459 pass
2460 2460
2461 2461 # Clear all user namespaces to release all references cleanly.
2462 2462 self.reset()
2463 2463
2464 2464 # Run user hooks
2465 2465 self.hooks.shutdown_hook()
2466 2466
2467 2467 def cleanup(self):
2468 2468 self.restore_sys_module_state()
2469 2469
2470 2470
@@ -1,214 +1,214 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Tests for IPython.core.component
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez (design help)
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from unittest import TestCase
24 24
25 25 from IPython.core.component import Component, ComponentError
26 26 from IPython.utils.traitlets import (
27 TraitletError, Int, Float, Str
27 TraitError, Int, Float, Str
28 28 )
29 29 from IPython.config.loader import Config
30 30
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Test cases
34 34 #-----------------------------------------------------------------------------
35 35
36 36
37 37 class TestComponentMeta(TestCase):
38 38
39 39 def test_get_instances(self):
40 40 class BaseComponent(Component):
41 41 pass
42 42 c1 = BaseComponent(None)
43 43 c2 = BaseComponent(c1)
44 44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
45 45
46 46 def test_get_instances_subclass(self):
47 47 class MyComponent(Component):
48 48 pass
49 49 class MyOtherComponent(MyComponent):
50 50 pass
51 51 c1 = MyComponent(None)
52 52 c2 = MyOtherComponent(c1)
53 53 c3 = MyOtherComponent(c2)
54 54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
55 55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
56 56
57 57 def test_get_instances_root(self):
58 58 class MyComponent(Component):
59 59 pass
60 60 class MyOtherComponent(MyComponent):
61 61 pass
62 62 c1 = MyComponent(None)
63 63 c2 = MyOtherComponent(c1)
64 64 c3 = MyOtherComponent(c2)
65 65 c4 = MyComponent(None)
66 66 c5 = MyComponent(c4)
67 67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
68 68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
69 69
70 70
71 71 class TestComponent(TestCase):
72 72
73 73 def test_parent_child(self):
74 74 c1 = Component(None)
75 75 c2 = Component(c1)
76 76 c3 = Component(c1)
77 77 c4 = Component(c3)
78 78 self.assertEquals(c1.parent, None)
79 79 self.assertEquals(c2.parent, c1)
80 80 self.assertEquals(c3.parent, c1)
81 81 self.assertEquals(c4.parent, c3)
82 82 self.assertEquals(c1.children, [c2, c3])
83 83 self.assertEquals(c2.children, [])
84 84 self.assertEquals(c3.children, [c4])
85 85 self.assertEquals(c4.children, [])
86 86
87 87 def test_root(self):
88 88 c1 = Component(None)
89 89 c2 = Component(c1)
90 90 c3 = Component(c1)
91 91 c4 = Component(c3)
92 92 self.assertEquals(c1.root, c1.root)
93 93 self.assertEquals(c2.root, c1)
94 94 self.assertEquals(c3.root, c1)
95 95 self.assertEquals(c4.root, c1)
96 96
97 97 def test_change_parent(self):
98 98 c1 = Component(None)
99 99 c2 = Component(None)
100 100 c3 = Component(c1)
101 101 self.assertEquals(c3.root, c1)
102 102 self.assertEquals(c3.parent, c1)
103 103 self.assertEquals(c1.children,[c3])
104 104 c3.parent = c2
105 105 self.assertEquals(c3.root, c2)
106 106 self.assertEquals(c3.parent, c2)
107 107 self.assertEquals(c2.children,[c3])
108 108 self.assertEquals(c1.children,[])
109 109
110 110 def test_subclass_parent(self):
111 111 c1 = Component(None)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
112 self.assertRaises(TraitError, setattr, c1, 'parent', 10)
113 113
114 114 class MyComponent(Component):
115 115 pass
116 116 c1 = Component(None)
117 117 c2 = MyComponent(c1)
118 118 self.assertEquals(MyComponent.parent.this_class, Component)
119 119 self.assertEquals(c2.parent, c1)
120 120
121 121 def test_bad_root(self):
122 122 c1 = Component(None)
123 123 c2 = Component(None)
124 124 c3 = Component(None)
125 125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
126 126 c1.parent = c2
127 127 self.assertEquals(c1.root, c2)
128 128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
129 129
130 130
131 131 class TestComponentConfig(TestCase):
132 132
133 133 def test_default(self):
134 134 c1 = Component(None)
135 135 c2 = Component(c1)
136 136 c3 = Component(c2)
137 137 self.assertEquals(c1.config, c2.config)
138 138 self.assertEquals(c2.config, c3.config)
139 139
140 140 def test_custom(self):
141 141 config = Config()
142 142 config.foo = 'foo'
143 143 config.bar = 'bar'
144 144 c1 = Component(None, config=config)
145 145 c2 = Component(c1)
146 146 c3 = Component(c2)
147 147 self.assertEquals(c1.config, config)
148 148 self.assertEquals(c2.config, config)
149 149 self.assertEquals(c3.config, config)
150 150 # Test that copies are not made
151 151 self.assert_(c1.config is config)
152 152 self.assert_(c2.config is config)
153 153 self.assert_(c3.config is config)
154 154 self.assert_(c1.config is c2.config)
155 155 self.assert_(c2.config is c3.config)
156 156
157 157 def test_inheritance(self):
158 158 class MyComponent(Component):
159 159 a = Int(1, config=True)
160 160 b = Float(1.0, config=True)
161 161 c = Str('no config')
162 162 config = Config()
163 163 config.MyComponent.a = 2
164 164 config.MyComponent.b = 2.0
165 165 c1 = MyComponent(None, config=config)
166 166 c2 = MyComponent(c1)
167 167 self.assertEquals(c1.a, config.MyComponent.a)
168 168 self.assertEquals(c1.b, config.MyComponent.b)
169 169 self.assertEquals(c2.a, config.MyComponent.a)
170 170 self.assertEquals(c2.b, config.MyComponent.b)
171 171 c4 = MyComponent(c2, config=Config())
172 172 self.assertEquals(c4.a, 1)
173 173 self.assertEquals(c4.b, 1.0)
174 174
175 175 def test_parent(self):
176 176 class Foo(Component):
177 177 a = Int(0, config=True)
178 178 b = Str('nope', config=True)
179 179 class Bar(Foo):
180 180 b = Str('gotit', config=False)
181 181 c = Float(config=True)
182 182 config = Config()
183 183 config.Foo.a = 10
184 184 config.Foo.b = "wow"
185 185 config.Bar.b = 'later'
186 186 config.Bar.c = 100.0
187 187 f = Foo(None, config=config)
188 188 b = Bar(f)
189 189 self.assertEquals(f.a, 10)
190 190 self.assertEquals(f.b, 'wow')
191 191 self.assertEquals(b.b, 'gotit')
192 192 self.assertEquals(b.c, 100.0)
193 193
194 194
195 195 class TestComponentName(TestCase):
196 196
197 197 def test_default(self):
198 198 class MyComponent(Component):
199 199 pass
200 200 c1 = Component(None)
201 201 c2 = MyComponent(None)
202 202 c3 = Component(c2)
203 203 self.assertNotEquals(c1.name, c2.name)
204 204 self.assertNotEquals(c1.name, c3.name)
205 205
206 206 def test_manual(self):
207 207 class MyComponent(Component):
208 208 pass
209 209 c1 = Component(None, name='foo')
210 210 c2 = MyComponent(None, name='bar')
211 211 c3 = Component(c2, name='bah')
212 212 self.assertEquals(c1.name, 'foo')
213 213 self.assertEquals(c2.name, 'bar')
214 214 self.assertEquals(c3.name, 'bah')
@@ -1,690 +1,690 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Tests for IPython.utils.traitlets.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
10 10 and is licensed under the BSD license. Also, many of the ideas also come
11 11 from enthought.traits even though our implementation is very different.
12 12 """
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Copyright (C) 2008-2009 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-----------------------------------------------------------------------------
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Imports
23 23 #-----------------------------------------------------------------------------
24 24
25 25 import sys
26 26 import os
27 27
28 28
29 29 from unittest import TestCase
30 30
31 31 from IPython.utils.traitlets import (
32 HasTraits, MetaHasTraits, TraitletType, Any,
33 Int, Long, Float, Complex, Str, Unicode, Bool, TraitletError,
32 HasTraits, MetaHasTraits, TraitType, Any,
33 Int, Long, Float, Complex, Str, Unicode, Bool, TraitError,
34 34 Undefined, Type, This, Instance
35 35 )
36 36
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Helper classes for testing
40 40 #-----------------------------------------------------------------------------
41 41
42 42
43 class HasTraitletsStub(HasTraits):
43 class HasTraitsStub(HasTraits):
44 44
45 def _notify_traitlet(self, name, old, new):
45 def _notify_trait(self, name, old, new):
46 46 self._notify_name = name
47 47 self._notify_old = old
48 48 self._notify_new = new
49 49
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Test classes
53 53 #-----------------------------------------------------------------------------
54 54
55 55
56 class TestTraitletType(TestCase):
56 class TestTraitType(TestCase):
57 57
58 58 def test_get_undefined(self):
59 59 class A(HasTraits):
60 a = TraitletType
60 a = TraitType
61 61 a = A()
62 62 self.assertEquals(a.a, Undefined)
63 63
64 64 def test_set(self):
65 class A(HasTraitletsStub):
66 a = TraitletType
65 class A(HasTraitsStub):
66 a = TraitType
67 67
68 68 a = A()
69 69 a.a = 10
70 70 self.assertEquals(a.a, 10)
71 71 self.assertEquals(a._notify_name, 'a')
72 72 self.assertEquals(a._notify_old, Undefined)
73 73 self.assertEquals(a._notify_new, 10)
74 74
75 75 def test_validate(self):
76 class MyTT(TraitletType):
76 class MyTT(TraitType):
77 77 def validate(self, inst, value):
78 78 return -1
79 class A(HasTraitletsStub):
79 class A(HasTraitsStub):
80 80 tt = MyTT
81 81
82 82 a = A()
83 83 a.tt = 10
84 84 self.assertEquals(a.tt, -1)
85 85
86 86 def test_default_validate(self):
87 class MyIntTT(TraitletType):
87 class MyIntTT(TraitType):
88 88 def validate(self, obj, value):
89 89 if isinstance(value, int):
90 90 return value
91 91 self.error(obj, value)
92 92 class A(HasTraits):
93 93 tt = MyIntTT(10)
94 94 a = A()
95 95 self.assertEquals(a.tt, 10)
96 96
97 97 # Defaults are validated when the HasTraits is instantiated
98 98 class B(HasTraits):
99 99 tt = MyIntTT('bad default')
100 self.assertRaises(TraitletError, B)
100 self.assertRaises(TraitError, B)
101 101
102 102 def test_is_valid_for(self):
103 class MyTT(TraitletType):
103 class MyTT(TraitType):
104 104 def is_valid_for(self, value):
105 105 return True
106 106 class A(HasTraits):
107 107 tt = MyTT
108 108
109 109 a = A()
110 110 a.tt = 10
111 111 self.assertEquals(a.tt, 10)
112 112
113 113 def test_value_for(self):
114 class MyTT(TraitletType):
114 class MyTT(TraitType):
115 115 def value_for(self, value):
116 116 return 20
117 117 class A(HasTraits):
118 118 tt = MyTT
119 119
120 120 a = A()
121 121 a.tt = 10
122 122 self.assertEquals(a.tt, 20)
123 123
124 124 def test_info(self):
125 125 class A(HasTraits):
126 tt = TraitletType
126 tt = TraitType
127 127 a = A()
128 128 self.assertEquals(A.tt.info(), 'any value')
129 129
130 130 def test_error(self):
131 131 class A(HasTraits):
132 tt = TraitletType
132 tt = TraitType
133 133 a = A()
134 self.assertRaises(TraitletError, A.tt.error, a, 10)
134 self.assertRaises(TraitError, A.tt.error, a, 10)
135 135
136 136
137 137 class TestHasTraitsMeta(TestCase):
138 138
139 139 def test_metaclass(self):
140 140 self.assertEquals(type(HasTraits), MetaHasTraits)
141 141
142 142 class A(HasTraits):
143 143 a = Int
144 144
145 145 a = A()
146 146 self.assertEquals(type(a.__class__), MetaHasTraits)
147 147 self.assertEquals(a.a,0)
148 148 a.a = 10
149 149 self.assertEquals(a.a,10)
150 150
151 151 class B(HasTraits):
152 152 b = Int()
153 153
154 154 b = B()
155 155 self.assertEquals(b.b,0)
156 156 b.b = 10
157 157 self.assertEquals(b.b,10)
158 158
159 159 class C(HasTraits):
160 160 c = Int(30)
161 161
162 162 c = C()
163 163 self.assertEquals(c.c,30)
164 164 c.c = 10
165 165 self.assertEquals(c.c,10)
166 166
167 167 def test_this_class(self):
168 168 class A(HasTraits):
169 169 t = This()
170 170 tt = This()
171 171 class B(A):
172 172 tt = This()
173 173 ttt = This()
174 174 self.assertEquals(A.t.this_class, A)
175 175 self.assertEquals(B.t.this_class, A)
176 176 self.assertEquals(B.tt.this_class, B)
177 177 self.assertEquals(B.ttt.this_class, B)
178 178
179 179 class TestHasTraitsNotify(TestCase):
180 180
181 181 def setUp(self):
182 182 self._notify1 = []
183 183 self._notify2 = []
184 184
185 185 def notify1(self, name, old, new):
186 186 self._notify1.append((name, old, new))
187 187
188 188 def notify2(self, name, old, new):
189 189 self._notify2.append((name, old, new))
190 190
191 191 def test_notify_all(self):
192 192
193 193 class A(HasTraits):
194 194 a = Int
195 195 b = Float
196 196
197 197 a = A()
198 198 a.on_trait_change(self.notify1)
199 199 a.a = 0
200 200 self.assertEquals(len(self._notify1),0)
201 201 a.b = 0.0
202 202 self.assertEquals(len(self._notify1),0)
203 203 a.a = 10
204 204 self.assert_(('a',0,10) in self._notify1)
205 205 a.b = 10.0
206 206 self.assert_(('b',0.0,10.0) in self._notify1)
207 self.assertRaises(TraitletError,setattr,a,'a','bad string')
208 self.assertRaises(TraitletError,setattr,a,'b','bad string')
207 self.assertRaises(TraitError,setattr,a,'a','bad string')
208 self.assertRaises(TraitError,setattr,a,'b','bad string')
209 209 self._notify1 = []
210 210 a.on_trait_change(self.notify1,remove=True)
211 211 a.a = 20
212 212 a.b = 20.0
213 213 self.assertEquals(len(self._notify1),0)
214 214
215 215 def test_notify_one(self):
216 216
217 217 class A(HasTraits):
218 218 a = Int
219 219 b = Float
220 220
221 221 a = A()
222 222 a.on_trait_change(self.notify1, 'a')
223 223 a.a = 0
224 224 self.assertEquals(len(self._notify1),0)
225 225 a.a = 10
226 226 self.assert_(('a',0,10) in self._notify1)
227 self.assertRaises(TraitletError,setattr,a,'a','bad string')
227 self.assertRaises(TraitError,setattr,a,'a','bad string')
228 228
229 229 def test_subclass(self):
230 230
231 231 class A(HasTraits):
232 232 a = Int
233 233
234 234 class B(A):
235 235 b = Float
236 236
237 237 b = B()
238 238 self.assertEquals(b.a,0)
239 239 self.assertEquals(b.b,0.0)
240 240 b.a = 100
241 241 b.b = 100.0
242 242 self.assertEquals(b.a,100)
243 243 self.assertEquals(b.b,100.0)
244 244
245 245 def test_notify_subclass(self):
246 246
247 247 class A(HasTraits):
248 248 a = Int
249 249
250 250 class B(A):
251 251 b = Float
252 252
253 253 b = B()
254 254 b.on_trait_change(self.notify1, 'a')
255 255 b.on_trait_change(self.notify2, 'b')
256 256 b.a = 0
257 257 b.b = 0.0
258 258 self.assertEquals(len(self._notify1),0)
259 259 self.assertEquals(len(self._notify2),0)
260 260 b.a = 10
261 261 b.b = 10.0
262 262 self.assert_(('a',0,10) in self._notify1)
263 263 self.assert_(('b',0.0,10.0) in self._notify2)
264 264
265 265 def test_static_notify(self):
266 266
267 267 class A(HasTraits):
268 268 a = Int
269 269 _notify1 = []
270 270 def _a_changed(self, name, old, new):
271 271 self._notify1.append((name, old, new))
272 272
273 273 a = A()
274 274 a.a = 0
275 275 # This is broken!!!
276 276 self.assertEquals(len(a._notify1),0)
277 277 a.a = 10
278 278 self.assert_(('a',0,10) in a._notify1)
279 279
280 280 class B(A):
281 281 b = Float
282 282 _notify2 = []
283 283 def _b_changed(self, name, old, new):
284 284 self._notify2.append((name, old, new))
285 285
286 286 b = B()
287 287 b.a = 10
288 288 b.b = 10.0
289 289 self.assert_(('a',0,10) in b._notify1)
290 290 self.assert_(('b',0.0,10.0) in b._notify2)
291 291
292 292 def test_notify_args(self):
293 293
294 294 def callback0():
295 295 self.cb = ()
296 296 def callback1(name):
297 297 self.cb = (name,)
298 298 def callback2(name, new):
299 299 self.cb = (name, new)
300 300 def callback3(name, old, new):
301 301 self.cb = (name, old, new)
302 302
303 303 class A(HasTraits):
304 304 a = Int
305 305
306 306 a = A()
307 307 a.on_trait_change(callback0, 'a')
308 308 a.a = 10
309 309 self.assertEquals(self.cb,())
310 310 a.on_trait_change(callback0, 'a', remove=True)
311 311
312 312 a.on_trait_change(callback1, 'a')
313 313 a.a = 100
314 314 self.assertEquals(self.cb,('a',))
315 315 a.on_trait_change(callback1, 'a', remove=True)
316 316
317 317 a.on_trait_change(callback2, 'a')
318 318 a.a = 1000
319 319 self.assertEquals(self.cb,('a',1000))
320 320 a.on_trait_change(callback2, 'a', remove=True)
321 321
322 322 a.on_trait_change(callback3, 'a')
323 323 a.a = 10000
324 324 self.assertEquals(self.cb,('a',1000,10000))
325 325 a.on_trait_change(callback3, 'a', remove=True)
326 326
327 self.assertEquals(len(a._traitlet_notifiers['a']),0)
327 self.assertEquals(len(a._trait_notifiers['a']),0)
328 328
329 329
330 330 class TestHasTraits(TestCase):
331 331
332 332 def test_trait_names(self):
333 333 class A(HasTraits):
334 334 i = Int
335 335 f = Float
336 336 a = A()
337 337 self.assertEquals(a.trait_names(),['i','f'])
338 338
339 339 def test_trait_metadata(self):
340 340 class A(HasTraits):
341 341 i = Int(config_key='MY_VALUE')
342 342 a = A()
343 343 self.assertEquals(a.trait_metadata('i','config_key'), 'MY_VALUE')
344 344
345 345 def test_traits(self):
346 346 class A(HasTraits):
347 347 i = Int
348 348 f = Float
349 349 a = A()
350 350 self.assertEquals(a.traits(), dict(i=A.i, f=A.f))
351 351
352 352 def test_traits_metadata(self):
353 353 class A(HasTraits):
354 354 i = Int(config_key='VALUE1', other_thing='VALUE2')
355 355 f = Float(config_key='VALUE3', other_thing='VALUE2')
356 356 j = Int(0)
357 357 a = A()
358 358 self.assertEquals(a.traits(), dict(i=A.i, f=A.f, j=A.j))
359 traitlets = a.traits(config_key='VALUE1', other_thing='VALUE2')
360 self.assertEquals(traitlets, dict(i=A.i))
359 traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
360 self.assertEquals(traits, dict(i=A.i))
361 361
362 362 # This passes, but it shouldn't because I am replicating a bug in
363 363 # traits.
364 traitlets = a.traits(config_key=lambda v: True)
365 self.assertEquals(traitlets, dict(i=A.i, f=A.f, j=A.j))
364 traits = a.traits(config_key=lambda v: True)
365 self.assertEquals(traits, dict(i=A.i, f=A.f, j=A.j))
366 366
367 367
368 368 #-----------------------------------------------------------------------------
369 # Tests for specific traitlet types
369 # Tests for specific trait types
370 370 #-----------------------------------------------------------------------------
371 371
372 372
373 373 class TestType(TestCase):
374 374
375 375 def test_default(self):
376 376
377 377 class B(object): pass
378 378 class A(HasTraits):
379 379 klass = Type
380 380
381 381 a = A()
382 382 self.assertEquals(a.klass, None)
383 383
384 384 a.klass = B
385 385 self.assertEquals(a.klass, B)
386 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
386 self.assertRaises(TraitError, setattr, a, 'klass', 10)
387 387
388 388 def test_value(self):
389 389
390 390 class B(object): pass
391 391 class C(object): pass
392 392 class A(HasTraits):
393 393 klass = Type(B)
394 394
395 395 a = A()
396 396 self.assertEquals(a.klass, B)
397 self.assertRaises(TraitletError, setattr, a, 'klass', C)
398 self.assertRaises(TraitletError, setattr, a, 'klass', object)
397 self.assertRaises(TraitError, setattr, a, 'klass', C)
398 self.assertRaises(TraitError, setattr, a, 'klass', object)
399 399 a.klass = B
400 400
401 401 def test_allow_none(self):
402 402
403 403 class B(object): pass
404 404 class C(B): pass
405 405 class A(HasTraits):
406 406 klass = Type(B, allow_none=False)
407 407
408 408 a = A()
409 409 self.assertEquals(a.klass, B)
410 self.assertRaises(TraitletError, setattr, a, 'klass', None)
410 self.assertRaises(TraitError, setattr, a, 'klass', None)
411 411 a.klass = C
412 412 self.assertEquals(a.klass, C)
413 413
414 414 def test_validate_klass(self):
415 415
416 416 class A(HasTraits):
417 417 klass = Type('no strings allowed')
418 418
419 419 self.assertRaises(ImportError, A)
420 420
421 421 class A(HasTraits):
422 422 klass = Type('rub.adub.Duck')
423 423
424 424 self.assertRaises(ImportError, A)
425 425
426 426 def test_validate_default(self):
427 427
428 428 class B(object): pass
429 429 class A(HasTraits):
430 430 klass = Type('bad default', B)
431 431
432 432 self.assertRaises(ImportError, A)
433 433
434 434 class C(HasTraits):
435 435 klass = Type(None, B, allow_none=False)
436 436
437 self.assertRaises(TraitletError, C)
437 self.assertRaises(TraitError, C)
438 438
439 439 def test_str_klass(self):
440 440
441 441 class A(HasTraits):
442 442 klass = Type('IPython.utils.ipstruct.Struct')
443 443
444 444 from IPython.utils.ipstruct import Struct
445 445 a = A()
446 446 a.klass = Struct
447 447 self.assertEquals(a.klass, Struct)
448 448
449 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
449 self.assertRaises(TraitError, setattr, a, 'klass', 10)
450 450
451 451 class TestInstance(TestCase):
452 452
453 453 def test_basic(self):
454 454 class Foo(object): pass
455 455 class Bar(Foo): pass
456 456 class Bah(object): pass
457 457
458 458 class A(HasTraits):
459 459 inst = Instance(Foo)
460 460
461 461 a = A()
462 462 self.assert_(a.inst is None)
463 463 a.inst = Foo()
464 464 self.assert_(isinstance(a.inst, Foo))
465 465 a.inst = Bar()
466 466 self.assert_(isinstance(a.inst, Foo))
467 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
468 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
469 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
467 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
468 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
469 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
470 470
471 471 def test_unique_default_value(self):
472 472 class Foo(object): pass
473 473 class A(HasTraits):
474 474 inst = Instance(Foo,(),{})
475 475
476 476 a = A()
477 477 b = A()
478 478 self.assert_(a.inst is not b.inst)
479 479
480 480 def test_args_kw(self):
481 481 class Foo(object):
482 482 def __init__(self, c): self.c = c
483 483 class Bar(object): pass
484 484 class Bah(object):
485 485 def __init__(self, c, d):
486 486 self.c = c; self.d = d
487 487
488 488 class A(HasTraits):
489 489 inst = Instance(Foo, (10,))
490 490 a = A()
491 491 self.assertEquals(a.inst.c, 10)
492 492
493 493 class B(HasTraits):
494 494 inst = Instance(Bah, args=(10,), kw=dict(d=20))
495 495 b = B()
496 496 self.assertEquals(b.inst.c, 10)
497 497 self.assertEquals(b.inst.d, 20)
498 498
499 499 class C(HasTraits):
500 500 inst = Instance(Foo)
501 501 c = C()
502 502 self.assert_(c.inst is None)
503 503
504 504 def test_bad_default(self):
505 505 class Foo(object): pass
506 506
507 507 class A(HasTraits):
508 508 inst = Instance(Foo, allow_none=False)
509 509
510 self.assertRaises(TraitletError, A)
510 self.assertRaises(TraitError, A)
511 511
512 512 def test_instance(self):
513 513 class Foo(object): pass
514 514
515 515 def inner():
516 516 class A(HasTraits):
517 517 inst = Instance(Foo())
518 518
519 self.assertRaises(TraitletError, inner)
519 self.assertRaises(TraitError, inner)
520 520
521 521
522 522 class TestThis(TestCase):
523 523
524 524 def test_this_class(self):
525 525 class Foo(HasTraits):
526 526 this = This
527 527
528 528 f = Foo()
529 529 self.assertEquals(f.this, None)
530 530 g = Foo()
531 531 f.this = g
532 532 self.assertEquals(f.this, g)
533 self.assertRaises(TraitletError, setattr, f, 'this', 10)
533 self.assertRaises(TraitError, setattr, f, 'this', 10)
534 534
535 535 def test_this_inst(self):
536 536 class Foo(HasTraits):
537 537 this = This()
538 538
539 539 f = Foo()
540 540 f.this = Foo()
541 541 self.assert_(isinstance(f.this, Foo))
542 542
543 543 def test_subclass(self):
544 544 class Foo(HasTraits):
545 545 t = This()
546 546 class Bar(Foo):
547 547 pass
548 548 f = Foo()
549 549 b = Bar()
550 550 f.t = b
551 551 b.t = f
552 552 self.assertEquals(f.t, b)
553 553 self.assertEquals(b.t, f)
554 554
555 555 def test_subclass_override(self):
556 556 class Foo(HasTraits):
557 557 t = This()
558 558 class Bar(Foo):
559 559 t = This()
560 560 f = Foo()
561 561 b = Bar()
562 562 f.t = b
563 563 self.assertEquals(f.t, b)
564 self.assertRaises(TraitletError, setattr, b, 't', f)
564 self.assertRaises(TraitError, setattr, b, 't', f)
565 565
566 class TraitletTestBase(TestCase):
567 """A best testing class for basic traitlet types."""
566 class TraitTestBase(TestCase):
567 """A best testing class for basic trait types."""
568 568
569 569 def assign(self, value):
570 570 self.obj.value = value
571 571
572 572 def coerce(self, value):
573 573 return value
574 574
575 575 def test_good_values(self):
576 576 if hasattr(self, '_good_values'):
577 577 for value in self._good_values:
578 578 self.assign(value)
579 579 self.assertEquals(self.obj.value, self.coerce(value))
580 580
581 581 def test_bad_values(self):
582 582 if hasattr(self, '_bad_values'):
583 583 for value in self._bad_values:
584 self.assertRaises(TraitletError, self.assign, value)
584 self.assertRaises(TraitError, self.assign, value)
585 585
586 586 def test_default_value(self):
587 587 if hasattr(self, '_default_value'):
588 588 self.assertEquals(self._default_value, self.obj.value)
589 589
590 590
591 class AnyTraitlet(HasTraits):
591 class AnyTrait(HasTraits):
592 592
593 593 value = Any
594 594
595 class AnyTraitTest(TraitletTestBase):
595 class AnyTraitTest(TraitTestBase):
596 596
597 obj = AnyTraitlet()
597 obj = AnyTrait()
598 598
599 599 _default_value = None
600 600 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
601 601 _bad_values = []
602 602
603 603
604 class IntTraitlet(HasTraits):
604 class IntTrait(HasTraits):
605 605
606 606 value = Int(99)
607 607
608 class TestInt(TraitletTestBase):
608 class TestInt(TraitTestBase):
609 609
610 obj = IntTraitlet()
610 obj = IntTrait()
611 611 _default_value = 99
612 612 _good_values = [10, -10]
613 613 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
614 614 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
615 615 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
616 616
617 617
618 class LongTraitlet(HasTraits):
618 class LongTrait(HasTraits):
619 619
620 620 value = Long(99L)
621 621
622 class TestLong(TraitletTestBase):
622 class TestLong(TraitTestBase):
623 623
624 obj = LongTraitlet()
624 obj = LongTrait()
625 625
626 626 _default_value = 99L
627 627 _good_values = [10, -10, 10L, -10L]
628 628 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
629 629 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
630 630 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
631 631 u'-10.1']
632 632
633 633
634 class FloatTraitlet(HasTraits):
634 class FloatTrait(HasTraits):
635 635
636 636 value = Float(99.0)
637 637
638 class TestFloat(TraitletTestBase):
638 class TestFloat(TraitTestBase):
639 639
640 obj = FloatTraitlet()
640 obj = FloatTrait()
641 641
642 642 _default_value = 99.0
643 643 _good_values = [10, -10, 10.1, -10.1]
644 644 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
645 645 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
646 646 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
647 647
648 648
649 class ComplexTraitlet(HasTraits):
649 class ComplexTrait(HasTraits):
650 650
651 651 value = Complex(99.0-99.0j)
652 652
653 class TestComplex(TraitletTestBase):
653 class TestComplex(TraitTestBase):
654 654
655 obj = ComplexTraitlet()
655 obj = ComplexTrait()
656 656
657 657 _default_value = 99.0-99.0j
658 658 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
659 659 10.1j, 10.1+10.1j, 10.1-10.1j]
660 660 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
661 661
662 662
663 class StringTraitlet(HasTraits):
663 class StringTrait(HasTraits):
664 664
665 665 value = Str('string')
666 666
667 class TestString(TraitletTestBase):
667 class TestString(TraitTestBase):
668 668
669 obj = StringTraitlet()
669 obj = StringTrait()
670 670
671 671 _default_value = 'string'
672 672 _good_values = ['10', '-10', '10L',
673 673 '-10L', '10.1', '-10.1', 'string']
674 674 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
675 675 ['ten'],{'ten': 10},(10,), None, u'string']
676 676
677 677
678 class UnicodeTraitlet(HasTraits):
678 class UnicodeTrait(HasTraits):
679 679
680 680 value = Unicode(u'unicode')
681 681
682 class TestUnicode(TraitletTestBase):
682 class TestUnicode(TraitTestBase):
683 683
684 obj = UnicodeTraitlet()
684 obj = UnicodeTrait()
685 685
686 686 _default_value = u'unicode'
687 687 _good_values = ['10', '-10', '10L', '-10L', '10.1',
688 688 '-10.1', '', u'', 'string', u'string', ]
689 689 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
690 690 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
@@ -1,1001 +1,994 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 A lightweight Traits like module.
5 5
6 6 This is designed to provide a lightweight, simple, pure Python version of
7 7 many of the capabilities of enthought.traits. This includes:
8 8
9 9 * Validation
10 10 * Type specification with defaults
11 11 * Static and dynamic notification
12 12 * Basic predefined types
13 13 * An API that is similar to enthought.traits
14 14
15 15 We don't support:
16 16
17 17 * Delegation
18 18 * Automatic GUI generation
19 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 21 contents change.
22 22 * API compatibility with enthought.traits
23 23
24 24 There are also some important difference in our design:
25 25
26 26 * enthought.traits does not validate default values. We do.
27 27
28 28 We choose to create this module because we need these capabilities, but
29 29 we need them to be pure Python so they work in all Python implementations,
30 30 including Jython and IronPython.
31 31
32 32 Authors:
33 33
34 34 * Brian Granger
35 35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
36 36 and is licensed under the BSD license. Also, many of the ideas also come
37 37 from enthought.traits even though our implementation is very different.
38 38 """
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Copyright (C) 2008-2009 The IPython Development Team
42 42 #
43 43 # Distributed under the terms of the BSD License. The full license is in
44 44 # the file COPYING, distributed as part of this software.
45 45 #-----------------------------------------------------------------------------
46 46
47 47 #-----------------------------------------------------------------------------
48 48 # Imports
49 49 #-----------------------------------------------------------------------------
50 50
51 51
52 52 import inspect
53 53 import sys
54 54 import types
55 55 from types import (
56 56 InstanceType, ClassType, FunctionType,
57 57 ListType, TupleType
58 58 )
59 59
60 60 def import_item(name):
61 61 """Import and return bar given the string foo.bar."""
62 62 package = '.'.join(name.split('.')[0:-1])
63 63 obj = name.split('.')[-1]
64 64 execString = 'from %s import %s' % (package, obj)
65 65 try:
66 66 exec execString
67 67 except SyntaxError:
68 68 raise ImportError("Invalid class specification: %s" % name)
69 69 exec 'temp = %s' % obj
70 70 return temp
71 71
72 72
73 73 ClassTypes = (ClassType, type)
74 74
75 75 SequenceTypes = (ListType, TupleType)
76 76
77 77 #-----------------------------------------------------------------------------
78 78 # Basic classes
79 79 #-----------------------------------------------------------------------------
80 80
81 81
82 82 class NoDefaultSpecified ( object ): pass
83 83 NoDefaultSpecified = NoDefaultSpecified()
84 84
85 85
86 86 class Undefined ( object ): pass
87 87 Undefined = Undefined()
88 88
89 # The following allows us to test specifically for a TraitletError, or more
90 # generally for a TraitError if we are going for compatability with Enthought
91 # Traits
92 89 class TraitError(Exception):
93 90 pass
94 91
95 class TraitletError(TraitError):
96 pass
97
98
99 92 #-----------------------------------------------------------------------------
100 93 # Utilities
101 94 #-----------------------------------------------------------------------------
102 95
103 96
104 97 def class_of ( object ):
105 98 """ Returns a string containing the class name of an object with the
106 99 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
107 100 'a PlotValue').
108 101 """
109 102 if isinstance( object, basestring ):
110 103 return add_article( object )
111 104
112 105 return add_article( object.__class__.__name__ )
113 106
114 107
115 108 def add_article ( name ):
116 109 """ Returns a string containing the correct indefinite article ('a' or 'an')
117 110 prefixed to the specified string.
118 111 """
119 112 if name[:1].lower() in 'aeiou':
120 113 return 'an ' + name
121 114
122 115 return 'a ' + name
123 116
124 117
125 118 def repr_type(obj):
126 119 """ Return a string representation of a value and its type for readable
127 120 error messages.
128 121 """
129 122 the_type = type(obj)
130 123 if the_type is InstanceType:
131 124 # Old-style class.
132 125 the_type = obj.__class__
133 126 msg = '%r %r' % (obj, the_type)
134 127 return msg
135 128
136 129
137 130 def parse_notifier_name(name):
138 131 """Convert the name argument to a list of names.
139 132
140 133 Examples
141 134 --------
142 135
143 136 >>> parse_notifier_name('a')
144 137 ['a']
145 138 >>> parse_notifier_name(['a','b'])
146 139 ['a', 'b']
147 140 >>> parse_notifier_name(None)
148 141 ['anytrait']
149 142 """
150 143 if isinstance(name, str):
151 144 return [name]
152 145 elif name is None:
153 146 return ['anytrait']
154 147 elif isinstance(name, (list, tuple)):
155 148 for n in name:
156 149 assert isinstance(n, str), "names must be strings"
157 150 return name
158 151
159 152
160 153 class _SimpleTest:
161 154 def __init__ ( self, value ): self.value = value
162 155 def __call__ ( self, test ):
163 156 return test == self.value
164 157 def __repr__(self):
165 158 return "<SimpleTest(%r)" % self.value
166 159 def __str__(self):
167 160 return self.__repr__()
168 161
169 162
170 163 #-----------------------------------------------------------------------------
171 # Base TraitletType for all traitlets
164 # Base TraitType for all traits
172 165 #-----------------------------------------------------------------------------
173 166
174 167
175 class TraitletType(object):
176 """A base class for all traitlet descriptors.
168 class TraitType(object):
169 """A base class for all trait descriptors.
177 170
178 171 Notes
179 172 -----
180 Our implementation of traitlets is based on Python's descriptor
173 Our implementation of traits is based on Python's descriptor
181 174 prototol. This class is the base class for all such descriptors. The
182 175 only magic we use is a custom metaclass for the main :class:`HasTraits`
183 176 class that does the following:
184 177
185 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
178 1. Sets the :attr:`name` attribute of every :class:`TraitType`
186 179 instance in the class dict to the name of the attribute.
187 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
188 instance in the class dict to the *class* that declared the traitlet.
189 This is used by the :class:`This` traitlet to allow subclasses to
180 2. Sets the :attr:`this_class` attribute of every :class:`TraitType`
181 instance in the class dict to the *class* that declared the trait.
182 This is used by the :class:`This` trait to allow subclasses to
190 183 accept superclasses for :class:`This` values.
191 184 """
192 185
193 186
194 187 metadata = {}
195 188 default_value = Undefined
196 189 info_text = 'any value'
197 190
198 191 def __init__(self, default_value=NoDefaultSpecified, **metadata):
199 """Create a TraitletType.
192 """Create a TraitType.
200 193 """
201 194 if default_value is not NoDefaultSpecified:
202 195 self.default_value = default_value
203 196
204 197 if len(metadata) > 0:
205 198 if len(self.metadata) > 0:
206 199 self._metadata = self.metadata.copy()
207 200 self._metadata.update(metadata)
208 201 else:
209 202 self._metadata = metadata
210 203 else:
211 204 self._metadata = self.metadata
212 205
213 206 self.init()
214 207
215 208 def init(self):
216 209 pass
217 210
218 211 def get_default_value(self):
219 212 """Create a new instance of the default value."""
220 213 dv = self.default_value
221 214 return dv
222 215
223 216 def instance_init(self, obj):
224 217 """This is called by :meth:`HasTraits.__new__` to finish init'ing.
225 218
226 219 Some stages of initialization must be delayed until the parent
227 220 :class:`HasTraits` instance has been created. This method is
228 221 called in :meth:`HasTraits.__new__` after the instance has been
229 222 created.
230 223
231 224 This method trigger the creation and validation of default values
232 225 and also things like the resolution of str given class names in
233 226 :class:`Type` and :class`Instance`.
234 227
235 228 Parameters
236 229 ----------
237 230 obj : :class:`HasTraits` instance
238 231 The parent :class:`HasTraits` instance that has just been
239 232 created.
240 233 """
241 234 self.set_default_value(obj)
242 235
243 236 def set_default_value(self, obj):
244 237 """Set the default value on a per instance basis.
245 238
246 239 This method is called by :meth:`instance_init` to create and
247 240 validate the default value. The creation and validation of
248 241 default values must be delayed until the parent :class:`HasTraits`
249 242 class has been instantiated.
250 243 """
251 244 dv = self.get_default_value()
252 245 newdv = self._validate(obj, dv)
253 obj._traitlet_values[self.name] = newdv
246 obj._trait_values[self.name] = newdv
254 247
255 248 def __get__(self, obj, cls=None):
256 """Get the value of the traitlet by self.name for the instance.
249 """Get the value of the trait by self.name for the instance.
257 250
258 251 Default values are instantiated when :meth:`HasTraits.__new__`
259 252 is called. Thus by the time this method gets called either the
260 253 default value or a user defined value (they called :meth:`__set__`)
261 254 is in the :class:`HasTraits` instance.
262 255 """
263 256 if obj is None:
264 257 return self
265 258 else:
266 259 try:
267 value = obj._traitlet_values[self.name]
260 value = obj._trait_values[self.name]
268 261 except:
269 262 # HasTraits should call set_default_value to populate
270 263 # this. So this should never be reached.
271 raise TraitletError('Unexpected error in TraitletType: '
264 raise TraitError('Unexpected error in TraitType: '
272 265 'default value not set properly')
273 266 else:
274 267 return value
275 268
276 269 def __set__(self, obj, value):
277 270 new_value = self._validate(obj, value)
278 271 old_value = self.__get__(obj)
279 272 if old_value != new_value:
280 obj._traitlet_values[self.name] = new_value
281 obj._notify_traitlet(self.name, old_value, new_value)
273 obj._trait_values[self.name] = new_value
274 obj._notify_trait(self.name, old_value, new_value)
282 275
283 276 def _validate(self, obj, value):
284 277 if hasattr(self, 'validate'):
285 278 return self.validate(obj, value)
286 279 elif hasattr(self, 'is_valid_for'):
287 280 valid = self.is_valid_for(value)
288 281 if valid:
289 282 return value
290 283 else:
291 raise TraitletError('invalid value for type: %r' % value)
284 raise TraitError('invalid value for type: %r' % value)
292 285 elif hasattr(self, 'value_for'):
293 286 return self.value_for(value)
294 287 else:
295 288 return value
296 289
297 290 def info(self):
298 291 return self.info_text
299 292
300 293 def error(self, obj, value):
301 294 if obj is not None:
302 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
295 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
303 296 % (self.name, class_of(obj),
304 297 self.info(), repr_type(value))
305 298 else:
306 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
299 e = "The '%s' trait must be %s, but a value of %r was specified." \
307 300 % (self.name, self.info(), repr_type(value))
308 raise TraitletError(e)
301 raise TraitError(e)
309 302
310 303 def get_metadata(self, key):
311 304 return getattr(self, '_metadata', {}).get(key, None)
312 305
313 306 def set_metadata(self, key, value):
314 307 getattr(self, '_metadata', {})[key] = value
315 308
316 309
317 310 #-----------------------------------------------------------------------------
318 311 # The HasTraits implementation
319 312 #-----------------------------------------------------------------------------
320 313
321 314
322 315 class MetaHasTraits(type):
323 316 """A metaclass for HasTraits.
324 317
325 This metaclass makes sure that any TraitletType class attributes are
318 This metaclass makes sure that any TraitType class attributes are
326 319 instantiated and sets their name attribute.
327 320 """
328 321
329 322 def __new__(mcls, name, bases, classdict):
330 323 """Create the HasTraits class.
331 324
332 This instantiates all TraitletTypes in the class dict and sets their
325 This instantiates all TraitTypes in the class dict and sets their
333 326 :attr:`name` attribute.
334 327 """
335 328 for k,v in classdict.iteritems():
336 if isinstance(v, TraitletType):
329 if isinstance(v, TraitType):
337 330 v.name = k
338 331 elif inspect.isclass(v):
339 if issubclass(v, TraitletType):
332 if issubclass(v, TraitType):
340 333 vinst = v()
341 334 vinst.name = k
342 335 classdict[k] = vinst
343 336 return super(MetaHasTraits, mcls).__new__(mcls, name, bases, classdict)
344 337
345 338 def __init__(cls, name, bases, classdict):
346 339 """Finish initializing the HasTraits class.
347 340
348 This sets the :attr:`this_class` attribute of each TraitletType in the
341 This sets the :attr:`this_class` attribute of each TraitType in the
349 342 class dict to the newly created class ``cls``.
350 343 """
351 344 for k, v in classdict.iteritems():
352 if isinstance(v, TraitletType):
345 if isinstance(v, TraitType):
353 346 v.this_class = cls
354 347 super(MetaHasTraits, cls).__init__(name, bases, classdict)
355 348
356 349 class HasTraits(object):
357 350
358 351 __metaclass__ = MetaHasTraits
359 352
360 353 def __new__(cls, *args, **kw):
361 354 # This is needed because in Python 2.6 object.__new__ only accepts
362 355 # the cls argument.
363 356 new_meth = super(HasTraits, cls).__new__
364 357 if new_meth is object.__new__:
365 358 inst = new_meth(cls)
366 359 else:
367 360 inst = new_meth(cls, *args, **kw)
368 inst._traitlet_values = {}
369 inst._traitlet_notifiers = {}
370 # Here we tell all the TraitletType instances to set their default
361 inst._trait_values = {}
362 inst._trait_notifiers = {}
363 # Here we tell all the TraitType instances to set their default
371 364 # values on the instance.
372 365 for key in dir(cls):
373 366 value = getattr(cls, key)
374 if isinstance(value, TraitletType):
367 if isinstance(value, TraitType):
375 368 value.instance_init(inst)
376 369 return inst
377 370
378 371 # def __init__(self):
379 # self._traitlet_values = {}
380 # self._traitlet_notifiers = {}
372 # self._trait_values = {}
373 # self._trait_notifiers = {}
381 374
382 def _notify_traitlet(self, name, old_value, new_value):
375 def _notify_trait(self, name, old_value, new_value):
383 376
384 377 # First dynamic ones
385 callables = self._traitlet_notifiers.get(name,[])
386 more_callables = self._traitlet_notifiers.get('anytrait',[])
378 callables = self._trait_notifiers.get(name,[])
379 more_callables = self._trait_notifiers.get('anytrait',[])
387 380 callables.extend(more_callables)
388 381
389 382 # Now static ones
390 383 try:
391 384 cb = getattr(self, '_%s_changed' % name)
392 385 except:
393 386 pass
394 387 else:
395 388 callables.append(cb)
396 389
397 390 # Call them all now
398 391 for c in callables:
399 392 # Traits catches and logs errors here. I allow them to raise
400 393 if callable(c):
401 394 argspec = inspect.getargspec(c)
402 395 nargs = len(argspec[0])
403 396 # Bound methods have an additional 'self' argument
404 397 # I don't know how to treat unbound methods, but they
405 398 # can't really be used for callbacks.
406 399 if isinstance(c, types.MethodType):
407 400 offset = -1
408 401 else:
409 402 offset = 0
410 403 if nargs + offset == 0:
411 404 c()
412 405 elif nargs + offset == 1:
413 406 c(name)
414 407 elif nargs + offset == 2:
415 408 c(name, new_value)
416 409 elif nargs + offset == 3:
417 410 c(name, old_value, new_value)
418 411 else:
419 raise TraitletError('a traitlet changed callback '
412 raise TraitError('a trait changed callback '
420 413 'must have 0-3 arguments.')
421 414 else:
422 raise TraitletError('a traitlet changed callback '
415 raise TraitError('a trait changed callback '
423 416 'must be callable.')
424 417
425 418
426 419 def _add_notifiers(self, handler, name):
427 if not self._traitlet_notifiers.has_key(name):
420 if not self._trait_notifiers.has_key(name):
428 421 nlist = []
429 self._traitlet_notifiers[name] = nlist
422 self._trait_notifiers[name] = nlist
430 423 else:
431 nlist = self._traitlet_notifiers[name]
424 nlist = self._trait_notifiers[name]
432 425 if handler not in nlist:
433 426 nlist.append(handler)
434 427
435 428 def _remove_notifiers(self, handler, name):
436 if self._traitlet_notifiers.has_key(name):
437 nlist = self._traitlet_notifiers[name]
429 if self._trait_notifiers.has_key(name):
430 nlist = self._trait_notifiers[name]
438 431 try:
439 432 index = nlist.index(handler)
440 433 except ValueError:
441 434 pass
442 435 else:
443 436 del nlist[index]
444 437
445 438 def on_trait_change(self, handler, name=None, remove=False):
446 """Setup a handler to be called when a traitlet changes.
439 """Setup a handler to be called when a trait changes.
447 440
448 This is used to setup dynamic notifications of traitlet changes.
441 This is used to setup dynamic notifications of trait changes.
449 442
450 443 Static handlers can be created by creating methods on a HasTraits
451 subclass with the naming convention '_[traitletname]_changed'. Thus,
452 to create static handler for the traitlet 'a', create the method
444 subclass with the naming convention '_[traitname]_changed'. Thus,
445 to create static handler for the trait 'a', create the method
453 446 _a_changed(self, name, old, new) (fewer arguments can be used, see
454 447 below).
455 448
456 449 Parameters
457 450 ----------
458 451 handler : callable
459 A callable that is called when a traitlet changes. Its
452 A callable that is called when a trait changes. Its
460 453 signature can be handler(), handler(name), handler(name, new)
461 454 or handler(name, old, new).
462 455 name : list, str, None
463 If None, the handler will apply to all traitlets. If a list
456 If None, the handler will apply to all traits. If a list
464 457 of str, handler will apply to all names in the list. If a
465 458 str, the handler will apply just to that name.
466 459 remove : bool
467 460 If False (the default), then install the handler. If True
468 461 then unintall it.
469 462 """
470 463 if remove:
471 464 names = parse_notifier_name(name)
472 465 for n in names:
473 466 self._remove_notifiers(handler, n)
474 467 else:
475 468 names = parse_notifier_name(name)
476 469 for n in names:
477 470 self._add_notifiers(handler, n)
478 471
479 472 def trait_names(self, **metadata):
480 """Get a list of all the names of this classes traitlets."""
473 """Get a list of all the names of this classes traits."""
481 474 return self.traits(**metadata).keys()
482 475
483 476 def traits(self, **metadata):
484 """Get a list of all the traitlets of this class.
477 """Get a list of all the traits of this class.
485 478
486 The TraitletTypes returned don't know anything about the values
487 that the various HasTraitlet's instances are holding.
479 The TraitTypes returned don't know anything about the values
480 that the various HasTrait's instances are holding.
488 481
489 482 This follows the same algorithm as traits does and does not allow
490 483 for any simple way of specifying merely that a metadata name
491 484 exists, but has any value. This is because get_metadata returns
492 485 None if a metadata key doesn't exist.
493 486 """
494 traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \
495 isinstance(memb[1], TraitletType)])
487 traits = dict([memb for memb in inspect.getmembers(self.__class__) if \
488 isinstance(memb[1], TraitType)])
496 489
497 490 if len(metadata) == 0:
498 return traitlets
491 return traits
499 492
500 493 for meta_name, meta_eval in metadata.items():
501 494 if type(meta_eval) is not FunctionType:
502 495 metadata[meta_name] = _SimpleTest(meta_eval)
503 496
504 497 result = {}
505 for name, traitlet in traitlets.items():
498 for name, trait in traits.items():
506 499 for meta_name, meta_eval in metadata.items():
507 if not meta_eval(traitlet.get_metadata(meta_name)):
500 if not meta_eval(trait.get_metadata(meta_name)):
508 501 break
509 502 else:
510 result[name] = traitlet
503 result[name] = trait
511 504
512 505 return result
513 506
514 def trait_metadata(self, traitletname, key):
515 """Get metadata values for traitlet by key."""
507 def trait_metadata(self, traitname, key):
508 """Get metadata values for trait by key."""
516 509 try:
517 traitlet = getattr(self.__class__, traitletname)
510 trait = getattr(self.__class__, traitname)
518 511 except AttributeError:
519 raise TraitletError("Class %s does not have a traitlet named %s" %
520 (self.__class__.__name__, traitletname))
512 raise TraitError("Class %s does not have a trait named %s" %
513 (self.__class__.__name__, traitname))
521 514 else:
522 return traitlet.get_metadata(key)
515 return trait.get_metadata(key)
523 516
524 517 #-----------------------------------------------------------------------------
525 # Actual TraitletTypes implementations/subclasses
518 # Actual TraitTypes implementations/subclasses
526 519 #-----------------------------------------------------------------------------
527 520
528 521 #-----------------------------------------------------------------------------
529 # TraitletTypes subclasses for handling classes and instances of classes
522 # TraitTypes subclasses for handling classes and instances of classes
530 523 #-----------------------------------------------------------------------------
531 524
532 525
533 class ClassBasedTraitletType(TraitletType):
534 """A traitlet with error reporting for Type, Instance and This."""
526 class ClassBasedTraitType(TraitType):
527 """A trait with error reporting for Type, Instance and This."""
535 528
536 529 def error(self, obj, value):
537 530 kind = type(value)
538 531 if kind is InstanceType:
539 532 msg = 'class %s' % value.__class__.__name__
540 533 else:
541 534 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
542 535
543 super(ClassBasedTraitletType, self).error(obj, msg)
536 super(ClassBasedTraitType, self).error(obj, msg)
544 537
545 538
546 class Type(ClassBasedTraitletType):
547 """A traitlet whose value must be a subclass of a specified class."""
539 class Type(ClassBasedTraitType):
540 """A trait whose value must be a subclass of a specified class."""
548 541
549 542 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
550 """Construct a Type traitlet
543 """Construct a Type trait
551 544
552 A Type traitlet specifies that its values must be subclasses of
545 A Type trait specifies that its values must be subclasses of
553 546 a particular class.
554 547
555 548 If only ``default_value`` is given, it is used for the ``klass`` as
556 549 well.
557 550
558 551 Parameters
559 552 ----------
560 553 default_value : class, str or None
561 554 The default value must be a subclass of klass. If an str,
562 555 the str must be a fully specified class name, like 'foo.bar.Bah'.
563 556 The string is resolved into real class, when the parent
564 557 :class:`HasTraits` class is instantiated.
565 558 klass : class, str, None
566 Values of this traitlet must be a subclass of klass. The klass
559 Values of this trait must be a subclass of klass. The klass
567 560 may be specified in a string like: 'foo.bar.MyClass'.
568 561 The string is resolved into real class, when the parent
569 562 :class:`HasTraits` class is instantiated.
570 563 allow_none : boolean
571 564 Indicates whether None is allowed as an assignable value. Even if
572 565 ``False``, the default value may be ``None``.
573 566 """
574 567 if default_value is None:
575 568 if klass is None:
576 569 klass = object
577 570 elif klass is None:
578 571 klass = default_value
579 572
580 573 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
581 raise TraitletError("A Type traitlet must specify a class.")
574 raise TraitError("A Type trait must specify a class.")
582 575
583 576 self.klass = klass
584 577 self._allow_none = allow_none
585 578
586 579 super(Type, self).__init__(default_value, **metadata)
587 580
588 581 def validate(self, obj, value):
589 582 """Validates that the value is a valid object instance."""
590 583 try:
591 584 if issubclass(value, self.klass):
592 585 return value
593 586 except:
594 587 if (value is None) and (self._allow_none):
595 588 return value
596 589
597 590 self.error(obj, value)
598 591
599 592 def info(self):
600 593 """ Returns a description of the trait."""
601 594 if isinstance(self.klass, basestring):
602 595 klass = self.klass
603 596 else:
604 597 klass = self.klass.__name__
605 598 result = 'a subclass of ' + klass
606 599 if self._allow_none:
607 600 return result + ' or None'
608 601 return result
609 602
610 603 def instance_init(self, obj):
611 604 self._resolve_classes()
612 605 super(Type, self).instance_init(obj)
613 606
614 607 def _resolve_classes(self):
615 608 if isinstance(self.klass, basestring):
616 609 self.klass = import_item(self.klass)
617 610 if isinstance(self.default_value, basestring):
618 611 self.default_value = import_item(self.default_value)
619 612
620 613 def get_default_value(self):
621 614 return self.default_value
622 615
623 616
624 617 class DefaultValueGenerator(object):
625 618 """A class for generating new default value instances."""
626 619
627 620 def __init__(self, *args, **kw):
628 621 self.args = args
629 622 self.kw = kw
630 623
631 624 def generate(self, klass):
632 625 return klass(*self.args, **self.kw)
633 626
634 627
635 class Instance(ClassBasedTraitletType):
628 class Instance(ClassBasedTraitType):
636 629 """A trait whose value must be an instance of a specified class.
637 630
638 631 The value can also be an instance of a subclass of the specified class.
639 632 """
640 633
641 634 def __init__(self, klass=None, args=None, kw=None,
642 635 allow_none=True, **metadata ):
643 """Construct an Instance traitlet.
636 """Construct an Instance trait.
644 637
645 This traitlet allows values that are instances of a particular
638 This trait allows values that are instances of a particular
646 639 class or its sublclasses. Our implementation is quite different
647 640 from that of enthough.traits as we don't allow instances to be used
648 641 for klass and we handle the ``args`` and ``kw`` arguments differently.
649 642
650 643 Parameters
651 644 ----------
652 645 klass : class, str
653 The class that forms the basis for the traitlet. Class names
646 The class that forms the basis for the trait. Class names
654 647 can also be specified as strings, like 'foo.bar.Bar'.
655 648 args : tuple
656 649 Positional arguments for generating the default value.
657 650 kw : dict
658 651 Keyword arguments for generating the default value.
659 652 allow_none : bool
660 653 Indicates whether None is allowed as a value.
661 654
662 655 Default Value
663 656 -------------
664 657 If both ``args`` and ``kw`` are None, then the default value is None.
665 658 If ``args`` is a tuple and ``kw`` is a dict, then the default is
666 659 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
667 660 not (but not both), None is replace by ``()`` or ``{}``.
668 661 """
669 662
670 663 self._allow_none = allow_none
671 664
672 665 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
673 raise TraitletError('The klass argument must be a class'
666 raise TraitError('The klass argument must be a class'
674 667 ' you gave: %r' % klass)
675 668 self.klass = klass
676 669
677 670 # self.klass is a class, so handle default_value
678 671 if args is None and kw is None:
679 672 default_value = None
680 673 else:
681 674 if args is None:
682 675 # kw is not None
683 676 args = ()
684 677 elif kw is None:
685 678 # args is not None
686 679 kw = {}
687 680
688 681 if not isinstance(kw, dict):
689 raise TraitletError("The 'kw' argument must be a dict or None.")
682 raise TraitError("The 'kw' argument must be a dict or None.")
690 683 if not isinstance(args, tuple):
691 raise TraitletError("The 'args' argument must be a tuple or None.")
684 raise TraitError("The 'args' argument must be a tuple or None.")
692 685
693 686 default_value = DefaultValueGenerator(*args, **kw)
694 687
695 688 super(Instance, self).__init__(default_value, **metadata)
696 689
697 690 def validate(self, obj, value):
698 691 if value is None:
699 692 if self._allow_none:
700 693 return value
701 694 self.error(obj, value)
702 695
703 696 if isinstance(value, self.klass):
704 697 return value
705 698 else:
706 699 self.error(obj, value)
707 700
708 701 def info(self):
709 702 if isinstance(self.klass, basestring):
710 703 klass = self.klass
711 704 else:
712 705 klass = self.klass.__name__
713 706 result = class_of(klass)
714 707 if self._allow_none:
715 708 return result + ' or None'
716 709
717 710 return result
718 711
719 712 def instance_init(self, obj):
720 713 self._resolve_classes()
721 714 super(Instance, self).instance_init(obj)
722 715
723 716 def _resolve_classes(self):
724 717 if isinstance(self.klass, basestring):
725 718 self.klass = import_item(self.klass)
726 719
727 720 def get_default_value(self):
728 721 """Instantiate a default value instance.
729 722
730 723 This is called when the containing HasTraits classes'
731 724 :meth:`__new__` method is called to ensure that a unique instance
732 725 is created for each HasTraits instance.
733 726 """
734 727 dv = self.default_value
735 728 if isinstance(dv, DefaultValueGenerator):
736 729 return dv.generate(self.klass)
737 730 else:
738 731 return dv
739 732
740 733
741 class This(ClassBasedTraitletType):
742 """A traitlet for instances of the class containing this trait.
734 class This(ClassBasedTraitType):
735 """A trait for instances of the class containing this trait.
743 736
744 737 Because how how and when class bodies are executed, the ``This``
745 traitlet can only have a default value of None. This, and because we
738 trait can only have a default value of None. This, and because we
746 739 always validate default values, ``allow_none`` is *always* true.
747 740 """
748 741
749 742 info_text = 'an instance of the same type as the receiver or None'
750 743
751 744 def __init__(self, **metadata):
752 745 super(This, self).__init__(None, **metadata)
753 746
754 747 def validate(self, obj, value):
755 748 # What if value is a superclass of obj.__class__? This is
756 749 # complicated if it was the superclass that defined the This
757 # traitlet.
750 # trait.
758 751 if isinstance(value, self.this_class) or (value is None):
759 752 return value
760 753 else:
761 754 self.error(obj, value)
762 755
763 756
764 757 #-----------------------------------------------------------------------------
765 # Basic TraitletTypes implementations/subclasses
758 # Basic TraitTypes implementations/subclasses
766 759 #-----------------------------------------------------------------------------
767 760
768 761
769 class Any(TraitletType):
762 class Any(TraitType):
770 763 default_value = None
771 764 info_text = 'any value'
772 765
773 766
774 class Int(TraitletType):
775 """A integer traitlet."""
767 class Int(TraitType):
768 """A integer trait."""
776 769
777 770 evaluate = int
778 771 default_value = 0
779 772 info_text = 'an integer'
780 773
781 774 def validate(self, obj, value):
782 775 if isinstance(value, int):
783 776 return value
784 777 self.error(obj, value)
785 778
786 779 class CInt(Int):
787 """A casting version of the int traitlet."""
780 """A casting version of the int trait."""
788 781
789 782 def validate(self, obj, value):
790 783 try:
791 784 return int(value)
792 785 except:
793 786 self.error(obj, value)
794 787
795 788
796 class Long(TraitletType):
797 """A long integer traitlet."""
789 class Long(TraitType):
790 """A long integer trait."""
798 791
799 792 evaluate = long
800 793 default_value = 0L
801 794 info_text = 'a long'
802 795
803 796 def validate(self, obj, value):
804 797 if isinstance(value, long):
805 798 return value
806 799 if isinstance(value, int):
807 800 return long(value)
808 801 self.error(obj, value)
809 802
810 803
811 804 class CLong(Long):
812 """A casting version of the long integer traitlet."""
805 """A casting version of the long integer trait."""
813 806
814 807 def validate(self, obj, value):
815 808 try:
816 809 return long(value)
817 810 except:
818 811 self.error(obj, value)
819 812
820 813
821 class Float(TraitletType):
822 """A float traitlet."""
814 class Float(TraitType):
815 """A float trait."""
823 816
824 817 evaluate = float
825 818 default_value = 0.0
826 819 info_text = 'a float'
827 820
828 821 def validate(self, obj, value):
829 822 if isinstance(value, float):
830 823 return value
831 824 if isinstance(value, int):
832 825 return float(value)
833 826 self.error(obj, value)
834 827
835 828
836 829 class CFloat(Float):
837 """A casting version of the float traitlet."""
830 """A casting version of the float trait."""
838 831
839 832 def validate(self, obj, value):
840 833 try:
841 834 return float(value)
842 835 except:
843 836 self.error(obj, value)
844 837
845 class Complex(TraitletType):
846 """A traitlet for complex numbers."""
838 class Complex(TraitType):
839 """A trait for complex numbers."""
847 840
848 841 evaluate = complex
849 842 default_value = 0.0 + 0.0j
850 843 info_text = 'a complex number'
851 844
852 845 def validate(self, obj, value):
853 846 if isinstance(value, complex):
854 847 return value
855 848 if isinstance(value, (float, int)):
856 849 return complex(value)
857 850 self.error(obj, value)
858 851
859 852
860 853 class CComplex(Complex):
861 """A casting version of the complex number traitlet."""
854 """A casting version of the complex number trait."""
862 855
863 856 def validate (self, obj, value):
864 857 try:
865 858 return complex(value)
866 859 except:
867 860 self.error(obj, value)
868 861
869 862
870 class Str(TraitletType):
871 """A traitlet for strings."""
863 class Str(TraitType):
864 """A trait for strings."""
872 865
873 866 evaluate = lambda x: x
874 867 default_value = ''
875 868 info_text = 'a string'
876 869
877 870 def validate(self, obj, value):
878 871 if isinstance(value, str):
879 872 return value
880 873 self.error(obj, value)
881 874
882 875
883 876 class CStr(Str):
884 """A casting version of the string traitlet."""
877 """A casting version of the string trait."""
885 878
886 879 def validate(self, obj, value):
887 880 try:
888 881 return str(value)
889 882 except:
890 883 try:
891 884 return unicode(value)
892 885 except:
893 886 self.error(obj, value)
894 887
895 888
896 class Unicode(TraitletType):
897 """A traitlet for unicode strings."""
889 class Unicode(TraitType):
890 """A trait for unicode strings."""
898 891
899 892 evaluate = unicode
900 893 default_value = u''
901 894 info_text = 'a unicode string'
902 895
903 896 def validate(self, obj, value):
904 897 if isinstance(value, unicode):
905 898 return value
906 899 if isinstance(value, str):
907 900 return unicode(value)
908 901 self.error(obj, value)
909 902
910 903
911 904 class CUnicode(Unicode):
912 """A casting version of the unicode traitlet."""
905 """A casting version of the unicode trait."""
913 906
914 907 def validate(self, obj, value):
915 908 try:
916 909 return unicode(value)
917 910 except:
918 911 self.error(obj, value)
919 912
920 913
921 class Bool(TraitletType):
922 """A boolean (True, False) traitlet."""
914 class Bool(TraitType):
915 """A boolean (True, False) trait."""
923 916 evaluate = bool
924 917 default_value = False
925 918 info_text = 'a boolean'
926 919
927 920 def validate(self, obj, value):
928 921 if isinstance(value, bool):
929 922 return value
930 923 self.error(obj, value)
931 924
932 925
933 926 class CBool(Bool):
934 """A casting version of the boolean traitlet."""
927 """A casting version of the boolean trait."""
935 928
936 929 def validate(self, obj, value):
937 930 try:
938 931 return bool(value)
939 932 except:
940 933 self.error(obj, value)
941 934
942 935
943 class Enum(TraitletType):
936 class Enum(TraitType):
944 937 """An enum that whose value must be in a given sequence."""
945 938
946 939 def __init__(self, values, default_value=None, allow_none=True, **metadata):
947 940 self.values = values
948 941 self._allow_none = allow_none
949 942 super(Enum, self).__init__(default_value, **metadata)
950 943
951 944 def validate(self, obj, value):
952 945 if value is None:
953 946 if self._allow_none:
954 947 return value
955 948
956 949 if value in self.values:
957 950 return value
958 951 self.error(obj, value)
959 952
960 953 def info(self):
961 954 """ Returns a description of the trait."""
962 955 result = 'any of ' + repr(self.values)
963 956 if self._allow_none:
964 957 return result + ' or None'
965 958 return result
966 959
967 960 class CaselessStrEnum(Enum):
968 961 """An enum of strings that are caseless in validate."""
969 962
970 963 def validate(self, obj, value):
971 964 if value is None:
972 965 if self._allow_none:
973 966 return value
974 967
975 968 if not isinstance(value, str):
976 969 self.error(obj, value)
977 970
978 971 for v in self.values:
979 972 if v.lower() == value.lower():
980 973 return v
981 974 self.error(obj, value)
982 975
983 976
984 977 class List(Instance):
985 978 """An instance of a Python list."""
986 979
987 980 def __init__(self, default_value=None, allow_none=True, **metadata):
988 """Create a list traitlet type from a list or tuple.
981 """Create a list trait type from a list or tuple.
989 982
990 983 The default value is created by doing ``list(default_value)``,
991 984 which creates a copy of the ``default_value``.
992 985 """
993 986 if default_value is None:
994 987 args = ((),)
995 988 elif isinstance(default_value, SequenceTypes):
996 989 args = (default_value,)
997 990 else:
998 991 raise TypeError('default value of List was %s' % default_value)
999 992
1000 993 super(List,self).__init__(klass=list, args=args,
1001 994 allow_none=allow_none, **metadata)
General Comments 0
You need to be logged in to leave comments. Login now