##// END OF EJS Templates
A number of changes to how traitlets and components work....
Brian Granger -
Show More
@@ -0,0 +1,32 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A simple utility to import something by its string name.
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Functions and classes
20 #-----------------------------------------------------------------------------
21
22 def import_item(name):
23 """Import and return bar given the string foo.bar."""
24 package = '.'.join(name.split('.')[0:-1])
25 obj = name.split('.')[-1]
26 execString = 'from %s import %s' % (package, obj)
27 try:
28 exec execString
29 except SyntaxError:
30 raise ImportError("Invalid class specification: %s" % name)
31 exec 'temp = %s' % obj
32 return temp
@@ -1,104 +1,107 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A context manager for managing things injected into :mod:`__builtin__`.
4 A context manager for managing things injected into :mod:`__builtin__`.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import __builtin__
22 import __builtin__
23
23
24 from IPython.core.component import Component
24 from IPython.core.component import Component
25 from IPython.core.quitter import Quitter
25 from IPython.core.quitter import Quitter
26
26
27 from IPython.utils.traitlets import Instance
28
27 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
28 # Classes and functions
30 # Classes and functions
29 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
30
32
31
33
32 class BuiltinUndefined(object): pass
34 class BuiltinUndefined(object): pass
33 BuiltinUndefined = BuiltinUndefined()
35 BuiltinUndefined = BuiltinUndefined()
34
36
35
37
36 class BuiltinTrap(Component):
38 class BuiltinTrap(Component):
39 shell = Instance('IPython.core.iplib.InteractiveShell')
37
40
38 def __init__(self, parent, name=None, config=None):
41 def __init__(self, parent, name=None, config=None):
39 super(BuiltinTrap, self).__init__(parent, name, config)
42 super(BuiltinTrap, self).__init__(parent, name, config)
40 # Don't just grab parent!!!
43 # Don't just grab parent!!!
41 from IPython.core.iplib import InteractiveShell
44 self.shell = Component.get_instances(root=self.root,
42 self.shell = InteractiveShell.get_instances(root=self.root)[0]
45 klass='IPython.core.iplib.InteractiveShell')[0]
43 self._orig_builtins = {}
46 self._orig_builtins = {}
44
47
45 def __enter__(self):
48 def __enter__(self):
46 self.set()
49 self.set()
47 # I return self, so callers can use add_builtin in a with clause.
50 # I return self, so callers can use add_builtin in a with clause.
48 return self
51 return self
49
52
50 def __exit__(self, type, value, traceback):
53 def __exit__(self, type, value, traceback):
51 self.unset()
54 self.unset()
52 return True
55 return True
53
56
54 def add_builtin(self, key, value):
57 def add_builtin(self, key, value):
55 """Add a builtin and save the original."""
58 """Add a builtin and save the original."""
56 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
59 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
57 self._orig_builtins[key] = orig
60 self._orig_builtins[key] = orig
58 __builtin__.__dict__[key] = value
61 __builtin__.__dict__[key] = value
59
62
60 def remove_builtin(self, key):
63 def remove_builtin(self, key):
61 """Remove an added builtin and re-set the original."""
64 """Remove an added builtin and re-set the original."""
62 try:
65 try:
63 orig = self._orig_builtins.pop(key)
66 orig = self._orig_builtins.pop(key)
64 except KeyError:
67 except KeyError:
65 pass
68 pass
66 else:
69 else:
67 if orig is BuiltinUndefined:
70 if orig is BuiltinUndefined:
68 del __builtin__.__dict__[key]
71 del __builtin__.__dict__[key]
69 else:
72 else:
70 __builtin__.__dict__[key] = orig
73 __builtin__.__dict__[key] = orig
71
74
72 def set(self):
75 def set(self):
73 """Store ipython references in the __builtin__ namespace."""
76 """Store ipython references in the __builtin__ namespace."""
74 self.add_builtin('exit', Quitter(self.shell, 'exit'))
77 self.add_builtin('exit', Quitter(self.shell, 'exit'))
75 self.add_builtin('quit', Quitter(self.shell, 'quit'))
78 self.add_builtin('quit', Quitter(self.shell, 'quit'))
76
79
77 # Recursive reload function
80 # Recursive reload function
78 try:
81 try:
79 from IPython.lib import deepreload
82 from IPython.lib import deepreload
80 if self.shell.deep_reload:
83 if self.shell.deep_reload:
81 self.add_builtin('reload', deepreload.reload)
84 self.add_builtin('reload', deepreload.reload)
82 else:
85 else:
83 self.add_builtin('dreload', deepreload.reload)
86 self.add_builtin('dreload', deepreload.reload)
84 del deepreload
87 del deepreload
85 except ImportError:
88 except ImportError:
86 pass
89 pass
87
90
88 # Keep in the builtins a flag for when IPython is active. We set it
91 # Keep in the builtins a flag for when IPython is active. We set it
89 # with setdefault so that multiple nested IPythons don't clobber one
92 # with setdefault so that multiple nested IPythons don't clobber one
90 # another. Each will increase its value by one upon being activated,
93 # another. Each will increase its value by one upon being activated,
91 # which also gives us a way to determine the nesting level.
94 # which also gives us a way to determine the nesting level.
92 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
95 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
93
96
94 def unset(self):
97 def unset(self):
95 """Remove any builtins which might have been added by add_builtins, or
98 """Remove any builtins which might have been added by add_builtins, or
96 restore overwritten ones to their previous values."""
99 restore overwritten ones to their previous values."""
97 for key in self._orig_builtins.keys():
100 for key in self._orig_builtins.keys():
98 self.remove_builtin(key)
101 self.remove_builtin(key)
99 self._orig_builtins.clear()
102 self._orig_builtins.clear()
100 self._builtins_added = False
103 self._builtins_added = False
101 try:
104 try:
102 del __builtin__.__dict__['__IPYTHON__active']
105 del __builtin__.__dict__['__IPYTHON__active']
103 except KeyError:
106 except KeyError:
104 pass No newline at end of file
107 pass
@@ -1,242 +1,248 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight component system for IPython.
4 A lightweight component system for IPython.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from copy import deepcopy
23 from copy import deepcopy
24 import datetime
24 import datetime
25 from weakref import WeakValueDictionary
25 from weakref import WeakValueDictionary
26
26
27 from IPython.utils.importstring import import_item
27 from IPython.utils.ipstruct import Struct
28 from IPython.utils.ipstruct import Struct
28 from IPython.utils.traitlets import (
29 from IPython.utils.traitlets import (
29 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
30 )
31 )
31
32
32
33
33 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
34 # Helper classes for Components
35 # Helper classes for Components
35 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
36
37
37
38
38 class ComponentError(Exception):
39 class ComponentError(Exception):
39 pass
40 pass
40
41
41 class MetaComponentTracker(type):
42 class MetaComponentTracker(type):
42 """A metaclass that tracks instances of Components and its subclasses."""
43 """A metaclass that tracks instances of Components and its subclasses."""
43
44
44 def __init__(cls, name, bases, d):
45 def __init__(cls, name, bases, d):
45 super(MetaComponentTracker, cls).__init__(name, bases, d)
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
46 cls.__instance_refs = WeakValueDictionary()
47 cls.__instance_refs = WeakValueDictionary()
47 cls.__numcreated = 0
48 cls.__numcreated = 0
48
49
49 def __call__(cls, *args, **kw):
50 def __call__(cls, *args, **kw):
50 """Called when *class* is called (instantiated)!!!
51 """Called when *class* is called (instantiated)!!!
51
52
52 When a Component or subclass is instantiated, this is called and
53 When a Component or subclass is instantiated, this is called and
53 the instance is saved in a WeakValueDictionary for tracking.
54 the instance is saved in a WeakValueDictionary for tracking.
54 """
55 """
55 instance = cls.__new__(cls, *args, **kw)
56 instance = cls.__new__(cls, *args, **kw)
56 # Do this before __init__ is called so get_instances works inside
57 # Do this before __init__ is called so get_instances works inside
57 # __init__ methods!
58 # __init__ methods!
58 for c in cls.__mro__:
59 for c in cls.__mro__:
59 if issubclass(cls, c) and issubclass(c, Component):
60 if issubclass(cls, c) and issubclass(c, Component):
60 c.__numcreated += 1
61 c.__numcreated += 1
61 c.__instance_refs[c.__numcreated] = instance
62 c.__instance_refs[c.__numcreated] = instance
62 if isinstance(instance, cls):
63 if isinstance(instance, cls):
63 cls.__init__(instance, *args, **kw)
64 cls.__init__(instance, *args, **kw)
64
65
65 return instance
66 return instance
66
67
67 def get_instances(cls, name=None, root=None, classname=None):
68 def get_instances(cls, name=None, root=None, klass=None):
68 """Get all instances of cls and its subclasses.
69 """Get all instances of cls and its subclasses.
69
70
70 Parameters
71 Parameters
71 ----------
72 ----------
72 name : str
73 name : str
73 Limit to components with this name.
74 Limit to components with this name.
74 root : Component or subclass
75 root : Component or subclass
75 Limit to components having this root.
76 Limit to components having this root.
76 classname : str
77 klass : class or str
77 The string name of a class to match exactly.
78 Limits to instances of the class or its subclasses. If a str
79 is given ut must be in the form 'foo.bar.MyClass'. The str
80 form of this argument is useful for forward declarations.
78 """
81 """
82 if klass is not None:
83 if isinstance(klass, basestring):
84 klass = import_item(klass)
79 instances = cls.__instance_refs.values()
85 instances = cls.__instance_refs.values()
80 if name is not None:
86 if name is not None:
81 instances = [i for i in instances if i.name == name]
87 instances = [i for i in instances if i.name == name]
82 if classname is not None:
88 if klass is not None:
83 instances = [i for i in instances if i.__class__.__name__ == classname]
89 instances = [i for i in instances if isinstance(i, klass)]
84 if root is not None:
90 if root is not None:
85 instances = [i for i in instances if i.root == root]
91 instances = [i for i in instances if i.root == root]
86 return instances
92 return instances
87
93
88 def get_instances_by_condition(cls, call, name=None, root=None,
94 def get_instances_by_condition(cls, call, name=None, root=None,
89 classname=None):
95 klass=None):
90 """Get all instances of cls, i such that call(i)==True.
96 """Get all instances of cls, i such that call(i)==True.
91
97
92 This also takes the ``name`` and ``root`` and ``classname``
98 This also takes the ``name`` and ``root`` and ``classname``
93 arguments of :meth:`get_instance`
99 arguments of :meth:`get_instance`
94 """
100 """
95 return [i for i in cls.get_instances(name, root, classname) if call(i)]
101 return [i for i in cls.get_instances(name, root, klass) if call(i)]
96
102
97
103
98 class ComponentNameGenerator(object):
104 class ComponentNameGenerator(object):
99 """A Singleton to generate unique component names."""
105 """A Singleton to generate unique component names."""
100
106
101 def __init__(self, prefix):
107 def __init__(self, prefix):
102 self.prefix = prefix
108 self.prefix = prefix
103 self.i = 0
109 self.i = 0
104
110
105 def __call__(self):
111 def __call__(self):
106 count = self.i
112 count = self.i
107 self.i += 1
113 self.i += 1
108 return "%s%s" % (self.prefix, count)
114 return "%s%s" % (self.prefix, count)
109
115
110
116
111 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
117 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
112
118
113
119
114 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
120 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
115 pass
121 pass
116
122
117
123
118 #-----------------------------------------------------------------------------
124 #-----------------------------------------------------------------------------
119 # Component implementation
125 # Component implementation
120 #-----------------------------------------------------------------------------
126 #-----------------------------------------------------------------------------
121
127
122
128
123 class Component(HasTraitlets):
129 class Component(HasTraitlets):
124
130
125 __metaclass__ = MetaComponent
131 __metaclass__ = MetaComponent
126
132
127 # Traitlets are fun!
133 # Traitlets are fun!
128 config = Instance(Struct,(),{})
134 config = Instance(Struct,(),{})
129 parent = This()
135 parent = This()
130 root = This()
136 root = This()
131 created = None
137 created = None
132
138
133 def __init__(self, parent, name=None, config=None):
139 def __init__(self, parent, name=None, config=None):
134 """Create a component given a parent and possibly and name and config.
140 """Create a component given a parent and possibly and name and config.
135
141
136 Parameters
142 Parameters
137 ----------
143 ----------
138 parent : Component subclass
144 parent : Component subclass
139 The parent in the component graph. The parent is used
145 The parent in the component graph. The parent is used
140 to get the root of the component graph.
146 to get the root of the component graph.
141 name : str
147 name : str
142 The unique name of the component. If empty, then a unique
148 The unique name of the component. If empty, then a unique
143 one will be autogenerated.
149 one will be autogenerated.
144 config : Struct
150 config : Struct
145 If this is empty, self.config = parent.config, otherwise
151 If this is empty, self.config = parent.config, otherwise
146 self.config = config and root.config is ignored. This argument
152 self.config = config and root.config is ignored. This argument
147 should only be used to *override* the automatic inheritance of
153 should only be used to *override* the automatic inheritance of
148 parent.config. If a caller wants to modify parent.config
154 parent.config. If a caller wants to modify parent.config
149 (not override), the caller should make a copy and change
155 (not override), the caller should make a copy and change
150 attributes and then pass the copy to this argument.
156 attributes and then pass the copy to this argument.
151
157
152 Notes
158 Notes
153 -----
159 -----
154 Subclasses of Component must call the :meth:`__init__` method of
160 Subclasses of Component must call the :meth:`__init__` method of
155 :class:`Component` *before* doing anything else and using
161 :class:`Component` *before* doing anything else and using
156 :func:`super`::
162 :func:`super`::
157
163
158 class MyComponent(Component):
164 class MyComponent(Component):
159 def __init__(self, parent, name=None, config=None):
165 def __init__(self, parent, name=None, config=None):
160 super(MyComponent, self).__init__(parent, name, config)
166 super(MyComponent, self).__init__(parent, name, config)
161 # Then any other code you need to finish initialization.
167 # Then any other code you need to finish initialization.
162
168
163 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
169 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
164 attributes are handled properly.
170 attributes are handled properly.
165 """
171 """
166 super(Component, self).__init__()
172 super(Component, self).__init__()
167 self._children = []
173 self._children = []
168 if name is None:
174 if name is None:
169 self.name = ComponentNameGenerator()
175 self.name = ComponentNameGenerator()
170 else:
176 else:
171 self.name = name
177 self.name = name
172 self.root = self # This is the default, it is set when parent is set
178 self.root = self # This is the default, it is set when parent is set
173 self.parent = parent
179 self.parent = parent
174 if config is not None:
180 if config is not None:
175 self.config = deepcopy(config)
181 self.config = deepcopy(config)
176 else:
182 else:
177 if self.parent is not None:
183 if self.parent is not None:
178 self.config = deepcopy(self.parent.config)
184 self.config = deepcopy(self.parent.config)
179
185
180 self.created = datetime.datetime.now()
186 self.created = datetime.datetime.now()
181
187
182 #-------------------------------------------------------------------------
188 #-------------------------------------------------------------------------
183 # Static traitlet notifiations
189 # Static traitlet notifiations
184 #-------------------------------------------------------------------------
190 #-------------------------------------------------------------------------
185
191
186 def _parent_changed(self, name, old, new):
192 def _parent_changed(self, name, old, new):
187 if old is not None:
193 if old is not None:
188 old._remove_child(self)
194 old._remove_child(self)
189 if new is not None:
195 if new is not None:
190 new._add_child(self)
196 new._add_child(self)
191
197
192 if new is None:
198 if new is None:
193 self.root = self
199 self.root = self
194 else:
200 else:
195 self.root = new.root
201 self.root = new.root
196
202
197 def _root_changed(self, name, old, new):
203 def _root_changed(self, name, old, new):
198 if self.parent is None:
204 if self.parent is None:
199 if not (new is self):
205 if not (new is self):
200 raise ComponentError("Root not self, but parent is None.")
206 raise ComponentError("Root not self, but parent is None.")
201 else:
207 else:
202 if not self.parent.root is new:
208 if not self.parent.root is new:
203 raise ComponentError("Error in setting the root attribute: "
209 raise ComponentError("Error in setting the root attribute: "
204 "root != parent.root")
210 "root != parent.root")
205
211
206 def _config_changed(self, name, old, new):
212 def _config_changed(self, name, old, new):
207 """Update all the class traits having a config_key with the config.
213 """Update all the class traits having a config_key with the config.
208
214
209 For any class traitlet with a ``config_key`` metadata attribute, we
215 For any class traitlet with a ``config_key`` metadata attribute, we
210 update the traitlet with the value of the corresponding config entry.
216 update the traitlet with the value of the corresponding config entry.
211
217
212 In the future, we might want to do a pop here so stale config info
218 In the future, we might want to do a pop here so stale config info
213 is not passed onto children.
219 is not passed onto children.
214 """
220 """
215 # Get all traitlets with a config_key metadata entry
221 # Get all traitlets with a config_key metadata entry
216 traitlets = self.traitlets('config_key')
222 traitlets = self.traitlets('config_key')
217 for k, v in traitlets.items():
223 for k, v in traitlets.items():
218 try:
224 try:
219 config_value = new[v.get_metadata('config_key')]
225 config_value = new[v.get_metadata('config_key')]
220 except KeyError:
226 except KeyError:
221 pass
227 pass
222 else:
228 else:
223 setattr(self, k, config_value)
229 setattr(self, k, config_value)
224
230
225 @property
231 @property
226 def children(self):
232 def children(self):
227 """A list of all my child components."""
233 """A list of all my child components."""
228 return self._children
234 return self._children
229
235
230 def _remove_child(self, child):
236 def _remove_child(self, child):
231 """A private method for removing children components."""
237 """A private method for removing children components."""
232 if child in self._children:
238 if child in self._children:
233 index = self._children.index(child)
239 index = self._children.index(child)
234 del self._children[index]
240 del self._children[index]
235
241
236 def _add_child(self, child):
242 def _add_child(self, child):
237 """A private method for adding children components."""
243 """A private method for adding children components."""
238 if child not in self._children:
244 if child not in self._children:
239 self._children.append(child)
245 self._children.append(child)
240
246
241 def __repr__(self):
247 def __repr__(self):
242 return "<Component('%s')>" % self.name
248 return "<Component('%s')>" % self.name
@@ -1,2962 +1,2961 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Main IPython Component
3 Main IPython Component
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from __future__ import with_statement
19 from __future__ import with_statement
20
20
21 import __main__
21 import __main__
22 import __builtin__
22 import __builtin__
23 import StringIO
23 import StringIO
24 import bdb
24 import bdb
25 import codeop
25 import codeop
26 import exceptions
26 import exceptions
27 import glob
27 import glob
28 import keyword
28 import keyword
29 import new
29 import new
30 import os
30 import os
31 import re
31 import re
32 import shutil
32 import shutil
33 import string
33 import string
34 import sys
34 import sys
35 import tempfile
35 import tempfile
36
36
37 from IPython.core import ultratb
37 from IPython.core import ultratb
38 from IPython.core import debugger, oinspect
38 from IPython.core import debugger, oinspect
39 from IPython.core import shadowns
39 from IPython.core import shadowns
40 from IPython.core import history as ipcorehist
40 from IPython.core import history as ipcorehist
41 from IPython.core import prefilter
41 from IPython.core import prefilter
42 from IPython.core.autocall import IPyAutocall
42 from IPython.core.autocall import IPyAutocall
43 from IPython.core.builtin_trap import BuiltinTrap
43 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.logger import Logger
45 from IPython.core.logger import Logger
46 from IPython.core.magic import Magic
46 from IPython.core.magic import Magic
47 from IPython.core.prompts import CachedOutput
47 from IPython.core.prompts import CachedOutput
48 from IPython.core.page import page
48 from IPython.core.page import page
49 from IPython.core.component import Component
49 from IPython.core.component import Component
50 from IPython.core.oldusersetup import user_setup
50 from IPython.core.oldusersetup import user_setup
51 from IPython.core.usage import interactive_usage, default_banner
51 from IPython.core.usage import interactive_usage, default_banner
52 from IPython.core.error import TryNext, UsageError
52 from IPython.core.error import TryNext, UsageError
53
53
54 from IPython.extensions import pickleshare
54 from IPython.extensions import pickleshare
55 from IPython.external.Itpl import ItplNS
55 from IPython.external.Itpl import ItplNS
56 from IPython.lib.backgroundjobs import BackgroundJobManager
56 from IPython.lib.backgroundjobs import BackgroundJobManager
57 from IPython.utils.ipstruct import Struct
57 from IPython.utils.ipstruct import Struct
58 from IPython.utils import PyColorize
58 from IPython.utils import PyColorize
59 from IPython.utils.genutils import *
59 from IPython.utils.genutils import *
60 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.strdispatch import StrDispatch
61 from IPython.utils.platutils import toggle_set_term_title, set_term_title
61 from IPython.utils.platutils import toggle_set_term_title, set_term_title
62
62
63 from IPython.utils.traitlets import (
63 from IPython.utils.traitlets import (
64 Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode
64 Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode
65 )
65 )
66
66
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68 # Globals
68 # Globals
69 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
70
70
71
71
72 # store the builtin raw_input globally, and use this always, in case user code
72 # store the builtin raw_input globally, and use this always, in case user code
73 # overwrites it (like wx.py.PyShell does)
73 # overwrites it (like wx.py.PyShell does)
74 raw_input_original = raw_input
74 raw_input_original = raw_input
75
75
76 # compiled regexps for autoindent management
76 # compiled regexps for autoindent management
77 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
77 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
78
78
79
79
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81 # Utilities
81 # Utilities
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83
83
84
84
85 ini_spaces_re = re.compile(r'^(\s+)')
85 ini_spaces_re = re.compile(r'^(\s+)')
86
86
87
87
88 def num_ini_spaces(strng):
88 def num_ini_spaces(strng):
89 """Return the number of initial spaces in a string"""
89 """Return the number of initial spaces in a string"""
90
90
91 ini_spaces = ini_spaces_re.match(strng)
91 ini_spaces = ini_spaces_re.match(strng)
92 if ini_spaces:
92 if ini_spaces:
93 return ini_spaces.end()
93 return ini_spaces.end()
94 else:
94 else:
95 return 0
95 return 0
96
96
97
97
98 def softspace(file, newvalue):
98 def softspace(file, newvalue):
99 """Copied from code.py, to remove the dependency"""
99 """Copied from code.py, to remove the dependency"""
100
100
101 oldvalue = 0
101 oldvalue = 0
102 try:
102 try:
103 oldvalue = file.softspace
103 oldvalue = file.softspace
104 except AttributeError:
104 except AttributeError:
105 pass
105 pass
106 try:
106 try:
107 file.softspace = newvalue
107 file.softspace = newvalue
108 except (AttributeError, TypeError):
108 except (AttributeError, TypeError):
109 # "attribute-less object" or "read-only attributes"
109 # "attribute-less object" or "read-only attributes"
110 pass
110 pass
111 return oldvalue
111 return oldvalue
112
112
113
113
114 class SpaceInInput(exceptions.Exception): pass
114 class SpaceInInput(exceptions.Exception): pass
115
115
116 class Bunch: pass
116 class Bunch: pass
117
117
118 class InputList(list):
118 class InputList(list):
119 """Class to store user input.
119 """Class to store user input.
120
120
121 It's basically a list, but slices return a string instead of a list, thus
121 It's basically a list, but slices return a string instead of a list, thus
122 allowing things like (assuming 'In' is an instance):
122 allowing things like (assuming 'In' is an instance):
123
123
124 exec In[4:7]
124 exec In[4:7]
125
125
126 or
126 or
127
127
128 exec In[5:9] + In[14] + In[21:25]"""
128 exec In[5:9] + In[14] + In[21:25]"""
129
129
130 def __getslice__(self,i,j):
130 def __getslice__(self,i,j):
131 return ''.join(list.__getslice__(self,i,j))
131 return ''.join(list.__getslice__(self,i,j))
132
132
133
133
134 class SyntaxTB(ultratb.ListTB):
134 class SyntaxTB(ultratb.ListTB):
135 """Extension which holds some state: the last exception value"""
135 """Extension which holds some state: the last exception value"""
136
136
137 def __init__(self,color_scheme = 'NoColor'):
137 def __init__(self,color_scheme = 'NoColor'):
138 ultratb.ListTB.__init__(self,color_scheme)
138 ultratb.ListTB.__init__(self,color_scheme)
139 self.last_syntax_error = None
139 self.last_syntax_error = None
140
140
141 def __call__(self, etype, value, elist):
141 def __call__(self, etype, value, elist):
142 self.last_syntax_error = value
142 self.last_syntax_error = value
143 ultratb.ListTB.__call__(self,etype,value,elist)
143 ultratb.ListTB.__call__(self,etype,value,elist)
144
144
145 def clear_err_state(self):
145 def clear_err_state(self):
146 """Return the current error state and clear it"""
146 """Return the current error state and clear it"""
147 e = self.last_syntax_error
147 e = self.last_syntax_error
148 self.last_syntax_error = None
148 self.last_syntax_error = None
149 return e
149 return e
150
150
151
151
152 def get_default_editor():
152 def get_default_editor():
153 try:
153 try:
154 ed = os.environ['EDITOR']
154 ed = os.environ['EDITOR']
155 except KeyError:
155 except KeyError:
156 if os.name == 'posix':
156 if os.name == 'posix':
157 ed = 'vi' # the only one guaranteed to be there!
157 ed = 'vi' # the only one guaranteed to be there!
158 else:
158 else:
159 ed = 'notepad' # same in Windows!
159 ed = 'notepad' # same in Windows!
160 return ed
160 return ed
161
161
162
162
163 class SeparateStr(Str):
163 class SeparateStr(Str):
164 """A Str subclass to validate separate_in, separate_out, etc.
164 """A Str subclass to validate separate_in, separate_out, etc.
165
165
166 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
166 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
167 """
167 """
168
168
169 def validate(self, obj, value):
169 def validate(self, obj, value):
170 if value == '0': value = ''
170 if value == '0': value = ''
171 value = value.replace('\\n','\n')
171 value = value.replace('\\n','\n')
172 return super(SeparateStr, self).validate(obj, value)
172 return super(SeparateStr, self).validate(obj, value)
173
173
174
174
175 #-----------------------------------------------------------------------------
175 #-----------------------------------------------------------------------------
176 # Main IPython class
176 # Main IPython class
177 #-----------------------------------------------------------------------------
177 #-----------------------------------------------------------------------------
178
178
179
179
180 class InteractiveShell(Component, Magic):
180 class InteractiveShell(Component, Magic):
181 """An enhanced, interactive shell for Python."""
181 """An enhanced, interactive shell for Python."""
182
182
183 autocall = Enum((0,1,2), config_key='AUTOCALL')
183 autocall = Enum((0,1,2), config_key='AUTOCALL')
184 autoedit_syntax = CBool(False, config_key='AUTOEDIT_SYNTAX')
184 autoedit_syntax = CBool(False, config_key='AUTOEDIT_SYNTAX')
185 autoindent = CBool(True, config_key='AUTOINDENT')
185 autoindent = CBool(True, config_key='AUTOINDENT')
186 automagic = CBool(True, config_key='AUTOMAGIC')
186 automagic = CBool(True, config_key='AUTOMAGIC')
187 display_banner = CBool(True, config_key='DISPLAY_BANNER')
187 display_banner = CBool(True, config_key='DISPLAY_BANNER')
188 banner = Str('')
188 banner = Str('')
189 banner1 = Str(default_banner, config_key='BANNER1')
189 banner1 = Str(default_banner, config_key='BANNER1')
190 banner2 = Str('', config_key='BANNER2')
190 banner2 = Str('', config_key='BANNER2')
191 c = Str('', config_key='C')
191 c = Str('', config_key='C')
192 cache_size = Int(1000, config_key='CACHE_SIZE')
192 cache_size = Int(1000, config_key='CACHE_SIZE')
193 classic = CBool(False, config_key='CLASSIC')
193 classic = CBool(False, config_key='CLASSIC')
194 color_info = CBool(True, config_key='COLOR_INFO')
194 color_info = CBool(True, config_key='COLOR_INFO')
195 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
195 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
196 default_value='LightBG', config_key='COLORS')
196 default_value='LightBG', config_key='COLORS')
197 confirm_exit = CBool(True, config_key='CONFIRM_EXIT')
197 confirm_exit = CBool(True, config_key='CONFIRM_EXIT')
198 debug = CBool(False, config_key='DEBUG')
198 debug = CBool(False, config_key='DEBUG')
199 deep_reload = CBool(False, config_key='DEEP_RELOAD')
199 deep_reload = CBool(False, config_key='DEEP_RELOAD')
200 embedded = CBool(False)
200 embedded = CBool(False)
201 embedded_active = CBool(False)
201 embedded_active = CBool(False)
202 editor = Str(get_default_editor(), config_key='EDITOR')
202 editor = Str(get_default_editor(), config_key='EDITOR')
203 filename = Str("<ipython console>")
203 filename = Str("<ipython console>")
204 interactive = CBool(False, config_key='INTERACTIVE')
204 interactive = CBool(False, config_key='INTERACTIVE')
205 ipythondir= Unicode('', config_key='IPYTHONDIR') # Set to os.getcwd() in __init__
205 ipythondir= Unicode('', config_key='IPYTHONDIR') # Set to os.getcwd() in __init__
206 logstart = CBool(False, config_key='LOGSTART')
206 logstart = CBool(False, config_key='LOGSTART')
207 logfile = Str('', config_key='LOGFILE')
207 logfile = Str('', config_key='LOGFILE')
208 logplay = Str('', config_key='LOGPLAY')
208 logplay = Str('', config_key='LOGPLAY')
209 multi_line_specials = CBool(True, config_key='MULTI_LINE_SPECIALS')
209 multi_line_specials = CBool(True, config_key='MULTI_LINE_SPECIALS')
210 object_info_string_level = Enum((0,1,2), default_value=0,
210 object_info_string_level = Enum((0,1,2), default_value=0,
211 config_keys='OBJECT_INFO_STRING_LEVEL')
211 config_keys='OBJECT_INFO_STRING_LEVEL')
212 pager = Str('less', config_key='PAGER')
212 pager = Str('less', config_key='PAGER')
213 pdb = CBool(False, config_key='PDB')
213 pdb = CBool(False, config_key='PDB')
214 pprint = CBool(True, config_key='PPRINT')
214 pprint = CBool(True, config_key='PPRINT')
215 profile = Str('', config_key='PROFILE')
215 profile = Str('', config_key='PROFILE')
216 prompt_in1 = Str('In [\\#]: ', config_key='PROMPT_IN1')
216 prompt_in1 = Str('In [\\#]: ', config_key='PROMPT_IN1')
217 prompt_in2 = Str(' .\\D.: ', config_key='PROMPT_IN2')
217 prompt_in2 = Str(' .\\D.: ', config_key='PROMPT_IN2')
218 prompt_out = Str('Out[\\#]: ', config_key='PROMPT_OUT1')
218 prompt_out = Str('Out[\\#]: ', config_key='PROMPT_OUT1')
219 prompts_pad_left = CBool(True, config_key='PROMPTS_PAD_LEFT')
219 prompts_pad_left = CBool(True, config_key='PROMPTS_PAD_LEFT')
220 quiet = CBool(False, config_key='QUIET')
220 quiet = CBool(False, config_key='QUIET')
221
221
222 readline_use = CBool(True, config_key='READLINE_USE')
222 readline_use = CBool(True, config_key='READLINE_USE')
223 readline_merge_completions = CBool(True,
223 readline_merge_completions = CBool(True,
224 config_key='READLINE_MERGE_COMPLETIONS')
224 config_key='READLINE_MERGE_COMPLETIONS')
225 readline_omit__names = Enum((0,1,2), default_value=0,
225 readline_omit__names = Enum((0,1,2), default_value=0,
226 config_key='READLINE_OMIT_NAMES')
226 config_key='READLINE_OMIT_NAMES')
227 readline_remove_delims = Str('-/~', config_key='READLINE_REMOVE_DELIMS')
227 readline_remove_delims = Str('-/~', config_key='READLINE_REMOVE_DELIMS')
228 readline_parse_and_bind = List([
228 readline_parse_and_bind = List([
229 'tab: complete',
229 'tab: complete',
230 '"\C-l": possible-completions',
230 '"\C-l": possible-completions',
231 'set show-all-if-ambiguous on',
231 'set show-all-if-ambiguous on',
232 '"\C-o": tab-insert',
232 '"\C-o": tab-insert',
233 '"\M-i": " "',
233 '"\M-i": " "',
234 '"\M-o": "\d\d\d\d"',
234 '"\M-o": "\d\d\d\d"',
235 '"\M-I": "\d\d\d\d"',
235 '"\M-I": "\d\d\d\d"',
236 '"\C-r": reverse-search-history',
236 '"\C-r": reverse-search-history',
237 '"\C-s": forward-search-history',
237 '"\C-s": forward-search-history',
238 '"\C-p": history-search-backward',
238 '"\C-p": history-search-backward',
239 '"\C-n": history-search-forward',
239 '"\C-n": history-search-forward',
240 '"\e[A": history-search-backward',
240 '"\e[A": history-search-backward',
241 '"\e[B": history-search-forward',
241 '"\e[B": history-search-forward',
242 '"\C-k": kill-line',
242 '"\C-k": kill-line',
243 '"\C-u": unix-line-discard',
243 '"\C-u": unix-line-discard',
244 ], allow_none=False, config_key='READLINE_PARSE_AND_BIND'
244 ], allow_none=False, config_key='READLINE_PARSE_AND_BIND'
245 )
245 )
246
246
247 screen_length = Int(0, config_key='SCREEN_LENGTH')
247 screen_length = Int(0, config_key='SCREEN_LENGTH')
248
248
249 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
249 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
250 separate_in = SeparateStr('\n', config_key='SEPARATE_IN')
250 separate_in = SeparateStr('\n', config_key='SEPARATE_IN')
251 separate_out = SeparateStr('', config_key='SEPARATE_OUT')
251 separate_out = SeparateStr('', config_key='SEPARATE_OUT')
252 separate_out2 = SeparateStr('', config_key='SEPARATE_OUT2')
252 separate_out2 = SeparateStr('', config_key='SEPARATE_OUT2')
253
253
254 system_header = Str('IPython system call: ', config_key='SYSTEM_HEADER')
254 system_header = Str('IPython system call: ', config_key='SYSTEM_HEADER')
255 system_verbose = CBool(False, config_key='SYSTEM_VERBOSE')
255 system_verbose = CBool(False, config_key='SYSTEM_VERBOSE')
256 term_title = CBool(False, config_key='TERM_TITLE')
256 term_title = CBool(False, config_key='TERM_TITLE')
257 wildcards_case_sensitive = CBool(True, config_key='WILDCARDS_CASE_SENSITIVE')
257 wildcards_case_sensitive = CBool(True, config_key='WILDCARDS_CASE_SENSITIVE')
258 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
258 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
259 default_value='Context', config_key='XMODE')
259 default_value='Context', config_key='XMODE')
260
260
261 alias = List(allow_none=False, config_key='ALIAS')
261 alias = List(allow_none=False, config_key='ALIAS')
262 autoexec = List(allow_none=False)
262 autoexec = List(allow_none=False)
263
263
264 # class attribute to indicate whether the class supports threads or not.
264 # class attribute to indicate whether the class supports threads or not.
265 # Subclasses with thread support should override this as needed.
265 # Subclasses with thread support should override this as needed.
266 isthreaded = False
266 isthreaded = False
267
267
268 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
268 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
269 user_ns=None, user_global_ns=None,
269 user_ns=None, user_global_ns=None,
270 banner1=None, banner2=None,
270 banner1=None, banner2=None,
271 custom_exceptions=((),None)):
271 custom_exceptions=((),None)):
272
272
273 # This is where traitlets with a config_key argument are updated
273 # This is where traitlets with a config_key argument are updated
274 # from the values on config.
274 # from the values on config.
275 super(InteractiveShell, self).__init__(parent, config=config, name='__IP')
275 super(InteractiveShell, self).__init__(parent, config=config, name='__IP')
276
276
277 # These are relatively independent and stateless
277 # These are relatively independent and stateless
278 self.init_ipythondir(ipythondir)
278 self.init_ipythondir(ipythondir)
279 self.init_instance_attrs()
279 self.init_instance_attrs()
280 self.init_term_title()
280 self.init_term_title()
281 self.init_usage(usage)
281 self.init_usage(usage)
282 self.init_banner(banner1, banner2)
282 self.init_banner(banner1, banner2)
283
283
284 # Create namespaces (user_ns, user_global_ns, alias_table, etc.)
284 # Create namespaces (user_ns, user_global_ns, alias_table, etc.)
285 self.init_create_namespaces(user_ns, user_global_ns)
285 self.init_create_namespaces(user_ns, user_global_ns)
286 # This has to be done after init_create_namespaces because it uses
286 # This has to be done after init_create_namespaces because it uses
287 # something in self.user_ns, but before init_sys_modules, which
287 # something in self.user_ns, but before init_sys_modules, which
288 # is the first thing to modify sys.
288 # is the first thing to modify sys.
289 self.save_sys_module_state()
289 self.save_sys_module_state()
290 self.init_sys_modules()
290 self.init_sys_modules()
291
291
292 self.init_history()
292 self.init_history()
293 self.init_encoding()
293 self.init_encoding()
294 self.init_handlers()
294 self.init_handlers()
295
295
296 Magic.__init__(self, self)
296 Magic.__init__(self, self)
297
297
298 self.init_syntax_highlighting()
298 self.init_syntax_highlighting()
299 self.init_hooks()
299 self.init_hooks()
300 self.init_pushd_popd_magic()
300 self.init_pushd_popd_magic()
301 self.init_traceback_handlers(custom_exceptions)
301 self.init_traceback_handlers(custom_exceptions)
302 self.init_user_ns()
302 self.init_user_ns()
303 self.init_logger()
303 self.init_logger()
304 self.init_aliases()
304 self.init_aliases()
305 self.init_builtins()
305 self.init_builtins()
306
306
307 # pre_config_initialization
307 # pre_config_initialization
308 self.init_shadow_hist()
308 self.init_shadow_hist()
309
309
310 # The next section should contain averything that was in ipmaker.
310 # The next section should contain averything that was in ipmaker.
311 self.init_logstart()
311 self.init_logstart()
312
312
313 # The following was in post_config_initialization
313 # The following was in post_config_initialization
314 self.init_inspector()
314 self.init_inspector()
315 self.init_readline()
315 self.init_readline()
316 self.init_prompts()
316 self.init_prompts()
317 self.init_displayhook()
317 self.init_displayhook()
318 self.init_reload_doctest()
318 self.init_reload_doctest()
319 self.init_magics()
319 self.init_magics()
320 self.init_pdb()
320 self.init_pdb()
321 self.hooks.late_startup_hook()
321 self.hooks.late_startup_hook()
322
322
323 def cleanup(self):
323 def cleanup(self):
324 self.restore_sys_module_state()
324 self.restore_sys_module_state()
325
325
326 #-------------------------------------------------------------------------
326 #-------------------------------------------------------------------------
327 # Traitlet changed handlers
327 # Traitlet changed handlers
328 #-------------------------------------------------------------------------
328 #-------------------------------------------------------------------------
329
329
330 def _banner1_changed(self):
330 def _banner1_changed(self):
331 self.compute_banner()
331 self.compute_banner()
332
332
333 def _banner2_changed(self):
333 def _banner2_changed(self):
334 self.compute_banner()
334 self.compute_banner()
335
335
336 @property
336 @property
337 def usable_screen_length(self):
337 def usable_screen_length(self):
338 if self.screen_length == 0:
338 if self.screen_length == 0:
339 return 0
339 return 0
340 else:
340 else:
341 num_lines_bot = self.separate_in.count('\n')+1
341 num_lines_bot = self.separate_in.count('\n')+1
342 return self.screen_length - num_lines_bot
342 return self.screen_length - num_lines_bot
343
343
344 def _term_title_changed(self, name, new_value):
344 def _term_title_changed(self, name, new_value):
345 self.init_term_title()
345 self.init_term_title()
346
346
347 #-------------------------------------------------------------------------
347 #-------------------------------------------------------------------------
348 # init_* methods called by __init__
348 # init_* methods called by __init__
349 #-------------------------------------------------------------------------
349 #-------------------------------------------------------------------------
350
350
351 def init_ipythondir(self, ipythondir):
351 def init_ipythondir(self, ipythondir):
352 if ipythondir is not None:
352 if ipythondir is not None:
353 self.ipythondir = ipythondir
353 self.ipythondir = ipythondir
354 self.config.IPYTHONDIR = self.ipythondir
354 self.config.IPYTHONDIR = self.ipythondir
355 return
355 return
356
356
357 if hasattr(self.config, 'IPYTHONDIR'):
357 if hasattr(self.config, 'IPYTHONDIR'):
358 self.ipythondir = self.config.IPYTHONDIR
358 self.ipythondir = self.config.IPYTHONDIR
359 if not hasattr(self.config, 'IPYTHONDIR'):
359 if not hasattr(self.config, 'IPYTHONDIR'):
360 # cdw is always defined
360 # cdw is always defined
361 self.ipythondir = os.getcwd()
361 self.ipythondir = os.getcwd()
362
362
363 # The caller must make sure that ipythondir exists. We should
363 # The caller must make sure that ipythondir exists. We should
364 # probably handle this using a Dir traitlet.
364 # probably handle this using a Dir traitlet.
365 if not os.path.isdir(self.ipythondir):
365 if not os.path.isdir(self.ipythondir):
366 raise IOError('IPython dir does not exist: %s' % self.ipythondir)
366 raise IOError('IPython dir does not exist: %s' % self.ipythondir)
367
367
368 # All children can just read this
368 # All children can just read this
369 self.config.IPYTHONDIR = self.ipythondir
369 self.config.IPYTHONDIR = self.ipythondir
370
370
371 def init_instance_attrs(self):
371 def init_instance_attrs(self):
372 self.jobs = BackgroundJobManager()
372 self.jobs = BackgroundJobManager()
373 self.more = False
373 self.more = False
374
374
375 # command compiler
375 # command compiler
376 self.compile = codeop.CommandCompiler()
376 self.compile = codeop.CommandCompiler()
377
377
378 # User input buffer
378 # User input buffer
379 self.buffer = []
379 self.buffer = []
380
380
381 # Make an empty namespace, which extension writers can rely on both
381 # Make an empty namespace, which extension writers can rely on both
382 # existing and NEVER being used by ipython itself. This gives them a
382 # existing and NEVER being used by ipython itself. This gives them a
383 # convenient location for storing additional information and state
383 # convenient location for storing additional information and state
384 # their extensions may require, without fear of collisions with other
384 # their extensions may require, without fear of collisions with other
385 # ipython names that may develop later.
385 # ipython names that may develop later.
386 self.meta = Struct()
386 self.meta = Struct()
387
387
388 # Object variable to store code object waiting execution. This is
388 # Object variable to store code object waiting execution. This is
389 # used mainly by the multithreaded shells, but it can come in handy in
389 # used mainly by the multithreaded shells, but it can come in handy in
390 # other situations. No need to use a Queue here, since it's a single
390 # other situations. No need to use a Queue here, since it's a single
391 # item which gets cleared once run.
391 # item which gets cleared once run.
392 self.code_to_run = None
392 self.code_to_run = None
393
393
394 # Flag to mark unconditional exit
394 # Flag to mark unconditional exit
395 self.exit_now = False
395 self.exit_now = False
396
396
397 # Temporary files used for various purposes. Deleted at exit.
397 # Temporary files used for various purposes. Deleted at exit.
398 self.tempfiles = []
398 self.tempfiles = []
399
399
400 # Keep track of readline usage (later set by init_readline)
400 # Keep track of readline usage (later set by init_readline)
401 self.has_readline = False
401 self.has_readline = False
402
402
403 # keep track of where we started running (mainly for crash post-mortem)
403 # keep track of where we started running (mainly for crash post-mortem)
404 # This is not being used anywhere currently.
404 # This is not being used anywhere currently.
405 self.starting_dir = os.getcwd()
405 self.starting_dir = os.getcwd()
406
406
407 # Indentation management
407 # Indentation management
408 self.indent_current_nsp = 0
408 self.indent_current_nsp = 0
409
409
410 def init_term_title(self):
410 def init_term_title(self):
411 # Enable or disable the terminal title.
411 # Enable or disable the terminal title.
412 if self.term_title:
412 if self.term_title:
413 toggle_set_term_title(True)
413 toggle_set_term_title(True)
414 set_term_title('IPython: ' + abbrev_cwd())
414 set_term_title('IPython: ' + abbrev_cwd())
415 else:
415 else:
416 toggle_set_term_title(False)
416 toggle_set_term_title(False)
417
417
418 def init_usage(self, usage=None):
418 def init_usage(self, usage=None):
419 if usage is None:
419 if usage is None:
420 self.usage = interactive_usage
420 self.usage = interactive_usage
421 else:
421 else:
422 self.usage = usage
422 self.usage = usage
423
423
424 def init_banner(self, banner1, banner2):
424 def init_banner(self, banner1, banner2):
425 if self.c: # regular python doesn't print the banner with -c
425 if self.c: # regular python doesn't print the banner with -c
426 self.display_banner = False
426 self.display_banner = False
427 if banner1 is not None:
427 if banner1 is not None:
428 self.banner1 = banner1
428 self.banner1 = banner1
429 if banner2 is not None:
429 if banner2 is not None:
430 self.banner2 = banner2
430 self.banner2 = banner2
431 self.compute_banner()
431 self.compute_banner()
432
432
433 def compute_banner(self):
433 def compute_banner(self):
434 self.banner = self.banner1 + '\n'
434 self.banner = self.banner1 + '\n'
435 if self.profile:
435 if self.profile:
436 self.banner += '\nIPython profile: %s\n' % self.profile
436 self.banner += '\nIPython profile: %s\n' % self.profile
437 if self.banner2:
437 if self.banner2:
438 self.banner += '\n' + self.banner2 + '\n'
438 self.banner += '\n' + self.banner2 + '\n'
439
439
440 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
440 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
441 # Create the namespace where the user will operate. user_ns is
441 # Create the namespace where the user will operate. user_ns is
442 # normally the only one used, and it is passed to the exec calls as
442 # normally the only one used, and it is passed to the exec calls as
443 # the locals argument. But we do carry a user_global_ns namespace
443 # the locals argument. But we do carry a user_global_ns namespace
444 # given as the exec 'globals' argument, This is useful in embedding
444 # given as the exec 'globals' argument, This is useful in embedding
445 # situations where the ipython shell opens in a context where the
445 # situations where the ipython shell opens in a context where the
446 # distinction between locals and globals is meaningful. For
446 # distinction between locals and globals is meaningful. For
447 # non-embedded contexts, it is just the same object as the user_ns dict.
447 # non-embedded contexts, it is just the same object as the user_ns dict.
448
448
449 # FIXME. For some strange reason, __builtins__ is showing up at user
449 # FIXME. For some strange reason, __builtins__ is showing up at user
450 # level as a dict instead of a module. This is a manual fix, but I
450 # level as a dict instead of a module. This is a manual fix, but I
451 # should really track down where the problem is coming from. Alex
451 # should really track down where the problem is coming from. Alex
452 # Schmolck reported this problem first.
452 # Schmolck reported this problem first.
453
453
454 # A useful post by Alex Martelli on this topic:
454 # A useful post by Alex Martelli on this topic:
455 # Re: inconsistent value from __builtins__
455 # Re: inconsistent value from __builtins__
456 # Von: Alex Martelli <aleaxit@yahoo.com>
456 # Von: Alex Martelli <aleaxit@yahoo.com>
457 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
457 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
458 # Gruppen: comp.lang.python
458 # Gruppen: comp.lang.python
459
459
460 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
460 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
461 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
461 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
462 # > <type 'dict'>
462 # > <type 'dict'>
463 # > >>> print type(__builtins__)
463 # > >>> print type(__builtins__)
464 # > <type 'module'>
464 # > <type 'module'>
465 # > Is this difference in return value intentional?
465 # > Is this difference in return value intentional?
466
466
467 # Well, it's documented that '__builtins__' can be either a dictionary
467 # Well, it's documented that '__builtins__' can be either a dictionary
468 # or a module, and it's been that way for a long time. Whether it's
468 # or a module, and it's been that way for a long time. Whether it's
469 # intentional (or sensible), I don't know. In any case, the idea is
469 # intentional (or sensible), I don't know. In any case, the idea is
470 # that if you need to access the built-in namespace directly, you
470 # that if you need to access the built-in namespace directly, you
471 # should start with "import __builtin__" (note, no 's') which will
471 # should start with "import __builtin__" (note, no 's') which will
472 # definitely give you a module. Yeah, it's somewhat confusing:-(.
472 # definitely give you a module. Yeah, it's somewhat confusing:-(.
473
473
474 # These routines return properly built dicts as needed by the rest of
474 # These routines return properly built dicts as needed by the rest of
475 # the code, and can also be used by extension writers to generate
475 # the code, and can also be used by extension writers to generate
476 # properly initialized namespaces.
476 # properly initialized namespaces.
477 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
477 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
478 user_global_ns)
478 user_global_ns)
479
479
480 # Assign namespaces
480 # Assign namespaces
481 # This is the namespace where all normal user variables live
481 # This is the namespace where all normal user variables live
482 self.user_ns = user_ns
482 self.user_ns = user_ns
483 self.user_global_ns = user_global_ns
483 self.user_global_ns = user_global_ns
484
484
485 # An auxiliary namespace that checks what parts of the user_ns were
485 # An auxiliary namespace that checks what parts of the user_ns were
486 # loaded at startup, so we can list later only variables defined in
486 # loaded at startup, so we can list later only variables defined in
487 # actual interactive use. Since it is always a subset of user_ns, it
487 # actual interactive use. Since it is always a subset of user_ns, it
488 # doesn't need to be seaparately tracked in the ns_table
488 # doesn't need to be seaparately tracked in the ns_table
489 self.user_config_ns = {}
489 self.user_config_ns = {}
490
490
491 # A namespace to keep track of internal data structures to prevent
491 # A namespace to keep track of internal data structures to prevent
492 # them from cluttering user-visible stuff. Will be updated later
492 # them from cluttering user-visible stuff. Will be updated later
493 self.internal_ns = {}
493 self.internal_ns = {}
494
494
495 # Namespace of system aliases. Each entry in the alias
495 # Namespace of system aliases. Each entry in the alias
496 # table must be a 2-tuple of the form (N,name), where N is the number
496 # table must be a 2-tuple of the form (N,name), where N is the number
497 # of positional arguments of the alias.
497 # of positional arguments of the alias.
498 self.alias_table = {}
498 self.alias_table = {}
499
499
500 # Now that FakeModule produces a real module, we've run into a nasty
500 # Now that FakeModule produces a real module, we've run into a nasty
501 # problem: after script execution (via %run), the module where the user
501 # problem: after script execution (via %run), the module where the user
502 # code ran is deleted. Now that this object is a true module (needed
502 # code ran is deleted. Now that this object is a true module (needed
503 # so docetst and other tools work correctly), the Python module
503 # so docetst and other tools work correctly), the Python module
504 # teardown mechanism runs over it, and sets to None every variable
504 # teardown mechanism runs over it, and sets to None every variable
505 # present in that module. Top-level references to objects from the
505 # present in that module. Top-level references to objects from the
506 # script survive, because the user_ns is updated with them. However,
506 # script survive, because the user_ns is updated with them. However,
507 # calling functions defined in the script that use other things from
507 # calling functions defined in the script that use other things from
508 # the script will fail, because the function's closure had references
508 # the script will fail, because the function's closure had references
509 # to the original objects, which are now all None. So we must protect
509 # to the original objects, which are now all None. So we must protect
510 # these modules from deletion by keeping a cache.
510 # these modules from deletion by keeping a cache.
511 #
511 #
512 # To avoid keeping stale modules around (we only need the one from the
512 # To avoid keeping stale modules around (we only need the one from the
513 # last run), we use a dict keyed with the full path to the script, so
513 # last run), we use a dict keyed with the full path to the script, so
514 # only the last version of the module is held in the cache. Note,
514 # only the last version of the module is held in the cache. Note,
515 # however, that we must cache the module *namespace contents* (their
515 # however, that we must cache the module *namespace contents* (their
516 # __dict__). Because if we try to cache the actual modules, old ones
516 # __dict__). Because if we try to cache the actual modules, old ones
517 # (uncached) could be destroyed while still holding references (such as
517 # (uncached) could be destroyed while still holding references (such as
518 # those held by GUI objects that tend to be long-lived)>
518 # those held by GUI objects that tend to be long-lived)>
519 #
519 #
520 # The %reset command will flush this cache. See the cache_main_mod()
520 # The %reset command will flush this cache. See the cache_main_mod()
521 # and clear_main_mod_cache() methods for details on use.
521 # and clear_main_mod_cache() methods for details on use.
522
522
523 # This is the cache used for 'main' namespaces
523 # This is the cache used for 'main' namespaces
524 self._main_ns_cache = {}
524 self._main_ns_cache = {}
525 # And this is the single instance of FakeModule whose __dict__ we keep
525 # And this is the single instance of FakeModule whose __dict__ we keep
526 # copying and clearing for reuse on each %run
526 # copying and clearing for reuse on each %run
527 self._user_main_module = FakeModule()
527 self._user_main_module = FakeModule()
528
528
529 # A table holding all the namespaces IPython deals with, so that
529 # A table holding all the namespaces IPython deals with, so that
530 # introspection facilities can search easily.
530 # introspection facilities can search easily.
531 self.ns_table = {'user':user_ns,
531 self.ns_table = {'user':user_ns,
532 'user_global':user_global_ns,
532 'user_global':user_global_ns,
533 'alias':self.alias_table,
533 'alias':self.alias_table,
534 'internal':self.internal_ns,
534 'internal':self.internal_ns,
535 'builtin':__builtin__.__dict__
535 'builtin':__builtin__.__dict__
536 }
536 }
537
537
538 # Similarly, track all namespaces where references can be held and that
538 # Similarly, track all namespaces where references can be held and that
539 # we can safely clear (so it can NOT include builtin). This one can be
539 # we can safely clear (so it can NOT include builtin). This one can be
540 # a simple list.
540 # a simple list.
541 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
541 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
542 self.alias_table, self.internal_ns,
542 self.alias_table, self.internal_ns,
543 self._main_ns_cache ]
543 self._main_ns_cache ]
544
544
545 def init_sys_modules(self):
545 def init_sys_modules(self):
546 # We need to insert into sys.modules something that looks like a
546 # We need to insert into sys.modules something that looks like a
547 # module but which accesses the IPython namespace, for shelve and
547 # module but which accesses the IPython namespace, for shelve and
548 # pickle to work interactively. Normally they rely on getting
548 # pickle to work interactively. Normally they rely on getting
549 # everything out of __main__, but for embedding purposes each IPython
549 # everything out of __main__, but for embedding purposes each IPython
550 # instance has its own private namespace, so we can't go shoving
550 # instance has its own private namespace, so we can't go shoving
551 # everything into __main__.
551 # everything into __main__.
552
552
553 # note, however, that we should only do this for non-embedded
553 # note, however, that we should only do this for non-embedded
554 # ipythons, which really mimic the __main__.__dict__ with their own
554 # ipythons, which really mimic the __main__.__dict__ with their own
555 # namespace. Embedded instances, on the other hand, should not do
555 # namespace. Embedded instances, on the other hand, should not do
556 # this because they need to manage the user local/global namespaces
556 # this because they need to manage the user local/global namespaces
557 # only, but they live within a 'normal' __main__ (meaning, they
557 # only, but they live within a 'normal' __main__ (meaning, they
558 # shouldn't overtake the execution environment of the script they're
558 # shouldn't overtake the execution environment of the script they're
559 # embedded in).
559 # embedded in).
560
560
561 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
561 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
562
562
563 try:
563 try:
564 main_name = self.user_ns['__name__']
564 main_name = self.user_ns['__name__']
565 except KeyError:
565 except KeyError:
566 raise KeyError('user_ns dictionary MUST have a "__name__" key')
566 raise KeyError('user_ns dictionary MUST have a "__name__" key')
567 else:
567 else:
568 sys.modules[main_name] = FakeModule(self.user_ns)
568 sys.modules[main_name] = FakeModule(self.user_ns)
569
569
570 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
570 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
571 """Return a valid local and global user interactive namespaces.
571 """Return a valid local and global user interactive namespaces.
572
572
573 This builds a dict with the minimal information needed to operate as a
573 This builds a dict with the minimal information needed to operate as a
574 valid IPython user namespace, which you can pass to the various
574 valid IPython user namespace, which you can pass to the various
575 embedding classes in ipython. The default implementation returns the
575 embedding classes in ipython. The default implementation returns the
576 same dict for both the locals and the globals to allow functions to
576 same dict for both the locals and the globals to allow functions to
577 refer to variables in the namespace. Customized implementations can
577 refer to variables in the namespace. Customized implementations can
578 return different dicts. The locals dictionary can actually be anything
578 return different dicts. The locals dictionary can actually be anything
579 following the basic mapping protocol of a dict, but the globals dict
579 following the basic mapping protocol of a dict, but the globals dict
580 must be a true dict, not even a subclass. It is recommended that any
580 must be a true dict, not even a subclass. It is recommended that any
581 custom object for the locals namespace synchronize with the globals
581 custom object for the locals namespace synchronize with the globals
582 dict somehow.
582 dict somehow.
583
583
584 Raises TypeError if the provided globals namespace is not a true dict.
584 Raises TypeError if the provided globals namespace is not a true dict.
585
585
586 :Parameters:
586 :Parameters:
587 user_ns : dict-like, optional
587 user_ns : dict-like, optional
588 The current user namespace. The items in this namespace should
588 The current user namespace. The items in this namespace should
589 be included in the output. If None, an appropriate blank
589 be included in the output. If None, an appropriate blank
590 namespace should be created.
590 namespace should be created.
591 user_global_ns : dict, optional
591 user_global_ns : dict, optional
592 The current user global namespace. The items in this namespace
592 The current user global namespace. The items in this namespace
593 should be included in the output. If None, an appropriate
593 should be included in the output. If None, an appropriate
594 blank namespace should be created.
594 blank namespace should be created.
595
595
596 :Returns:
596 :Returns:
597 A tuple pair of dictionary-like object to be used as the local namespace
597 A tuple pair of dictionary-like object to be used as the local namespace
598 of the interpreter and a dict to be used as the global namespace.
598 of the interpreter and a dict to be used as the global namespace.
599 """
599 """
600
600
601 if user_ns is None:
601 if user_ns is None:
602 # Set __name__ to __main__ to better match the behavior of the
602 # Set __name__ to __main__ to better match the behavior of the
603 # normal interpreter.
603 # normal interpreter.
604 user_ns = {'__name__' :'__main__',
604 user_ns = {'__name__' :'__main__',
605 '__builtins__' : __builtin__,
605 '__builtins__' : __builtin__,
606 }
606 }
607 else:
607 else:
608 user_ns.setdefault('__name__','__main__')
608 user_ns.setdefault('__name__','__main__')
609 user_ns.setdefault('__builtins__',__builtin__)
609 user_ns.setdefault('__builtins__',__builtin__)
610
610
611 if user_global_ns is None:
611 if user_global_ns is None:
612 user_global_ns = user_ns
612 user_global_ns = user_ns
613 if type(user_global_ns) is not dict:
613 if type(user_global_ns) is not dict:
614 raise TypeError("user_global_ns must be a true dict; got %r"
614 raise TypeError("user_global_ns must be a true dict; got %r"
615 % type(user_global_ns))
615 % type(user_global_ns))
616
616
617 return user_ns, user_global_ns
617 return user_ns, user_global_ns
618
618
619 def init_history(self):
619 def init_history(self):
620 # List of input with multi-line handling.
620 # List of input with multi-line handling.
621 self.input_hist = InputList()
621 self.input_hist = InputList()
622 # This one will hold the 'raw' input history, without any
622 # This one will hold the 'raw' input history, without any
623 # pre-processing. This will allow users to retrieve the input just as
623 # pre-processing. This will allow users to retrieve the input just as
624 # it was exactly typed in by the user, with %hist -r.
624 # it was exactly typed in by the user, with %hist -r.
625 self.input_hist_raw = InputList()
625 self.input_hist_raw = InputList()
626
626
627 # list of visited directories
627 # list of visited directories
628 try:
628 try:
629 self.dir_hist = [os.getcwd()]
629 self.dir_hist = [os.getcwd()]
630 except OSError:
630 except OSError:
631 self.dir_hist = []
631 self.dir_hist = []
632
632
633 # dict of output history
633 # dict of output history
634 self.output_hist = {}
634 self.output_hist = {}
635
635
636 # Now the history file
636 # Now the history file
637 try:
637 try:
638 histfname = 'history-%s' % self.profile
638 histfname = 'history-%s' % self.profile
639 except AttributeError:
639 except AttributeError:
640 histfname = 'history'
640 histfname = 'history'
641 self.histfile = os.path.join(self.config.IPYTHONDIR, histfname)
641 self.histfile = os.path.join(self.config.IPYTHONDIR, histfname)
642
642
643 # Fill the history zero entry, user counter starts at 1
643 # Fill the history zero entry, user counter starts at 1
644 self.input_hist.append('\n')
644 self.input_hist.append('\n')
645 self.input_hist_raw.append('\n')
645 self.input_hist_raw.append('\n')
646
646
647 def init_encoding(self):
647 def init_encoding(self):
648 # Get system encoding at startup time. Certain terminals (like Emacs
648 # Get system encoding at startup time. Certain terminals (like Emacs
649 # under Win32 have it set to None, and we need to have a known valid
649 # under Win32 have it set to None, and we need to have a known valid
650 # encoding to use in the raw_input() method
650 # encoding to use in the raw_input() method
651 try:
651 try:
652 self.stdin_encoding = sys.stdin.encoding or 'ascii'
652 self.stdin_encoding = sys.stdin.encoding or 'ascii'
653 except AttributeError:
653 except AttributeError:
654 self.stdin_encoding = 'ascii'
654 self.stdin_encoding = 'ascii'
655
655
656 def init_handlers(self):
656 def init_handlers(self):
657 # escapes for automatic behavior on the command line
657 # escapes for automatic behavior on the command line
658 self.ESC_SHELL = '!'
658 self.ESC_SHELL = '!'
659 self.ESC_SH_CAP = '!!'
659 self.ESC_SH_CAP = '!!'
660 self.ESC_HELP = '?'
660 self.ESC_HELP = '?'
661 self.ESC_MAGIC = '%'
661 self.ESC_MAGIC = '%'
662 self.ESC_QUOTE = ','
662 self.ESC_QUOTE = ','
663 self.ESC_QUOTE2 = ';'
663 self.ESC_QUOTE2 = ';'
664 self.ESC_PAREN = '/'
664 self.ESC_PAREN = '/'
665
665
666 # And their associated handlers
666 # And their associated handlers
667 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
667 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
668 self.ESC_QUOTE : self.handle_auto,
668 self.ESC_QUOTE : self.handle_auto,
669 self.ESC_QUOTE2 : self.handle_auto,
669 self.ESC_QUOTE2 : self.handle_auto,
670 self.ESC_MAGIC : self.handle_magic,
670 self.ESC_MAGIC : self.handle_magic,
671 self.ESC_HELP : self.handle_help,
671 self.ESC_HELP : self.handle_help,
672 self.ESC_SHELL : self.handle_shell_escape,
672 self.ESC_SHELL : self.handle_shell_escape,
673 self.ESC_SH_CAP : self.handle_shell_escape,
673 self.ESC_SH_CAP : self.handle_shell_escape,
674 }
674 }
675
675
676 def init_syntax_highlighting(self):
676 def init_syntax_highlighting(self):
677 # Python source parser/formatter for syntax highlighting
677 # Python source parser/formatter for syntax highlighting
678 pyformat = PyColorize.Parser().format
678 pyformat = PyColorize.Parser().format
679 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
679 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
680
680
681 def init_hooks(self):
681 def init_hooks(self):
682 # hooks holds pointers used for user-side customizations
682 # hooks holds pointers used for user-side customizations
683 self.hooks = Struct()
683 self.hooks = Struct()
684
684
685 self.strdispatchers = {}
685 self.strdispatchers = {}
686
686
687 # Set all default hooks, defined in the IPython.hooks module.
687 # Set all default hooks, defined in the IPython.hooks module.
688 import IPython.core.hooks
688 import IPython.core.hooks
689 hooks = IPython.core.hooks
689 hooks = IPython.core.hooks
690 for hook_name in hooks.__all__:
690 for hook_name in hooks.__all__:
691 # default hooks have priority 100, i.e. low; user hooks should have
691 # default hooks have priority 100, i.e. low; user hooks should have
692 # 0-100 priority
692 # 0-100 priority
693 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
693 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
694
694
695 def init_pushd_popd_magic(self):
695 def init_pushd_popd_magic(self):
696 # for pushd/popd management
696 # for pushd/popd management
697 try:
697 try:
698 self.home_dir = get_home_dir()
698 self.home_dir = get_home_dir()
699 except HomeDirError, msg:
699 except HomeDirError, msg:
700 fatal(msg)
700 fatal(msg)
701
701
702 self.dir_stack = []
702 self.dir_stack = []
703
703
704 def init_traceback_handlers(self, custom_exceptions):
704 def init_traceback_handlers(self, custom_exceptions):
705 # Syntax error handler.
705 # Syntax error handler.
706 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
706 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
707
707
708 # The interactive one is initialized with an offset, meaning we always
708 # The interactive one is initialized with an offset, meaning we always
709 # want to remove the topmost item in the traceback, which is our own
709 # want to remove the topmost item in the traceback, which is our own
710 # internal code. Valid modes: ['Plain','Context','Verbose']
710 # internal code. Valid modes: ['Plain','Context','Verbose']
711 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
711 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
712 color_scheme='NoColor',
712 color_scheme='NoColor',
713 tb_offset = 1)
713 tb_offset = 1)
714
714
715 # IPython itself shouldn't crash. This will produce a detailed
715 # IPython itself shouldn't crash. This will produce a detailed
716 # post-mortem if it does. But we only install the crash handler for
716 # post-mortem if it does. But we only install the crash handler for
717 # non-threaded shells, the threaded ones use a normal verbose reporter
717 # non-threaded shells, the threaded ones use a normal verbose reporter
718 # and lose the crash handler. This is because exceptions in the main
718 # and lose the crash handler. This is because exceptions in the main
719 # thread (such as in GUI code) propagate directly to sys.excepthook,
719 # thread (such as in GUI code) propagate directly to sys.excepthook,
720 # and there's no point in printing crash dumps for every user exception.
720 # and there's no point in printing crash dumps for every user exception.
721 if self.isthreaded:
721 if self.isthreaded:
722 ipCrashHandler = ultratb.FormattedTB()
722 ipCrashHandler = ultratb.FormattedTB()
723 else:
723 else:
724 from IPython.core import crashhandler
724 from IPython.core import crashhandler
725 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
725 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
726 self.set_crash_handler(ipCrashHandler)
726 self.set_crash_handler(ipCrashHandler)
727
727
728 # and add any custom exception handlers the user may have specified
728 # and add any custom exception handlers the user may have specified
729 self.set_custom_exc(*custom_exceptions)
729 self.set_custom_exc(*custom_exceptions)
730
730
731 def init_logger(self):
731 def init_logger(self):
732 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
732 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
733 # local shortcut, this is used a LOT
733 # local shortcut, this is used a LOT
734 self.log = self.logger.log
734 self.log = self.logger.log
735 # template for logfile headers. It gets resolved at runtime by the
735 # template for logfile headers. It gets resolved at runtime by the
736 # logstart method.
736 # logstart method.
737 self.loghead_tpl = \
737 self.loghead_tpl = \
738 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
738 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
739 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
739 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
740 #log# opts = %s
740 #log# opts = %s
741 #log# args = %s
741 #log# args = %s
742 #log# It is safe to make manual edits below here.
742 #log# It is safe to make manual edits below here.
743 #log#-----------------------------------------------------------------------
743 #log#-----------------------------------------------------------------------
744 """
744 """
745
745
746 def init_logstart(self):
746 def init_logstart(self):
747 if self.logplay:
747 if self.logplay:
748 self.magic_logstart(self.logplay + ' append')
748 self.magic_logstart(self.logplay + ' append')
749 elif self.logfile:
749 elif self.logfile:
750 self.magic_logstart(self.logfile)
750 self.magic_logstart(self.logfile)
751 elif self.logstart:
751 elif self.logstart:
752 self.magic_logstart()
752 self.magic_logstart()
753
753
754 def init_aliases(self):
754 def init_aliases(self):
755 # dict of things NOT to alias (keywords, builtins and some magics)
755 # dict of things NOT to alias (keywords, builtins and some magics)
756 no_alias = {}
756 no_alias = {}
757 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
757 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
758 for key in keyword.kwlist + no_alias_magics:
758 for key in keyword.kwlist + no_alias_magics:
759 no_alias[key] = 1
759 no_alias[key] = 1
760 no_alias.update(__builtin__.__dict__)
760 no_alias.update(__builtin__.__dict__)
761 self.no_alias = no_alias
761 self.no_alias = no_alias
762
762
763 # Make some aliases automatically
763 # Make some aliases automatically
764 # Prepare list of shell aliases to auto-define
764 # Prepare list of shell aliases to auto-define
765 if os.name == 'posix':
765 if os.name == 'posix':
766 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
766 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
767 'mv mv -i','rm rm -i','cp cp -i',
767 'mv mv -i','rm rm -i','cp cp -i',
768 'cat cat','less less','clear clear',
768 'cat cat','less less','clear clear',
769 # a better ls
769 # a better ls
770 'ls ls -F',
770 'ls ls -F',
771 # long ls
771 # long ls
772 'll ls -lF')
772 'll ls -lF')
773 # Extra ls aliases with color, which need special treatment on BSD
773 # Extra ls aliases with color, which need special treatment on BSD
774 # variants
774 # variants
775 ls_extra = ( # color ls
775 ls_extra = ( # color ls
776 'lc ls -F -o --color',
776 'lc ls -F -o --color',
777 # ls normal files only
777 # ls normal files only
778 'lf ls -F -o --color %l | grep ^-',
778 'lf ls -F -o --color %l | grep ^-',
779 # ls symbolic links
779 # ls symbolic links
780 'lk ls -F -o --color %l | grep ^l',
780 'lk ls -F -o --color %l | grep ^l',
781 # directories or links to directories,
781 # directories or links to directories,
782 'ldir ls -F -o --color %l | grep /$',
782 'ldir ls -F -o --color %l | grep /$',
783 # things which are executable
783 # things which are executable
784 'lx ls -F -o --color %l | grep ^-..x',
784 'lx ls -F -o --color %l | grep ^-..x',
785 )
785 )
786 # The BSDs don't ship GNU ls, so they don't understand the
786 # The BSDs don't ship GNU ls, so they don't understand the
787 # --color switch out of the box
787 # --color switch out of the box
788 if 'bsd' in sys.platform:
788 if 'bsd' in sys.platform:
789 ls_extra = ( # ls normal files only
789 ls_extra = ( # ls normal files only
790 'lf ls -lF | grep ^-',
790 'lf ls -lF | grep ^-',
791 # ls symbolic links
791 # ls symbolic links
792 'lk ls -lF | grep ^l',
792 'lk ls -lF | grep ^l',
793 # directories or links to directories,
793 # directories or links to directories,
794 'ldir ls -lF | grep /$',
794 'ldir ls -lF | grep /$',
795 # things which are executable
795 # things which are executable
796 'lx ls -lF | grep ^-..x',
796 'lx ls -lF | grep ^-..x',
797 )
797 )
798 auto_alias = auto_alias + ls_extra
798 auto_alias = auto_alias + ls_extra
799 elif os.name in ['nt','dos']:
799 elif os.name in ['nt','dos']:
800 auto_alias = ('ls dir /on',
800 auto_alias = ('ls dir /on',
801 'ddir dir /ad /on', 'ldir dir /ad /on',
801 'ddir dir /ad /on', 'ldir dir /ad /on',
802 'mkdir mkdir','rmdir rmdir','echo echo',
802 'mkdir mkdir','rmdir rmdir','echo echo',
803 'ren ren','cls cls','copy copy')
803 'ren ren','cls cls','copy copy')
804 else:
804 else:
805 auto_alias = ()
805 auto_alias = ()
806 self.auto_alias = [s.split(None,1) for s in auto_alias]
806 self.auto_alias = [s.split(None,1) for s in auto_alias]
807
807
808 # Load default aliases
808 # Load default aliases
809 for alias, cmd in self.auto_alias:
809 for alias, cmd in self.auto_alias:
810 self.define_alias(alias,cmd)
810 self.define_alias(alias,cmd)
811
811
812 # Load user aliases
812 # Load user aliases
813 for alias in self.alias:
813 for alias in self.alias:
814 self.magic_alias(alias)
814 self.magic_alias(alias)
815
815
816 def init_builtins(self):
816 def init_builtins(self):
817 self.builtin_trap = BuiltinTrap(self)
817 self.builtin_trap = BuiltinTrap(self)
818
818
819 def init_shadow_hist(self):
819 def init_shadow_hist(self):
820 try:
820 try:
821 self.db = pickleshare.PickleShareDB(self.config.IPYTHONDIR + "/db")
821 self.db = pickleshare.PickleShareDB(self.config.IPYTHONDIR + "/db")
822 except exceptions.UnicodeDecodeError:
822 except exceptions.UnicodeDecodeError:
823 print "Your ipythondir can't be decoded to unicode!"
823 print "Your ipythondir can't be decoded to unicode!"
824 print "Please set HOME environment variable to something that"
824 print "Please set HOME environment variable to something that"
825 print r"only has ASCII characters, e.g. c:\home"
825 print r"only has ASCII characters, e.g. c:\home"
826 print "Now it is", self.config.IPYTHONDIR
826 print "Now it is", self.config.IPYTHONDIR
827 sys.exit()
827 sys.exit()
828 self.shadowhist = ipcorehist.ShadowHist(self.db)
828 self.shadowhist = ipcorehist.ShadowHist(self.db)
829
829
830 def init_inspector(self):
830 def init_inspector(self):
831 # Object inspector
831 # Object inspector
832 self.inspector = oinspect.Inspector(oinspect.InspectColors,
832 self.inspector = oinspect.Inspector(oinspect.InspectColors,
833 PyColorize.ANSICodeColors,
833 PyColorize.ANSICodeColors,
834 'NoColor',
834 'NoColor',
835 self.object_info_string_level)
835 self.object_info_string_level)
836
836
837 def init_readline(self):
837 def init_readline(self):
838 """Command history completion/saving/reloading."""
838 """Command history completion/saving/reloading."""
839
839
840 self.rl_next_input = None
840 self.rl_next_input = None
841 self.rl_do_indent = False
841 self.rl_do_indent = False
842
842
843 if not self.readline_use:
843 if not self.readline_use:
844 return
844 return
845
845
846 import IPython.utils.rlineimpl as readline
846 import IPython.utils.rlineimpl as readline
847
847
848 if not readline.have_readline:
848 if not readline.have_readline:
849 self.has_readline = 0
849 self.has_readline = 0
850 self.readline = None
850 self.readline = None
851 # no point in bugging windows users with this every time:
851 # no point in bugging windows users with this every time:
852 warn('Readline services not available on this platform.')
852 warn('Readline services not available on this platform.')
853 else:
853 else:
854 sys.modules['readline'] = readline
854 sys.modules['readline'] = readline
855 import atexit
855 import atexit
856 from IPython.core.completer import IPCompleter
856 from IPython.core.completer import IPCompleter
857 self.Completer = IPCompleter(self,
857 self.Completer = IPCompleter(self,
858 self.user_ns,
858 self.user_ns,
859 self.user_global_ns,
859 self.user_global_ns,
860 self.readline_omit__names,
860 self.readline_omit__names,
861 self.alias_table)
861 self.alias_table)
862 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
862 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
863 self.strdispatchers['complete_command'] = sdisp
863 self.strdispatchers['complete_command'] = sdisp
864 self.Completer.custom_completers = sdisp
864 self.Completer.custom_completers = sdisp
865 # Platform-specific configuration
865 # Platform-specific configuration
866 if os.name == 'nt':
866 if os.name == 'nt':
867 self.readline_startup_hook = readline.set_pre_input_hook
867 self.readline_startup_hook = readline.set_pre_input_hook
868 else:
868 else:
869 self.readline_startup_hook = readline.set_startup_hook
869 self.readline_startup_hook = readline.set_startup_hook
870
870
871 # Load user's initrc file (readline config)
871 # Load user's initrc file (readline config)
872 # Or if libedit is used, load editrc.
872 # Or if libedit is used, load editrc.
873 inputrc_name = os.environ.get('INPUTRC')
873 inputrc_name = os.environ.get('INPUTRC')
874 if inputrc_name is None:
874 if inputrc_name is None:
875 home_dir = get_home_dir()
875 home_dir = get_home_dir()
876 if home_dir is not None:
876 if home_dir is not None:
877 inputrc_name = '.inputrc'
877 inputrc_name = '.inputrc'
878 if readline.uses_libedit:
878 if readline.uses_libedit:
879 inputrc_name = '.editrc'
879 inputrc_name = '.editrc'
880 inputrc_name = os.path.join(home_dir, inputrc_name)
880 inputrc_name = os.path.join(home_dir, inputrc_name)
881 if os.path.isfile(inputrc_name):
881 if os.path.isfile(inputrc_name):
882 try:
882 try:
883 readline.read_init_file(inputrc_name)
883 readline.read_init_file(inputrc_name)
884 except:
884 except:
885 warn('Problems reading readline initialization file <%s>'
885 warn('Problems reading readline initialization file <%s>'
886 % inputrc_name)
886 % inputrc_name)
887
887
888 self.has_readline = 1
888 self.has_readline = 1
889 self.readline = readline
889 self.readline = readline
890 # save this in sys so embedded copies can restore it properly
890 # save this in sys so embedded copies can restore it properly
891 sys.ipcompleter = self.Completer.complete
891 sys.ipcompleter = self.Completer.complete
892 self.set_completer()
892 self.set_completer()
893
893
894 # Configure readline according to user's prefs
894 # Configure readline according to user's prefs
895 # This is only done if GNU readline is being used. If libedit
895 # This is only done if GNU readline is being used. If libedit
896 # is being used (as on Leopard) the readline config is
896 # is being used (as on Leopard) the readline config is
897 # not run as the syntax for libedit is different.
897 # not run as the syntax for libedit is different.
898 if not readline.uses_libedit:
898 if not readline.uses_libedit:
899 for rlcommand in self.readline_parse_and_bind:
899 for rlcommand in self.readline_parse_and_bind:
900 #print "loading rl:",rlcommand # dbg
900 #print "loading rl:",rlcommand # dbg
901 readline.parse_and_bind(rlcommand)
901 readline.parse_and_bind(rlcommand)
902
902
903 # Remove some chars from the delimiters list. If we encounter
903 # Remove some chars from the delimiters list. If we encounter
904 # unicode chars, discard them.
904 # unicode chars, discard them.
905 delims = readline.get_completer_delims().encode("ascii", "ignore")
905 delims = readline.get_completer_delims().encode("ascii", "ignore")
906 delims = delims.translate(string._idmap,
906 delims = delims.translate(string._idmap,
907 self.readline_remove_delims)
907 self.readline_remove_delims)
908 readline.set_completer_delims(delims)
908 readline.set_completer_delims(delims)
909 # otherwise we end up with a monster history after a while:
909 # otherwise we end up with a monster history after a while:
910 readline.set_history_length(1000)
910 readline.set_history_length(1000)
911 try:
911 try:
912 #print '*** Reading readline history' # dbg
912 #print '*** Reading readline history' # dbg
913 readline.read_history_file(self.histfile)
913 readline.read_history_file(self.histfile)
914 except IOError:
914 except IOError:
915 pass # It doesn't exist yet.
915 pass # It doesn't exist yet.
916
916
917 atexit.register(self.atexit_operations)
917 atexit.register(self.atexit_operations)
918 del atexit
918 del atexit
919
919
920 # Configure auto-indent for all platforms
920 # Configure auto-indent for all platforms
921 self.set_autoindent(self.autoindent)
921 self.set_autoindent(self.autoindent)
922
922
923 def init_prompts(self):
923 def init_prompts(self):
924 # Initialize cache, set in/out prompts and printing system
924 # Initialize cache, set in/out prompts and printing system
925 self.outputcache = CachedOutput(self,
925 self.outputcache = CachedOutput(self,
926 self.cache_size,
926 self.cache_size,
927 self.pprint,
927 self.pprint,
928 input_sep = self.separate_in,
928 input_sep = self.separate_in,
929 output_sep = self.separate_out,
929 output_sep = self.separate_out,
930 output_sep2 = self.separate_out2,
930 output_sep2 = self.separate_out2,
931 ps1 = self.prompt_in1,
931 ps1 = self.prompt_in1,
932 ps2 = self.prompt_in2,
932 ps2 = self.prompt_in2,
933 ps_out = self.prompt_out,
933 ps_out = self.prompt_out,
934 pad_left = self.prompts_pad_left)
934 pad_left = self.prompts_pad_left)
935
935
936 # user may have over-ridden the default print hook:
936 # user may have over-ridden the default print hook:
937 try:
937 try:
938 self.outputcache.__class__.display = self.hooks.display
938 self.outputcache.__class__.display = self.hooks.display
939 except AttributeError:
939 except AttributeError:
940 pass
940 pass
941
941
942 def init_displayhook(self):
942 def init_displayhook(self):
943 # I don't like assigning globally to sys, because it means when
943 # I don't like assigning globally to sys, because it means when
944 # embedding instances, each embedded instance overrides the previous
944 # embedding instances, each embedded instance overrides the previous
945 # choice. But sys.displayhook seems to be called internally by exec,
945 # choice. But sys.displayhook seems to be called internally by exec,
946 # so I don't see a way around it. We first save the original and then
946 # so I don't see a way around it. We first save the original and then
947 # overwrite it.
947 # overwrite it.
948 self.sys_displayhook = sys.displayhook
948 self.sys_displayhook = sys.displayhook
949 sys.displayhook = self.outputcache
949 sys.displayhook = self.outputcache
950
950
951 def init_reload_doctest(self):
951 def init_reload_doctest(self):
952 # Do a proper resetting of doctest, including the necessary displayhook
952 # Do a proper resetting of doctest, including the necessary displayhook
953 # monkeypatching
953 # monkeypatching
954 try:
954 try:
955 doctest_reload()
955 doctest_reload()
956 except ImportError:
956 except ImportError:
957 warn("doctest module does not exist.")
957 warn("doctest module does not exist.")
958
958
959 def init_magics(self):
959 def init_magics(self):
960 # Set user colors (don't do it in the constructor above so that it
960 # Set user colors (don't do it in the constructor above so that it
961 # doesn't crash if colors option is invalid)
961 # doesn't crash if colors option is invalid)
962 self.magic_colors(self.colors)
962 self.magic_colors(self.colors)
963
963
964 def init_pdb(self):
964 def init_pdb(self):
965 # Set calling of pdb on exceptions
965 # Set calling of pdb on exceptions
966 # self.call_pdb is a property
966 # self.call_pdb is a property
967 self.call_pdb = self.pdb
967 self.call_pdb = self.pdb
968
968
969 # def init_exec_commands(self):
969 # def init_exec_commands(self):
970 # for cmd in self.config.EXECUTE:
970 # for cmd in self.config.EXECUTE:
971 # print "execute:", cmd
971 # print "execute:", cmd
972 # self.api.runlines(cmd)
972 # self.api.runlines(cmd)
973 #
973 #
974 # batchrun = False
974 # batchrun = False
975 # if self.config.has_key('EXECFILE'):
975 # if self.config.has_key('EXECFILE'):
976 # for batchfile in [path(arg) for arg in self.config.EXECFILE
976 # for batchfile in [path(arg) for arg in self.config.EXECFILE
977 # if arg.lower().endswith('.ipy')]:
977 # if arg.lower().endswith('.ipy')]:
978 # if not batchfile.isfile():
978 # if not batchfile.isfile():
979 # print "No such batch file:", batchfile
979 # print "No such batch file:", batchfile
980 # continue
980 # continue
981 # self.api.runlines(batchfile.text())
981 # self.api.runlines(batchfile.text())
982 # batchrun = True
982 # batchrun = True
983 # # without -i option, exit after running the batch file
983 # # without -i option, exit after running the batch file
984 # if batchrun and not self.interactive:
984 # if batchrun and not self.interactive:
985 # self.ask_exit()
985 # self.ask_exit()
986
986
987 # def load(self, mod):
987 # def load(self, mod):
988 # """ Load an extension.
988 # """ Load an extension.
989 #
989 #
990 # Some modules should (or must) be 'load()':ed, rather than just imported.
990 # Some modules should (or must) be 'load()':ed, rather than just imported.
991 #
991 #
992 # Loading will do:
992 # Loading will do:
993 #
993 #
994 # - run init_ipython(ip)
994 # - run init_ipython(ip)
995 # - run ipython_firstrun(ip)
995 # - run ipython_firstrun(ip)
996 # """
996 # """
997 #
997 #
998 # if mod in self.extensions:
998 # if mod in self.extensions:
999 # # just to make sure we don't init it twice
999 # # just to make sure we don't init it twice
1000 # # note that if you 'load' a module that has already been
1000 # # note that if you 'load' a module that has already been
1001 # # imported, init_ipython gets run anyway
1001 # # imported, init_ipython gets run anyway
1002 #
1002 #
1003 # return self.extensions[mod]
1003 # return self.extensions[mod]
1004 # __import__(mod)
1004 # __import__(mod)
1005 # m = sys.modules[mod]
1005 # m = sys.modules[mod]
1006 # if hasattr(m,'init_ipython'):
1006 # if hasattr(m,'init_ipython'):
1007 # m.init_ipython(self)
1007 # m.init_ipython(self)
1008 #
1008 #
1009 # if hasattr(m,'ipython_firstrun'):
1009 # if hasattr(m,'ipython_firstrun'):
1010 # already_loaded = self.db.get('firstrun_done', set())
1010 # already_loaded = self.db.get('firstrun_done', set())
1011 # if mod not in already_loaded:
1011 # if mod not in already_loaded:
1012 # m.ipython_firstrun(self)
1012 # m.ipython_firstrun(self)
1013 # already_loaded.add(mod)
1013 # already_loaded.add(mod)
1014 # self.db['firstrun_done'] = already_loaded
1014 # self.db['firstrun_done'] = already_loaded
1015 #
1015 #
1016 # self.extensions[mod] = m
1016 # self.extensions[mod] = m
1017 # return m
1017 # return m
1018
1018
1019 def init_user_ns(self):
1019 def init_user_ns(self):
1020 """Initialize all user-visible namespaces to their minimum defaults.
1020 """Initialize all user-visible namespaces to their minimum defaults.
1021
1021
1022 Certain history lists are also initialized here, as they effectively
1022 Certain history lists are also initialized here, as they effectively
1023 act as user namespaces.
1023 act as user namespaces.
1024
1024
1025 Notes
1025 Notes
1026 -----
1026 -----
1027 All data structures here are only filled in, they are NOT reset by this
1027 All data structures here are only filled in, they are NOT reset by this
1028 method. If they were not empty before, data will simply be added to
1028 method. If they were not empty before, data will simply be added to
1029 therm.
1029 therm.
1030 """
1030 """
1031 # The user namespace MUST have a pointer to the shell itself.
1031 # The user namespace MUST have a pointer to the shell itself.
1032 self.user_ns[self.name] = self
1032 self.user_ns[self.name] = self
1033
1033
1034 # Store myself as the public api!!!
1034 # Store myself as the public api!!!
1035 self.user_ns['_ip'] = self
1035 self.user_ns['_ip'] = self
1036
1036
1037 # make global variables for user access to the histories
1037 # make global variables for user access to the histories
1038 self.user_ns['_ih'] = self.input_hist
1038 self.user_ns['_ih'] = self.input_hist
1039 self.user_ns['_oh'] = self.output_hist
1039 self.user_ns['_oh'] = self.output_hist
1040 self.user_ns['_dh'] = self.dir_hist
1040 self.user_ns['_dh'] = self.dir_hist
1041
1041
1042 # user aliases to input and output histories
1042 # user aliases to input and output histories
1043 self.user_ns['In'] = self.input_hist
1043 self.user_ns['In'] = self.input_hist
1044 self.user_ns['Out'] = self.output_hist
1044 self.user_ns['Out'] = self.output_hist
1045
1045
1046 self.user_ns['_sh'] = shadowns
1046 self.user_ns['_sh'] = shadowns
1047
1047
1048 # Put 'help' in the user namespace
1048 # Put 'help' in the user namespace
1049 try:
1049 try:
1050 from site import _Helper
1050 from site import _Helper
1051 self.user_ns['help'] = _Helper()
1051 self.user_ns['help'] = _Helper()
1052 except ImportError:
1052 except ImportError:
1053 warn('help() not available - check site.py')
1053 warn('help() not available - check site.py')
1054
1054
1055 def save_sys_module_state(self):
1055 def save_sys_module_state(self):
1056 """Save the state of hooks in the sys module.
1056 """Save the state of hooks in the sys module.
1057
1057
1058 This has to be called after self.user_ns is created.
1058 This has to be called after self.user_ns is created.
1059 """
1059 """
1060 self._orig_sys_module_state = {}
1060 self._orig_sys_module_state = {}
1061 self._orig_sys_module_state['stdin'] = sys.stdin
1061 self._orig_sys_module_state['stdin'] = sys.stdin
1062 self._orig_sys_module_state['stdout'] = sys.stdout
1062 self._orig_sys_module_state['stdout'] = sys.stdout
1063 self._orig_sys_module_state['stderr'] = sys.stderr
1063 self._orig_sys_module_state['stderr'] = sys.stderr
1064 self._orig_sys_module_state['displayhook'] = sys.displayhook
1064 self._orig_sys_module_state['displayhook'] = sys.displayhook
1065 self._orig_sys_module_state['excepthook'] = sys.excepthook
1065 self._orig_sys_module_state['excepthook'] = sys.excepthook
1066 try:
1066 try:
1067 self._orig_sys_modules_main_name = self.user_ns['__name__']
1067 self._orig_sys_modules_main_name = self.user_ns['__name__']
1068 except KeyError:
1068 except KeyError:
1069 pass
1069 pass
1070
1070
1071 def restore_sys_module_state(self):
1071 def restore_sys_module_state(self):
1072 """Restore the state of the sys module."""
1072 """Restore the state of the sys module."""
1073 try:
1073 try:
1074 for k, v in self._orig_sys_module_state.items():
1074 for k, v in self._orig_sys_module_state.items():
1075 setattr(sys, k, v)
1075 setattr(sys, k, v)
1076 except AttributeError:
1076 except AttributeError:
1077 pass
1077 pass
1078 try:
1078 try:
1079 delattr(sys, 'ipcompleter')
1079 delattr(sys, 'ipcompleter')
1080 except AttributeError:
1080 except AttributeError:
1081 pass
1081 pass
1082 # Reset what what done in self.init_sys_modules
1082 # Reset what what done in self.init_sys_modules
1083 try:
1083 try:
1084 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
1084 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
1085 except (AttributeError, KeyError):
1085 except (AttributeError, KeyError):
1086 pass
1086 pass
1087
1087
1088 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
1088 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
1089 """set_hook(name,hook) -> sets an internal IPython hook.
1089 """set_hook(name,hook) -> sets an internal IPython hook.
1090
1090
1091 IPython exposes some of its internal API as user-modifiable hooks. By
1091 IPython exposes some of its internal API as user-modifiable hooks. By
1092 adding your function to one of these hooks, you can modify IPython's
1092 adding your function to one of these hooks, you can modify IPython's
1093 behavior to call at runtime your own routines."""
1093 behavior to call at runtime your own routines."""
1094
1094
1095 # At some point in the future, this should validate the hook before it
1095 # At some point in the future, this should validate the hook before it
1096 # accepts it. Probably at least check that the hook takes the number
1096 # accepts it. Probably at least check that the hook takes the number
1097 # of args it's supposed to.
1097 # of args it's supposed to.
1098
1098
1099 f = new.instancemethod(hook,self,self.__class__)
1099 f = new.instancemethod(hook,self,self.__class__)
1100
1100
1101 # check if the hook is for strdispatcher first
1101 # check if the hook is for strdispatcher first
1102 if str_key is not None:
1102 if str_key is not None:
1103 sdp = self.strdispatchers.get(name, StrDispatch())
1103 sdp = self.strdispatchers.get(name, StrDispatch())
1104 sdp.add_s(str_key, f, priority )
1104 sdp.add_s(str_key, f, priority )
1105 self.strdispatchers[name] = sdp
1105 self.strdispatchers[name] = sdp
1106 return
1106 return
1107 if re_key is not None:
1107 if re_key is not None:
1108 sdp = self.strdispatchers.get(name, StrDispatch())
1108 sdp = self.strdispatchers.get(name, StrDispatch())
1109 sdp.add_re(re.compile(re_key), f, priority )
1109 sdp.add_re(re.compile(re_key), f, priority )
1110 self.strdispatchers[name] = sdp
1110 self.strdispatchers[name] = sdp
1111 return
1111 return
1112
1112
1113 dp = getattr(self.hooks, name, None)
1113 dp = getattr(self.hooks, name, None)
1114 if name not in IPython.core.hooks.__all__:
1114 if name not in IPython.core.hooks.__all__:
1115 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
1115 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
1116 if not dp:
1116 if not dp:
1117 dp = IPython.core.hooks.CommandChainDispatcher()
1117 dp = IPython.core.hooks.CommandChainDispatcher()
1118
1118
1119 try:
1119 try:
1120 dp.add(f,priority)
1120 dp.add(f,priority)
1121 except AttributeError:
1121 except AttributeError:
1122 # it was not commandchain, plain old func - replace
1122 # it was not commandchain, plain old func - replace
1123 dp = f
1123 dp = f
1124
1124
1125 setattr(self.hooks,name, dp)
1125 setattr(self.hooks,name, dp)
1126
1126
1127 def set_crash_handler(self, crashHandler):
1127 def set_crash_handler(self, crashHandler):
1128 """Set the IPython crash handler.
1128 """Set the IPython crash handler.
1129
1129
1130 This must be a callable with a signature suitable for use as
1130 This must be a callable with a signature suitable for use as
1131 sys.excepthook."""
1131 sys.excepthook."""
1132
1132
1133 # Install the given crash handler as the Python exception hook
1133 # Install the given crash handler as the Python exception hook
1134 sys.excepthook = crashHandler
1134 sys.excepthook = crashHandler
1135
1135
1136 # The instance will store a pointer to this, so that runtime code
1136 # The instance will store a pointer to this, so that runtime code
1137 # (such as magics) can access it. This is because during the
1137 # (such as magics) can access it. This is because during the
1138 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1138 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1139 # frameworks).
1139 # frameworks).
1140 self.sys_excepthook = sys.excepthook
1140 self.sys_excepthook = sys.excepthook
1141
1141
1142 def set_custom_exc(self,exc_tuple,handler):
1142 def set_custom_exc(self,exc_tuple,handler):
1143 """set_custom_exc(exc_tuple,handler)
1143 """set_custom_exc(exc_tuple,handler)
1144
1144
1145 Set a custom exception handler, which will be called if any of the
1145 Set a custom exception handler, which will be called if any of the
1146 exceptions in exc_tuple occur in the mainloop (specifically, in the
1146 exceptions in exc_tuple occur in the mainloop (specifically, in the
1147 runcode() method.
1147 runcode() method.
1148
1148
1149 Inputs:
1149 Inputs:
1150
1150
1151 - exc_tuple: a *tuple* of valid exceptions to call the defined
1151 - exc_tuple: a *tuple* of valid exceptions to call the defined
1152 handler for. It is very important that you use a tuple, and NOT A
1152 handler for. It is very important that you use a tuple, and NOT A
1153 LIST here, because of the way Python's except statement works. If
1153 LIST here, because of the way Python's except statement works. If
1154 you only want to trap a single exception, use a singleton tuple:
1154 you only want to trap a single exception, use a singleton tuple:
1155
1155
1156 exc_tuple == (MyCustomException,)
1156 exc_tuple == (MyCustomException,)
1157
1157
1158 - handler: this must be defined as a function with the following
1158 - handler: this must be defined as a function with the following
1159 basic interface: def my_handler(self,etype,value,tb).
1159 basic interface: def my_handler(self,etype,value,tb).
1160
1160
1161 This will be made into an instance method (via new.instancemethod)
1161 This will be made into an instance method (via new.instancemethod)
1162 of IPython itself, and it will be called if any of the exceptions
1162 of IPython itself, and it will be called if any of the exceptions
1163 listed in the exc_tuple are caught. If the handler is None, an
1163 listed in the exc_tuple are caught. If the handler is None, an
1164 internal basic one is used, which just prints basic info.
1164 internal basic one is used, which just prints basic info.
1165
1165
1166 WARNING: by putting in your own exception handler into IPython's main
1166 WARNING: by putting in your own exception handler into IPython's main
1167 execution loop, you run a very good chance of nasty crashes. This
1167 execution loop, you run a very good chance of nasty crashes. This
1168 facility should only be used if you really know what you are doing."""
1168 facility should only be used if you really know what you are doing."""
1169
1169
1170 assert type(exc_tuple)==type(()) , \
1170 assert type(exc_tuple)==type(()) , \
1171 "The custom exceptions must be given AS A TUPLE."
1171 "The custom exceptions must be given AS A TUPLE."
1172
1172
1173 def dummy_handler(self,etype,value,tb):
1173 def dummy_handler(self,etype,value,tb):
1174 print '*** Simple custom exception handler ***'
1174 print '*** Simple custom exception handler ***'
1175 print 'Exception type :',etype
1175 print 'Exception type :',etype
1176 print 'Exception value:',value
1176 print 'Exception value:',value
1177 print 'Traceback :',tb
1177 print 'Traceback :',tb
1178 print 'Source code :','\n'.join(self.buffer)
1178 print 'Source code :','\n'.join(self.buffer)
1179
1179
1180 if handler is None: handler = dummy_handler
1180 if handler is None: handler = dummy_handler
1181
1181
1182 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1182 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1183 self.custom_exceptions = exc_tuple
1183 self.custom_exceptions = exc_tuple
1184
1184
1185 def set_custom_completer(self,completer,pos=0):
1185 def set_custom_completer(self,completer,pos=0):
1186 """set_custom_completer(completer,pos=0)
1186 """set_custom_completer(completer,pos=0)
1187
1187
1188 Adds a new custom completer function.
1188 Adds a new custom completer function.
1189
1189
1190 The position argument (defaults to 0) is the index in the completers
1190 The position argument (defaults to 0) is the index in the completers
1191 list where you want the completer to be inserted."""
1191 list where you want the completer to be inserted."""
1192
1192
1193 newcomp = new.instancemethod(completer,self.Completer,
1193 newcomp = new.instancemethod(completer,self.Completer,
1194 self.Completer.__class__)
1194 self.Completer.__class__)
1195 self.Completer.matchers.insert(pos,newcomp)
1195 self.Completer.matchers.insert(pos,newcomp)
1196
1196
1197 def set_completer(self):
1197 def set_completer(self):
1198 """reset readline's completer to be our own."""
1198 """reset readline's completer to be our own."""
1199 self.readline.set_completer(self.Completer.complete)
1199 self.readline.set_completer(self.Completer.complete)
1200
1200
1201 def _get_call_pdb(self):
1201 def _get_call_pdb(self):
1202 return self._call_pdb
1202 return self._call_pdb
1203
1203
1204 def _set_call_pdb(self,val):
1204 def _set_call_pdb(self,val):
1205
1205
1206 if val not in (0,1,False,True):
1206 if val not in (0,1,False,True):
1207 raise ValueError,'new call_pdb value must be boolean'
1207 raise ValueError,'new call_pdb value must be boolean'
1208
1208
1209 # store value in instance
1209 # store value in instance
1210 self._call_pdb = val
1210 self._call_pdb = val
1211
1211
1212 # notify the actual exception handlers
1212 # notify the actual exception handlers
1213 self.InteractiveTB.call_pdb = val
1213 self.InteractiveTB.call_pdb = val
1214 if self.isthreaded:
1214 if self.isthreaded:
1215 try:
1215 try:
1216 self.sys_excepthook.call_pdb = val
1216 self.sys_excepthook.call_pdb = val
1217 except:
1217 except:
1218 warn('Failed to activate pdb for threaded exception handler')
1218 warn('Failed to activate pdb for threaded exception handler')
1219
1219
1220 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1220 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1221 'Control auto-activation of pdb at exceptions')
1221 'Control auto-activation of pdb at exceptions')
1222
1222
1223 def magic(self,arg_s):
1223 def magic(self,arg_s):
1224 """Call a magic function by name.
1224 """Call a magic function by name.
1225
1225
1226 Input: a string containing the name of the magic function to call and any
1226 Input: a string containing the name of the magic function to call and any
1227 additional arguments to be passed to the magic.
1227 additional arguments to be passed to the magic.
1228
1228
1229 magic('name -opt foo bar') is equivalent to typing at the ipython
1229 magic('name -opt foo bar') is equivalent to typing at the ipython
1230 prompt:
1230 prompt:
1231
1231
1232 In[1]: %name -opt foo bar
1232 In[1]: %name -opt foo bar
1233
1233
1234 To call a magic without arguments, simply use magic('name').
1234 To call a magic without arguments, simply use magic('name').
1235
1235
1236 This provides a proper Python function to call IPython's magics in any
1236 This provides a proper Python function to call IPython's magics in any
1237 valid Python code you can type at the interpreter, including loops and
1237 valid Python code you can type at the interpreter, including loops and
1238 compound statements.
1238 compound statements.
1239 """
1239 """
1240
1240
1241 args = arg_s.split(' ',1)
1241 args = arg_s.split(' ',1)
1242 magic_name = args[0]
1242 magic_name = args[0]
1243 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1243 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1244
1244
1245 try:
1245 try:
1246 magic_args = args[1]
1246 magic_args = args[1]
1247 except IndexError:
1247 except IndexError:
1248 magic_args = ''
1248 magic_args = ''
1249 fn = getattr(self,'magic_'+magic_name,None)
1249 fn = getattr(self,'magic_'+magic_name,None)
1250 if fn is None:
1250 if fn is None:
1251 error("Magic function `%s` not found." % magic_name)
1251 error("Magic function `%s` not found." % magic_name)
1252 else:
1252 else:
1253 magic_args = self.var_expand(magic_args,1)
1253 magic_args = self.var_expand(magic_args,1)
1254 with self.builtin_trap:
1254 with self.builtin_trap:
1255 result = fn(magic_args)
1255 return fn(magic_args)
1256 return result
1256 # return result
1257
1257
1258 def define_magic(self, magicname, func):
1258 def define_magic(self, magicname, func):
1259 """Expose own function as magic function for ipython
1259 """Expose own function as magic function for ipython
1260
1260
1261 def foo_impl(self,parameter_s=''):
1261 def foo_impl(self,parameter_s=''):
1262 'My very own magic!. (Use docstrings, IPython reads them).'
1262 'My very own magic!. (Use docstrings, IPython reads them).'
1263 print 'Magic function. Passed parameter is between < >:'
1263 print 'Magic function. Passed parameter is between < >:'
1264 print '<%s>' % parameter_s
1264 print '<%s>' % parameter_s
1265 print 'The self object is:',self
1265 print 'The self object is:',self
1266
1266
1267 self.define_magic('foo',foo_impl)
1267 self.define_magic('foo',foo_impl)
1268 """
1268 """
1269
1269
1270 import new
1270 import new
1271 im = new.instancemethod(func,self, self.__class__)
1271 im = new.instancemethod(func,self, self.__class__)
1272 old = getattr(self, "magic_" + magicname, None)
1272 old = getattr(self, "magic_" + magicname, None)
1273 setattr(self, "magic_" + magicname, im)
1273 setattr(self, "magic_" + magicname, im)
1274 return old
1274 return old
1275
1275
1276 def define_macro(self, name, themacro):
1276 def define_macro(self, name, themacro):
1277 """Define a new macro
1277 """Define a new macro
1278
1278
1279 Parameters
1279 Parameters
1280 ----------
1280 ----------
1281 name : str
1281 name : str
1282 The name of the macro.
1282 The name of the macro.
1283 themacro : str or Macro
1283 themacro : str or Macro
1284 The action to do upon invoking the macro. If a string, a new
1284 The action to do upon invoking the macro. If a string, a new
1285 Macro object is created by passing the string to it.
1285 Macro object is created by passing the string to it.
1286 """
1286 """
1287
1287
1288 from IPython.core import macro
1288 from IPython.core import macro
1289
1289
1290 if isinstance(themacro, basestring):
1290 if isinstance(themacro, basestring):
1291 themacro = macro.Macro(themacro)
1291 themacro = macro.Macro(themacro)
1292 if not isinstance(themacro, macro.Macro):
1292 if not isinstance(themacro, macro.Macro):
1293 raise ValueError('A macro must be a string or a Macro instance.')
1293 raise ValueError('A macro must be a string or a Macro instance.')
1294 self.user_ns[name] = themacro
1294 self.user_ns[name] = themacro
1295
1295
1296 def define_alias(self, name, cmd):
1296 def define_alias(self, name, cmd):
1297 """ Define a new alias."""
1297 """ Define a new alias."""
1298
1298
1299 if callable(cmd):
1299 if callable(cmd):
1300 self.alias_table[name] = cmd
1300 self.alias_table[name] = cmd
1301 from IPython.core import shadowns
1301 from IPython.core import shadowns
1302 setattr(shadowns, name, cmd)
1302 setattr(shadowns, name, cmd)
1303 return
1303 return
1304
1304
1305 if isinstance(cmd, basestring):
1305 if isinstance(cmd, basestring):
1306 nargs = cmd.count('%s')
1306 nargs = cmd.count('%s')
1307 if nargs>0 and cmd.find('%l')>=0:
1307 if nargs>0 and cmd.find('%l')>=0:
1308 raise Exception('The %s and %l specifiers are mutually '
1308 raise Exception('The %s and %l specifiers are mutually '
1309 'exclusive in alias definitions.')
1309 'exclusive in alias definitions.')
1310
1310
1311 self.alias_table[name] = (nargs,cmd)
1311 self.alias_table[name] = (nargs,cmd)
1312 return
1312 return
1313
1313
1314 self.alias_table[name] = cmd
1314 self.alias_table[name] = cmd
1315
1315
1316 def ipalias(self,arg_s):
1316 def ipalias(self,arg_s):
1317 """Call an alias by name.
1317 """Call an alias by name.
1318
1318
1319 Input: a string containing the name of the alias to call and any
1319 Input: a string containing the name of the alias to call and any
1320 additional arguments to be passed to the magic.
1320 additional arguments to be passed to the magic.
1321
1321
1322 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1322 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1323 prompt:
1323 prompt:
1324
1324
1325 In[1]: name -opt foo bar
1325 In[1]: name -opt foo bar
1326
1326
1327 To call an alias without arguments, simply use ipalias('name').
1327 To call an alias without arguments, simply use ipalias('name').
1328
1328
1329 This provides a proper Python function to call IPython's aliases in any
1329 This provides a proper Python function to call IPython's aliases in any
1330 valid Python code you can type at the interpreter, including loops and
1330 valid Python code you can type at the interpreter, including loops and
1331 compound statements. It is added by IPython to the Python builtin
1331 compound statements. It is added by IPython to the Python builtin
1332 namespace upon initialization."""
1332 namespace upon initialization."""
1333
1333
1334 args = arg_s.split(' ',1)
1334 args = arg_s.split(' ',1)
1335 alias_name = args[0]
1335 alias_name = args[0]
1336 try:
1336 try:
1337 alias_args = args[1]
1337 alias_args = args[1]
1338 except IndexError:
1338 except IndexError:
1339 alias_args = ''
1339 alias_args = ''
1340 if alias_name in self.alias_table:
1340 if alias_name in self.alias_table:
1341 self.call_alias(alias_name,alias_args)
1341 self.call_alias(alias_name,alias_args)
1342 else:
1342 else:
1343 error("Alias `%s` not found." % alias_name)
1343 error("Alias `%s` not found." % alias_name)
1344
1344
1345 def system(self, cmd):
1345 def system(self, cmd):
1346 """Make a system call, using IPython."""
1346 """Make a system call, using IPython."""
1347 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1347 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1348
1348
1349 def ex(self, cmd):
1349 def ex(self, cmd):
1350 """Execute a normal python statement in user namespace."""
1350 """Execute a normal python statement in user namespace."""
1351 with self.builtin_trap:
1351 with self.builtin_trap:
1352 exec cmd in self.user_global_ns, self.user_ns
1352 exec cmd in self.user_global_ns, self.user_ns
1353
1353
1354 def ev(self, expr):
1354 def ev(self, expr):
1355 """Evaluate python expression expr in user namespace.
1355 """Evaluate python expression expr in user namespace.
1356
1356
1357 Returns the result of evaluation
1357 Returns the result of evaluation
1358 """
1358 """
1359 with self.builtin_trap:
1359 with self.builtin_trap:
1360 result = eval(expr, self.user_global_ns, self.user_ns)
1360 return eval(expr, self.user_global_ns, self.user_ns)
1361 return result
1362
1361
1363 def getoutput(self, cmd):
1362 def getoutput(self, cmd):
1364 return getoutput(self.var_expand(cmd,depth=2),
1363 return getoutput(self.var_expand(cmd,depth=2),
1365 header=self.system_header,
1364 header=self.system_header,
1366 verbose=self.system_verbose)
1365 verbose=self.system_verbose)
1367
1366
1368 def getoutputerror(self, cmd):
1367 def getoutputerror(self, cmd):
1369 return getoutputerror(self.var_expand(cmd,depth=2),
1368 return getoutputerror(self.var_expand(cmd,depth=2),
1370 header=self.system_header,
1369 header=self.system_header,
1371 verbose=self.system_verbose)
1370 verbose=self.system_verbose)
1372
1371
1373 def complete(self, text):
1372 def complete(self, text):
1374 """Return a sorted list of all possible completions on text.
1373 """Return a sorted list of all possible completions on text.
1375
1374
1376 Inputs:
1375 Inputs:
1377
1376
1378 - text: a string of text to be completed on.
1377 - text: a string of text to be completed on.
1379
1378
1380 This is a wrapper around the completion mechanism, similar to what
1379 This is a wrapper around the completion mechanism, similar to what
1381 readline does at the command line when the TAB key is hit. By
1380 readline does at the command line when the TAB key is hit. By
1382 exposing it as a method, it can be used by other non-readline
1381 exposing it as a method, it can be used by other non-readline
1383 environments (such as GUIs) for text completion.
1382 environments (such as GUIs) for text completion.
1384
1383
1385 Simple usage example:
1384 Simple usage example:
1386
1385
1387 In [7]: x = 'hello'
1386 In [7]: x = 'hello'
1388
1387
1389 In [8]: x
1388 In [8]: x
1390 Out[8]: 'hello'
1389 Out[8]: 'hello'
1391
1390
1392 In [9]: print x
1391 In [9]: print x
1393 hello
1392 hello
1394
1393
1395 In [10]: _ip.complete('x.l')
1394 In [10]: _ip.complete('x.l')
1396 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1395 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1397 """
1396 """
1398
1397
1399 # Inject names into __builtin__ so we can complete on the added names.
1398 # Inject names into __builtin__ so we can complete on the added names.
1400 with self.builtin_trap:
1399 with self.builtin_trap:
1401 complete = self.Completer.complete
1400 complete = self.Completer.complete
1402 state = 0
1401 state = 0
1403 # use a dict so we get unique keys, since ipyhton's multiple
1402 # use a dict so we get unique keys, since ipyhton's multiple
1404 # completers can return duplicates. When we make 2.4 a requirement,
1403 # completers can return duplicates. When we make 2.4 a requirement,
1405 # start using sets instead, which are faster.
1404 # start using sets instead, which are faster.
1406 comps = {}
1405 comps = {}
1407 while True:
1406 while True:
1408 newcomp = complete(text,state,line_buffer=text)
1407 newcomp = complete(text,state,line_buffer=text)
1409 if newcomp is None:
1408 if newcomp is None:
1410 break
1409 break
1411 comps[newcomp] = 1
1410 comps[newcomp] = 1
1412 state += 1
1411 state += 1
1413 outcomps = comps.keys()
1412 outcomps = comps.keys()
1414 outcomps.sort()
1413 outcomps.sort()
1415 #print "T:",text,"OC:",outcomps # dbg
1414 #print "T:",text,"OC:",outcomps # dbg
1416 #print "vars:",self.user_ns.keys()
1415 #print "vars:",self.user_ns.keys()
1417 return outcomps
1416 return outcomps
1418
1417
1419 def set_completer_frame(self, frame=None):
1418 def set_completer_frame(self, frame=None):
1420 if frame:
1419 if frame:
1421 self.Completer.namespace = frame.f_locals
1420 self.Completer.namespace = frame.f_locals
1422 self.Completer.global_namespace = frame.f_globals
1421 self.Completer.global_namespace = frame.f_globals
1423 else:
1422 else:
1424 self.Completer.namespace = self.user_ns
1423 self.Completer.namespace = self.user_ns
1425 self.Completer.global_namespace = self.user_global_ns
1424 self.Completer.global_namespace = self.user_global_ns
1426
1425
1427 def init_auto_alias(self):
1426 def init_auto_alias(self):
1428 """Define some aliases automatically.
1427 """Define some aliases automatically.
1429
1428
1430 These are ALL parameter-less aliases"""
1429 These are ALL parameter-less aliases"""
1431
1430
1432 for alias,cmd in self.auto_alias:
1431 for alias,cmd in self.auto_alias:
1433 self.define_alias(alias,cmd)
1432 self.define_alias(alias,cmd)
1434
1433
1435 def alias_table_validate(self,verbose=0):
1434 def alias_table_validate(self,verbose=0):
1436 """Update information about the alias table.
1435 """Update information about the alias table.
1437
1436
1438 In particular, make sure no Python keywords/builtins are in it."""
1437 In particular, make sure no Python keywords/builtins are in it."""
1439
1438
1440 no_alias = self.no_alias
1439 no_alias = self.no_alias
1441 for k in self.alias_table.keys():
1440 for k in self.alias_table.keys():
1442 if k in no_alias:
1441 if k in no_alias:
1443 del self.alias_table[k]
1442 del self.alias_table[k]
1444 if verbose:
1443 if verbose:
1445 print ("Deleting alias <%s>, it's a Python "
1444 print ("Deleting alias <%s>, it's a Python "
1446 "keyword or builtin." % k)
1445 "keyword or builtin." % k)
1447
1446
1448 def set_next_input(self, s):
1447 def set_next_input(self, s):
1449 """ Sets the 'default' input string for the next command line.
1448 """ Sets the 'default' input string for the next command line.
1450
1449
1451 Requires readline.
1450 Requires readline.
1452
1451
1453 Example:
1452 Example:
1454
1453
1455 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1454 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1456 [D:\ipython]|2> Hello Word_ # cursor is here
1455 [D:\ipython]|2> Hello Word_ # cursor is here
1457 """
1456 """
1458
1457
1459 self.rl_next_input = s
1458 self.rl_next_input = s
1460
1459
1461 def set_autoindent(self,value=None):
1460 def set_autoindent(self,value=None):
1462 """Set the autoindent flag, checking for readline support.
1461 """Set the autoindent flag, checking for readline support.
1463
1462
1464 If called with no arguments, it acts as a toggle."""
1463 If called with no arguments, it acts as a toggle."""
1465
1464
1466 if not self.has_readline:
1465 if not self.has_readline:
1467 if os.name == 'posix':
1466 if os.name == 'posix':
1468 warn("The auto-indent feature requires the readline library")
1467 warn("The auto-indent feature requires the readline library")
1469 self.autoindent = 0
1468 self.autoindent = 0
1470 return
1469 return
1471 if value is None:
1470 if value is None:
1472 self.autoindent = not self.autoindent
1471 self.autoindent = not self.autoindent
1473 else:
1472 else:
1474 self.autoindent = value
1473 self.autoindent = value
1475
1474
1476 def atexit_operations(self):
1475 def atexit_operations(self):
1477 """This will be executed at the time of exit.
1476 """This will be executed at the time of exit.
1478
1477
1479 Saving of persistent data should be performed here. """
1478 Saving of persistent data should be performed here. """
1480
1479
1481 #print '*** IPython exit cleanup ***' # dbg
1480 #print '*** IPython exit cleanup ***' # dbg
1482 # input history
1481 # input history
1483 self.savehist()
1482 self.savehist()
1484
1483
1485 # Cleanup all tempfiles left around
1484 # Cleanup all tempfiles left around
1486 for tfile in self.tempfiles:
1485 for tfile in self.tempfiles:
1487 try:
1486 try:
1488 os.unlink(tfile)
1487 os.unlink(tfile)
1489 except OSError:
1488 except OSError:
1490 pass
1489 pass
1491
1490
1492 # Clear all user namespaces to release all references cleanly.
1491 # Clear all user namespaces to release all references cleanly.
1493 self.reset()
1492 self.reset()
1494
1493
1495 # Run user hooks
1494 # Run user hooks
1496 self.hooks.shutdown_hook()
1495 self.hooks.shutdown_hook()
1497
1496
1498 def reset(self):
1497 def reset(self):
1499 """Clear all internal namespaces.
1498 """Clear all internal namespaces.
1500
1499
1501 Note that this is much more aggressive than %reset, since it clears
1500 Note that this is much more aggressive than %reset, since it clears
1502 fully all namespaces, as well as all input/output lists.
1501 fully all namespaces, as well as all input/output lists.
1503 """
1502 """
1504 for ns in self.ns_refs_table:
1503 for ns in self.ns_refs_table:
1505 ns.clear()
1504 ns.clear()
1506
1505
1507 # Clear input and output histories
1506 # Clear input and output histories
1508 self.input_hist[:] = []
1507 self.input_hist[:] = []
1509 self.input_hist_raw[:] = []
1508 self.input_hist_raw[:] = []
1510 self.output_hist.clear()
1509 self.output_hist.clear()
1511 # Restore the user namespaces to minimal usability
1510 # Restore the user namespaces to minimal usability
1512 self.init_user_ns()
1511 self.init_user_ns()
1513
1512
1514 def savehist(self):
1513 def savehist(self):
1515 """Save input history to a file (via readline library)."""
1514 """Save input history to a file (via readline library)."""
1516
1515
1517 if not self.has_readline:
1516 if not self.has_readline:
1518 return
1517 return
1519
1518
1520 try:
1519 try:
1521 self.readline.write_history_file(self.histfile)
1520 self.readline.write_history_file(self.histfile)
1522 except:
1521 except:
1523 print 'Unable to save IPython command history to file: ' + \
1522 print 'Unable to save IPython command history to file: ' + \
1524 `self.histfile`
1523 `self.histfile`
1525
1524
1526 def reloadhist(self):
1525 def reloadhist(self):
1527 """Reload the input history from disk file."""
1526 """Reload the input history from disk file."""
1528
1527
1529 if self.has_readline:
1528 if self.has_readline:
1530 try:
1529 try:
1531 self.readline.clear_history()
1530 self.readline.clear_history()
1532 self.readline.read_history_file(self.shell.histfile)
1531 self.readline.read_history_file(self.shell.histfile)
1533 except AttributeError:
1532 except AttributeError:
1534 pass
1533 pass
1535
1534
1536
1535
1537 def history_saving_wrapper(self, func):
1536 def history_saving_wrapper(self, func):
1538 """ Wrap func for readline history saving
1537 """ Wrap func for readline history saving
1539
1538
1540 Convert func into callable that saves & restores
1539 Convert func into callable that saves & restores
1541 history around the call """
1540 history around the call """
1542
1541
1543 if not self.has_readline:
1542 if not self.has_readline:
1544 return func
1543 return func
1545
1544
1546 def wrapper():
1545 def wrapper():
1547 self.savehist()
1546 self.savehist()
1548 try:
1547 try:
1549 func()
1548 func()
1550 finally:
1549 finally:
1551 readline.read_history_file(self.histfile)
1550 readline.read_history_file(self.histfile)
1552 return wrapper
1551 return wrapper
1553
1552
1554 def pre_readline(self):
1553 def pre_readline(self):
1555 """readline hook to be used at the start of each line.
1554 """readline hook to be used at the start of each line.
1556
1555
1557 Currently it handles auto-indent only."""
1556 Currently it handles auto-indent only."""
1558
1557
1559 #debugx('self.indent_current_nsp','pre_readline:')
1558 #debugx('self.indent_current_nsp','pre_readline:')
1560
1559
1561 if self.rl_do_indent:
1560 if self.rl_do_indent:
1562 self.readline.insert_text(self.indent_current_str())
1561 self.readline.insert_text(self.indent_current_str())
1563 if self.rl_next_input is not None:
1562 if self.rl_next_input is not None:
1564 self.readline.insert_text(self.rl_next_input)
1563 self.readline.insert_text(self.rl_next_input)
1565 self.rl_next_input = None
1564 self.rl_next_input = None
1566
1565
1567 def ask_yes_no(self,prompt,default=True):
1566 def ask_yes_no(self,prompt,default=True):
1568 if self.quiet:
1567 if self.quiet:
1569 return True
1568 return True
1570 return ask_yes_no(prompt,default)
1569 return ask_yes_no(prompt,default)
1571
1570
1572 def new_main_mod(self,ns=None):
1571 def new_main_mod(self,ns=None):
1573 """Return a new 'main' module object for user code execution.
1572 """Return a new 'main' module object for user code execution.
1574 """
1573 """
1575 main_mod = self._user_main_module
1574 main_mod = self._user_main_module
1576 init_fakemod_dict(main_mod,ns)
1575 init_fakemod_dict(main_mod,ns)
1577 return main_mod
1576 return main_mod
1578
1577
1579 def cache_main_mod(self,ns,fname):
1578 def cache_main_mod(self,ns,fname):
1580 """Cache a main module's namespace.
1579 """Cache a main module's namespace.
1581
1580
1582 When scripts are executed via %run, we must keep a reference to the
1581 When scripts are executed via %run, we must keep a reference to the
1583 namespace of their __main__ module (a FakeModule instance) around so
1582 namespace of their __main__ module (a FakeModule instance) around so
1584 that Python doesn't clear it, rendering objects defined therein
1583 that Python doesn't clear it, rendering objects defined therein
1585 useless.
1584 useless.
1586
1585
1587 This method keeps said reference in a private dict, keyed by the
1586 This method keeps said reference in a private dict, keyed by the
1588 absolute path of the module object (which corresponds to the script
1587 absolute path of the module object (which corresponds to the script
1589 path). This way, for multiple executions of the same script we only
1588 path). This way, for multiple executions of the same script we only
1590 keep one copy of the namespace (the last one), thus preventing memory
1589 keep one copy of the namespace (the last one), thus preventing memory
1591 leaks from old references while allowing the objects from the last
1590 leaks from old references while allowing the objects from the last
1592 execution to be accessible.
1591 execution to be accessible.
1593
1592
1594 Note: we can not allow the actual FakeModule instances to be deleted,
1593 Note: we can not allow the actual FakeModule instances to be deleted,
1595 because of how Python tears down modules (it hard-sets all their
1594 because of how Python tears down modules (it hard-sets all their
1596 references to None without regard for reference counts). This method
1595 references to None without regard for reference counts). This method
1597 must therefore make a *copy* of the given namespace, to allow the
1596 must therefore make a *copy* of the given namespace, to allow the
1598 original module's __dict__ to be cleared and reused.
1597 original module's __dict__ to be cleared and reused.
1599
1598
1600
1599
1601 Parameters
1600 Parameters
1602 ----------
1601 ----------
1603 ns : a namespace (a dict, typically)
1602 ns : a namespace (a dict, typically)
1604
1603
1605 fname : str
1604 fname : str
1606 Filename associated with the namespace.
1605 Filename associated with the namespace.
1607
1606
1608 Examples
1607 Examples
1609 --------
1608 --------
1610
1609
1611 In [10]: import IPython
1610 In [10]: import IPython
1612
1611
1613 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1612 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1614
1613
1615 In [12]: IPython.__file__ in _ip._main_ns_cache
1614 In [12]: IPython.__file__ in _ip._main_ns_cache
1616 Out[12]: True
1615 Out[12]: True
1617 """
1616 """
1618 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1617 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1619
1618
1620 def clear_main_mod_cache(self):
1619 def clear_main_mod_cache(self):
1621 """Clear the cache of main modules.
1620 """Clear the cache of main modules.
1622
1621
1623 Mainly for use by utilities like %reset.
1622 Mainly for use by utilities like %reset.
1624
1623
1625 Examples
1624 Examples
1626 --------
1625 --------
1627
1626
1628 In [15]: import IPython
1627 In [15]: import IPython
1629
1628
1630 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1629 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1631
1630
1632 In [17]: len(_ip._main_ns_cache) > 0
1631 In [17]: len(_ip._main_ns_cache) > 0
1633 Out[17]: True
1632 Out[17]: True
1634
1633
1635 In [18]: _ip.clear_main_mod_cache()
1634 In [18]: _ip.clear_main_mod_cache()
1636
1635
1637 In [19]: len(_ip._main_ns_cache) == 0
1636 In [19]: len(_ip._main_ns_cache) == 0
1638 Out[19]: True
1637 Out[19]: True
1639 """
1638 """
1640 self._main_ns_cache.clear()
1639 self._main_ns_cache.clear()
1641
1640
1642 def _should_recompile(self,e):
1641 def _should_recompile(self,e):
1643 """Utility routine for edit_syntax_error"""
1642 """Utility routine for edit_syntax_error"""
1644
1643
1645 if e.filename in ('<ipython console>','<input>','<string>',
1644 if e.filename in ('<ipython console>','<input>','<string>',
1646 '<console>','<BackgroundJob compilation>',
1645 '<console>','<BackgroundJob compilation>',
1647 None):
1646 None):
1648
1647
1649 return False
1648 return False
1650 try:
1649 try:
1651 if (self.autoedit_syntax and
1650 if (self.autoedit_syntax and
1652 not self.ask_yes_no('Return to editor to correct syntax error? '
1651 not self.ask_yes_no('Return to editor to correct syntax error? '
1653 '[Y/n] ','y')):
1652 '[Y/n] ','y')):
1654 return False
1653 return False
1655 except EOFError:
1654 except EOFError:
1656 return False
1655 return False
1657
1656
1658 def int0(x):
1657 def int0(x):
1659 try:
1658 try:
1660 return int(x)
1659 return int(x)
1661 except TypeError:
1660 except TypeError:
1662 return 0
1661 return 0
1663 # always pass integer line and offset values to editor hook
1662 # always pass integer line and offset values to editor hook
1664 try:
1663 try:
1665 self.hooks.fix_error_editor(e.filename,
1664 self.hooks.fix_error_editor(e.filename,
1666 int0(e.lineno),int0(e.offset),e.msg)
1665 int0(e.lineno),int0(e.offset),e.msg)
1667 except TryNext:
1666 except TryNext:
1668 warn('Could not open editor')
1667 warn('Could not open editor')
1669 return False
1668 return False
1670 return True
1669 return True
1671
1670
1672 def edit_syntax_error(self):
1671 def edit_syntax_error(self):
1673 """The bottom half of the syntax error handler called in the main loop.
1672 """The bottom half of the syntax error handler called in the main loop.
1674
1673
1675 Loop until syntax error is fixed or user cancels.
1674 Loop until syntax error is fixed or user cancels.
1676 """
1675 """
1677
1676
1678 while self.SyntaxTB.last_syntax_error:
1677 while self.SyntaxTB.last_syntax_error:
1679 # copy and clear last_syntax_error
1678 # copy and clear last_syntax_error
1680 err = self.SyntaxTB.clear_err_state()
1679 err = self.SyntaxTB.clear_err_state()
1681 if not self._should_recompile(err):
1680 if not self._should_recompile(err):
1682 return
1681 return
1683 try:
1682 try:
1684 # may set last_syntax_error again if a SyntaxError is raised
1683 # may set last_syntax_error again if a SyntaxError is raised
1685 self.safe_execfile(err.filename,self.user_ns)
1684 self.safe_execfile(err.filename,self.user_ns)
1686 except:
1685 except:
1687 self.showtraceback()
1686 self.showtraceback()
1688 else:
1687 else:
1689 try:
1688 try:
1690 f = file(err.filename)
1689 f = file(err.filename)
1691 try:
1690 try:
1692 sys.displayhook(f.read())
1691 sys.displayhook(f.read())
1693 finally:
1692 finally:
1694 f.close()
1693 f.close()
1695 except:
1694 except:
1696 self.showtraceback()
1695 self.showtraceback()
1697
1696
1698 def showsyntaxerror(self, filename=None):
1697 def showsyntaxerror(self, filename=None):
1699 """Display the syntax error that just occurred.
1698 """Display the syntax error that just occurred.
1700
1699
1701 This doesn't display a stack trace because there isn't one.
1700 This doesn't display a stack trace because there isn't one.
1702
1701
1703 If a filename is given, it is stuffed in the exception instead
1702 If a filename is given, it is stuffed in the exception instead
1704 of what was there before (because Python's parser always uses
1703 of what was there before (because Python's parser always uses
1705 "<string>" when reading from a string).
1704 "<string>" when reading from a string).
1706 """
1705 """
1707 etype, value, last_traceback = sys.exc_info()
1706 etype, value, last_traceback = sys.exc_info()
1708
1707
1709 # See note about these variables in showtraceback() below
1708 # See note about these variables in showtraceback() below
1710 sys.last_type = etype
1709 sys.last_type = etype
1711 sys.last_value = value
1710 sys.last_value = value
1712 sys.last_traceback = last_traceback
1711 sys.last_traceback = last_traceback
1713
1712
1714 if filename and etype is SyntaxError:
1713 if filename and etype is SyntaxError:
1715 # Work hard to stuff the correct filename in the exception
1714 # Work hard to stuff the correct filename in the exception
1716 try:
1715 try:
1717 msg, (dummy_filename, lineno, offset, line) = value
1716 msg, (dummy_filename, lineno, offset, line) = value
1718 except:
1717 except:
1719 # Not the format we expect; leave it alone
1718 # Not the format we expect; leave it alone
1720 pass
1719 pass
1721 else:
1720 else:
1722 # Stuff in the right filename
1721 # Stuff in the right filename
1723 try:
1722 try:
1724 # Assume SyntaxError is a class exception
1723 # Assume SyntaxError is a class exception
1725 value = SyntaxError(msg, (filename, lineno, offset, line))
1724 value = SyntaxError(msg, (filename, lineno, offset, line))
1726 except:
1725 except:
1727 # If that failed, assume SyntaxError is a string
1726 # If that failed, assume SyntaxError is a string
1728 value = msg, (filename, lineno, offset, line)
1727 value = msg, (filename, lineno, offset, line)
1729 self.SyntaxTB(etype,value,[])
1728 self.SyntaxTB(etype,value,[])
1730
1729
1731 def debugger(self,force=False):
1730 def debugger(self,force=False):
1732 """Call the pydb/pdb debugger.
1731 """Call the pydb/pdb debugger.
1733
1732
1734 Keywords:
1733 Keywords:
1735
1734
1736 - force(False): by default, this routine checks the instance call_pdb
1735 - force(False): by default, this routine checks the instance call_pdb
1737 flag and does not actually invoke the debugger if the flag is false.
1736 flag and does not actually invoke the debugger if the flag is false.
1738 The 'force' option forces the debugger to activate even if the flag
1737 The 'force' option forces the debugger to activate even if the flag
1739 is false.
1738 is false.
1740 """
1739 """
1741
1740
1742 if not (force or self.call_pdb):
1741 if not (force or self.call_pdb):
1743 return
1742 return
1744
1743
1745 if not hasattr(sys,'last_traceback'):
1744 if not hasattr(sys,'last_traceback'):
1746 error('No traceback has been produced, nothing to debug.')
1745 error('No traceback has been produced, nothing to debug.')
1747 return
1746 return
1748
1747
1749 # use pydb if available
1748 # use pydb if available
1750 if debugger.has_pydb:
1749 if debugger.has_pydb:
1751 from pydb import pm
1750 from pydb import pm
1752 else:
1751 else:
1753 # fallback to our internal debugger
1752 # fallback to our internal debugger
1754 pm = lambda : self.InteractiveTB.debugger(force=True)
1753 pm = lambda : self.InteractiveTB.debugger(force=True)
1755 self.history_saving_wrapper(pm)()
1754 self.history_saving_wrapper(pm)()
1756
1755
1757 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1756 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1758 """Display the exception that just occurred.
1757 """Display the exception that just occurred.
1759
1758
1760 If nothing is known about the exception, this is the method which
1759 If nothing is known about the exception, this is the method which
1761 should be used throughout the code for presenting user tracebacks,
1760 should be used throughout the code for presenting user tracebacks,
1762 rather than directly invoking the InteractiveTB object.
1761 rather than directly invoking the InteractiveTB object.
1763
1762
1764 A specific showsyntaxerror() also exists, but this method can take
1763 A specific showsyntaxerror() also exists, but this method can take
1765 care of calling it if needed, so unless you are explicitly catching a
1764 care of calling it if needed, so unless you are explicitly catching a
1766 SyntaxError exception, don't try to analyze the stack manually and
1765 SyntaxError exception, don't try to analyze the stack manually and
1767 simply call this method."""
1766 simply call this method."""
1768
1767
1769
1768
1770 # Though this won't be called by syntax errors in the input line,
1769 # Though this won't be called by syntax errors in the input line,
1771 # there may be SyntaxError cases whith imported code.
1770 # there may be SyntaxError cases whith imported code.
1772
1771
1773 try:
1772 try:
1774 if exc_tuple is None:
1773 if exc_tuple is None:
1775 etype, value, tb = sys.exc_info()
1774 etype, value, tb = sys.exc_info()
1776 else:
1775 else:
1777 etype, value, tb = exc_tuple
1776 etype, value, tb = exc_tuple
1778
1777
1779 if etype is SyntaxError:
1778 if etype is SyntaxError:
1780 self.showsyntaxerror(filename)
1779 self.showsyntaxerror(filename)
1781 elif etype is UsageError:
1780 elif etype is UsageError:
1782 print "UsageError:", value
1781 print "UsageError:", value
1783 else:
1782 else:
1784 # WARNING: these variables are somewhat deprecated and not
1783 # WARNING: these variables are somewhat deprecated and not
1785 # necessarily safe to use in a threaded environment, but tools
1784 # necessarily safe to use in a threaded environment, but tools
1786 # like pdb depend on their existence, so let's set them. If we
1785 # like pdb depend on their existence, so let's set them. If we
1787 # find problems in the field, we'll need to revisit their use.
1786 # find problems in the field, we'll need to revisit their use.
1788 sys.last_type = etype
1787 sys.last_type = etype
1789 sys.last_value = value
1788 sys.last_value = value
1790 sys.last_traceback = tb
1789 sys.last_traceback = tb
1791
1790
1792 if etype in self.custom_exceptions:
1791 if etype in self.custom_exceptions:
1793 self.CustomTB(etype,value,tb)
1792 self.CustomTB(etype,value,tb)
1794 else:
1793 else:
1795 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1794 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1796 if self.InteractiveTB.call_pdb and self.has_readline:
1795 if self.InteractiveTB.call_pdb and self.has_readline:
1797 # pdb mucks up readline, fix it back
1796 # pdb mucks up readline, fix it back
1798 self.set_completer()
1797 self.set_completer()
1799 except KeyboardInterrupt:
1798 except KeyboardInterrupt:
1800 self.write("\nKeyboardInterrupt\n")
1799 self.write("\nKeyboardInterrupt\n")
1801
1800
1802 def mainloop(self, banner=None):
1801 def mainloop(self, banner=None):
1803 """Start the mainloop.
1802 """Start the mainloop.
1804
1803
1805 If an optional banner argument is given, it will override the
1804 If an optional banner argument is given, it will override the
1806 internally created default banner.
1805 internally created default banner.
1807 """
1806 """
1808
1807
1809 with self.builtin_trap:
1808 with self.builtin_trap:
1810 if self.c: # Emulate Python's -c option
1809 if self.c: # Emulate Python's -c option
1811 self.exec_init_cmd()
1810 self.exec_init_cmd()
1812
1811
1813 if self.display_banner:
1812 if self.display_banner:
1814 if banner is None:
1813 if banner is None:
1815 banner = self.banner
1814 banner = self.banner
1816
1815
1817 # if you run stuff with -c <cmd>, raw hist is not updated
1816 # if you run stuff with -c <cmd>, raw hist is not updated
1818 # ensure that it's in sync
1817 # ensure that it's in sync
1819 if len(self.input_hist) != len (self.input_hist_raw):
1818 if len(self.input_hist) != len (self.input_hist_raw):
1820 self.input_hist_raw = InputList(self.input_hist)
1819 self.input_hist_raw = InputList(self.input_hist)
1821
1820
1822 while 1:
1821 while 1:
1823 try:
1822 try:
1824 self.interact()
1823 self.interact()
1825 #self.interact_with_readline()
1824 #self.interact_with_readline()
1826 # XXX for testing of a readline-decoupled repl loop, call
1825 # XXX for testing of a readline-decoupled repl loop, call
1827 # interact_with_readline above
1826 # interact_with_readline above
1828 break
1827 break
1829 except KeyboardInterrupt:
1828 except KeyboardInterrupt:
1830 # this should not be necessary, but KeyboardInterrupt
1829 # this should not be necessary, but KeyboardInterrupt
1831 # handling seems rather unpredictable...
1830 # handling seems rather unpredictable...
1832 self.write("\nKeyboardInterrupt in interact()\n")
1831 self.write("\nKeyboardInterrupt in interact()\n")
1833
1832
1834 def exec_init_cmd(self):
1833 def exec_init_cmd(self):
1835 """Execute a command given at the command line.
1834 """Execute a command given at the command line.
1836
1835
1837 This emulates Python's -c option."""
1836 This emulates Python's -c option."""
1838
1837
1839 #sys.argv = ['-c']
1838 #sys.argv = ['-c']
1840 self.push_line(self.prefilter(self.c, False))
1839 self.push_line(self.prefilter(self.c, False))
1841 if not self.interactive:
1840 if not self.interactive:
1842 self.ask_exit()
1841 self.ask_exit()
1843
1842
1844 def interact_prompt(self):
1843 def interact_prompt(self):
1845 """ Print the prompt (in read-eval-print loop)
1844 """ Print the prompt (in read-eval-print loop)
1846
1845
1847 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1846 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1848 used in standard IPython flow.
1847 used in standard IPython flow.
1849 """
1848 """
1850 if self.more:
1849 if self.more:
1851 try:
1850 try:
1852 prompt = self.hooks.generate_prompt(True)
1851 prompt = self.hooks.generate_prompt(True)
1853 except:
1852 except:
1854 self.showtraceback()
1853 self.showtraceback()
1855 if self.autoindent:
1854 if self.autoindent:
1856 self.rl_do_indent = True
1855 self.rl_do_indent = True
1857
1856
1858 else:
1857 else:
1859 try:
1858 try:
1860 prompt = self.hooks.generate_prompt(False)
1859 prompt = self.hooks.generate_prompt(False)
1861 except:
1860 except:
1862 self.showtraceback()
1861 self.showtraceback()
1863 self.write(prompt)
1862 self.write(prompt)
1864
1863
1865 def interact_handle_input(self,line):
1864 def interact_handle_input(self,line):
1866 """ Handle the input line (in read-eval-print loop)
1865 """ Handle the input line (in read-eval-print loop)
1867
1866
1868 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1867 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1869 used in standard IPython flow.
1868 used in standard IPython flow.
1870 """
1869 """
1871 if line.lstrip() == line:
1870 if line.lstrip() == line:
1872 self.shadowhist.add(line.strip())
1871 self.shadowhist.add(line.strip())
1873 lineout = self.prefilter(line,self.more)
1872 lineout = self.prefilter(line,self.more)
1874
1873
1875 if line.strip():
1874 if line.strip():
1876 if self.more:
1875 if self.more:
1877 self.input_hist_raw[-1] += '%s\n' % line
1876 self.input_hist_raw[-1] += '%s\n' % line
1878 else:
1877 else:
1879 self.input_hist_raw.append('%s\n' % line)
1878 self.input_hist_raw.append('%s\n' % line)
1880
1879
1881
1880
1882 self.more = self.push_line(lineout)
1881 self.more = self.push_line(lineout)
1883 if (self.SyntaxTB.last_syntax_error and
1882 if (self.SyntaxTB.last_syntax_error and
1884 self.autoedit_syntax):
1883 self.autoedit_syntax):
1885 self.edit_syntax_error()
1884 self.edit_syntax_error()
1886
1885
1887 def interact_with_readline(self):
1886 def interact_with_readline(self):
1888 """ Demo of using interact_handle_input, interact_prompt
1887 """ Demo of using interact_handle_input, interact_prompt
1889
1888
1890 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1889 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1891 it should work like this.
1890 it should work like this.
1892 """
1891 """
1893 self.readline_startup_hook(self.pre_readline)
1892 self.readline_startup_hook(self.pre_readline)
1894 while not self.exit_now:
1893 while not self.exit_now:
1895 self.interact_prompt()
1894 self.interact_prompt()
1896 if self.more:
1895 if self.more:
1897 self.rl_do_indent = True
1896 self.rl_do_indent = True
1898 else:
1897 else:
1899 self.rl_do_indent = False
1898 self.rl_do_indent = False
1900 line = raw_input_original().decode(self.stdin_encoding)
1899 line = raw_input_original().decode(self.stdin_encoding)
1901 self.interact_handle_input(line)
1900 self.interact_handle_input(line)
1902
1901
1903 def interact(self, banner=None):
1902 def interact(self, banner=None):
1904 """Closely emulate the interactive Python console."""
1903 """Closely emulate the interactive Python console."""
1905
1904
1906 # batch run -> do not interact
1905 # batch run -> do not interact
1907 if self.exit_now:
1906 if self.exit_now:
1908 return
1907 return
1909
1908
1910 if self.display_banner:
1909 if self.display_banner:
1911 if banner is None:
1910 if banner is None:
1912 banner = self.banner
1911 banner = self.banner
1913 self.write(banner)
1912 self.write(banner)
1914
1913
1915 more = 0
1914 more = 0
1916
1915
1917 # Mark activity in the builtins
1916 # Mark activity in the builtins
1918 __builtin__.__dict__['__IPYTHON__active'] += 1
1917 __builtin__.__dict__['__IPYTHON__active'] += 1
1919
1918
1920 if self.has_readline:
1919 if self.has_readline:
1921 self.readline_startup_hook(self.pre_readline)
1920 self.readline_startup_hook(self.pre_readline)
1922 # exit_now is set by a call to %Exit or %Quit, through the
1921 # exit_now is set by a call to %Exit or %Quit, through the
1923 # ask_exit callback.
1922 # ask_exit callback.
1924
1923
1925 while not self.exit_now:
1924 while not self.exit_now:
1926 self.hooks.pre_prompt_hook()
1925 self.hooks.pre_prompt_hook()
1927 if more:
1926 if more:
1928 try:
1927 try:
1929 prompt = self.hooks.generate_prompt(True)
1928 prompt = self.hooks.generate_prompt(True)
1930 except:
1929 except:
1931 self.showtraceback()
1930 self.showtraceback()
1932 if self.autoindent:
1931 if self.autoindent:
1933 self.rl_do_indent = True
1932 self.rl_do_indent = True
1934
1933
1935 else:
1934 else:
1936 try:
1935 try:
1937 prompt = self.hooks.generate_prompt(False)
1936 prompt = self.hooks.generate_prompt(False)
1938 except:
1937 except:
1939 self.showtraceback()
1938 self.showtraceback()
1940 try:
1939 try:
1941 line = self.raw_input(prompt, more)
1940 line = self.raw_input(prompt, more)
1942 if self.exit_now:
1941 if self.exit_now:
1943 # quick exit on sys.std[in|out] close
1942 # quick exit on sys.std[in|out] close
1944 break
1943 break
1945 if self.autoindent:
1944 if self.autoindent:
1946 self.rl_do_indent = False
1945 self.rl_do_indent = False
1947
1946
1948 except KeyboardInterrupt:
1947 except KeyboardInterrupt:
1949 #double-guard against keyboardinterrupts during kbdint handling
1948 #double-guard against keyboardinterrupts during kbdint handling
1950 try:
1949 try:
1951 self.write('\nKeyboardInterrupt\n')
1950 self.write('\nKeyboardInterrupt\n')
1952 self.resetbuffer()
1951 self.resetbuffer()
1953 # keep cache in sync with the prompt counter:
1952 # keep cache in sync with the prompt counter:
1954 self.outputcache.prompt_count -= 1
1953 self.outputcache.prompt_count -= 1
1955
1954
1956 if self.autoindent:
1955 if self.autoindent:
1957 self.indent_current_nsp = 0
1956 self.indent_current_nsp = 0
1958 more = 0
1957 more = 0
1959 except KeyboardInterrupt:
1958 except KeyboardInterrupt:
1960 pass
1959 pass
1961 except EOFError:
1960 except EOFError:
1962 if self.autoindent:
1961 if self.autoindent:
1963 self.rl_do_indent = False
1962 self.rl_do_indent = False
1964 self.readline_startup_hook(None)
1963 self.readline_startup_hook(None)
1965 self.write('\n')
1964 self.write('\n')
1966 self.exit()
1965 self.exit()
1967 except bdb.BdbQuit:
1966 except bdb.BdbQuit:
1968 warn('The Python debugger has exited with a BdbQuit exception.\n'
1967 warn('The Python debugger has exited with a BdbQuit exception.\n'
1969 'Because of how pdb handles the stack, it is impossible\n'
1968 'Because of how pdb handles the stack, it is impossible\n'
1970 'for IPython to properly format this particular exception.\n'
1969 'for IPython to properly format this particular exception.\n'
1971 'IPython will resume normal operation.')
1970 'IPython will resume normal operation.')
1972 except:
1971 except:
1973 # exceptions here are VERY RARE, but they can be triggered
1972 # exceptions here are VERY RARE, but they can be triggered
1974 # asynchronously by signal handlers, for example.
1973 # asynchronously by signal handlers, for example.
1975 self.showtraceback()
1974 self.showtraceback()
1976 else:
1975 else:
1977 more = self.push_line(line)
1976 more = self.push_line(line)
1978 if (self.SyntaxTB.last_syntax_error and
1977 if (self.SyntaxTB.last_syntax_error and
1979 self.autoedit_syntax):
1978 self.autoedit_syntax):
1980 self.edit_syntax_error()
1979 self.edit_syntax_error()
1981
1980
1982 # We are off again...
1981 # We are off again...
1983 __builtin__.__dict__['__IPYTHON__active'] -= 1
1982 __builtin__.__dict__['__IPYTHON__active'] -= 1
1984
1983
1985 def excepthook(self, etype, value, tb):
1984 def excepthook(self, etype, value, tb):
1986 """One more defense for GUI apps that call sys.excepthook.
1985 """One more defense for GUI apps that call sys.excepthook.
1987
1986
1988 GUI frameworks like wxPython trap exceptions and call
1987 GUI frameworks like wxPython trap exceptions and call
1989 sys.excepthook themselves. I guess this is a feature that
1988 sys.excepthook themselves. I guess this is a feature that
1990 enables them to keep running after exceptions that would
1989 enables them to keep running after exceptions that would
1991 otherwise kill their mainloop. This is a bother for IPython
1990 otherwise kill their mainloop. This is a bother for IPython
1992 which excepts to catch all of the program exceptions with a try:
1991 which excepts to catch all of the program exceptions with a try:
1993 except: statement.
1992 except: statement.
1994
1993
1995 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1994 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1996 any app directly invokes sys.excepthook, it will look to the user like
1995 any app directly invokes sys.excepthook, it will look to the user like
1997 IPython crashed. In order to work around this, we can disable the
1996 IPython crashed. In order to work around this, we can disable the
1998 CrashHandler and replace it with this excepthook instead, which prints a
1997 CrashHandler and replace it with this excepthook instead, which prints a
1999 regular traceback using our InteractiveTB. In this fashion, apps which
1998 regular traceback using our InteractiveTB. In this fashion, apps which
2000 call sys.excepthook will generate a regular-looking exception from
1999 call sys.excepthook will generate a regular-looking exception from
2001 IPython, and the CrashHandler will only be triggered by real IPython
2000 IPython, and the CrashHandler will only be triggered by real IPython
2002 crashes.
2001 crashes.
2003
2002
2004 This hook should be used sparingly, only in places which are not likely
2003 This hook should be used sparingly, only in places which are not likely
2005 to be true IPython errors.
2004 to be true IPython errors.
2006 """
2005 """
2007 self.showtraceback((etype,value,tb),tb_offset=0)
2006 self.showtraceback((etype,value,tb),tb_offset=0)
2008
2007
2009 def expand_alias(self, line):
2008 def expand_alias(self, line):
2010 """ Expand an alias in the command line
2009 """ Expand an alias in the command line
2011
2010
2012 Returns the provided command line, possibly with the first word
2011 Returns the provided command line, possibly with the first word
2013 (command) translated according to alias expansion rules.
2012 (command) translated according to alias expansion rules.
2014
2013
2015 [ipython]|16> _ip.expand_aliases("np myfile.txt")
2014 [ipython]|16> _ip.expand_aliases("np myfile.txt")
2016 <16> 'q:/opt/np/notepad++.exe myfile.txt'
2015 <16> 'q:/opt/np/notepad++.exe myfile.txt'
2017 """
2016 """
2018
2017
2019 pre,fn,rest = self.split_user_input(line)
2018 pre,fn,rest = self.split_user_input(line)
2020 res = pre + self.expand_aliases(fn, rest)
2019 res = pre + self.expand_aliases(fn, rest)
2021 return res
2020 return res
2022
2021
2023 def expand_aliases(self, fn, rest):
2022 def expand_aliases(self, fn, rest):
2024 """Expand multiple levels of aliases:
2023 """Expand multiple levels of aliases:
2025
2024
2026 if:
2025 if:
2027
2026
2028 alias foo bar /tmp
2027 alias foo bar /tmp
2029 alias baz foo
2028 alias baz foo
2030
2029
2031 then:
2030 then:
2032
2031
2033 baz huhhahhei -> bar /tmp huhhahhei
2032 baz huhhahhei -> bar /tmp huhhahhei
2034
2033
2035 """
2034 """
2036 line = fn + " " + rest
2035 line = fn + " " + rest
2037
2036
2038 done = set()
2037 done = set()
2039 while 1:
2038 while 1:
2040 pre,fn,rest = prefilter.splitUserInput(line,
2039 pre,fn,rest = prefilter.splitUserInput(line,
2041 prefilter.shell_line_split)
2040 prefilter.shell_line_split)
2042 if fn in self.alias_table:
2041 if fn in self.alias_table:
2043 if fn in done:
2042 if fn in done:
2044 warn("Cyclic alias definition, repeated '%s'" % fn)
2043 warn("Cyclic alias definition, repeated '%s'" % fn)
2045 return ""
2044 return ""
2046 done.add(fn)
2045 done.add(fn)
2047
2046
2048 l2 = self.transform_alias(fn,rest)
2047 l2 = self.transform_alias(fn,rest)
2049 # dir -> dir
2048 # dir -> dir
2050 # print "alias",line, "->",l2 #dbg
2049 # print "alias",line, "->",l2 #dbg
2051 if l2 == line:
2050 if l2 == line:
2052 break
2051 break
2053 # ls -> ls -F should not recurse forever
2052 # ls -> ls -F should not recurse forever
2054 if l2.split(None,1)[0] == line.split(None,1)[0]:
2053 if l2.split(None,1)[0] == line.split(None,1)[0]:
2055 line = l2
2054 line = l2
2056 break
2055 break
2057
2056
2058 line=l2
2057 line=l2
2059
2058
2060
2059
2061 # print "al expand to",line #dbg
2060 # print "al expand to",line #dbg
2062 else:
2061 else:
2063 break
2062 break
2064
2063
2065 return line
2064 return line
2066
2065
2067 def transform_alias(self, alias,rest=''):
2066 def transform_alias(self, alias,rest=''):
2068 """ Transform alias to system command string.
2067 """ Transform alias to system command string.
2069 """
2068 """
2070 trg = self.alias_table[alias]
2069 trg = self.alias_table[alias]
2071
2070
2072 nargs,cmd = trg
2071 nargs,cmd = trg
2073 # print trg #dbg
2072 # print trg #dbg
2074 if ' ' in cmd and os.path.isfile(cmd):
2073 if ' ' in cmd and os.path.isfile(cmd):
2075 cmd = '"%s"' % cmd
2074 cmd = '"%s"' % cmd
2076
2075
2077 # Expand the %l special to be the user's input line
2076 # Expand the %l special to be the user's input line
2078 if cmd.find('%l') >= 0:
2077 if cmd.find('%l') >= 0:
2079 cmd = cmd.replace('%l',rest)
2078 cmd = cmd.replace('%l',rest)
2080 rest = ''
2079 rest = ''
2081 if nargs==0:
2080 if nargs==0:
2082 # Simple, argument-less aliases
2081 # Simple, argument-less aliases
2083 cmd = '%s %s' % (cmd,rest)
2082 cmd = '%s %s' % (cmd,rest)
2084 else:
2083 else:
2085 # Handle aliases with positional arguments
2084 # Handle aliases with positional arguments
2086 args = rest.split(None,nargs)
2085 args = rest.split(None,nargs)
2087 if len(args)< nargs:
2086 if len(args)< nargs:
2088 error('Alias <%s> requires %s arguments, %s given.' %
2087 error('Alias <%s> requires %s arguments, %s given.' %
2089 (alias,nargs,len(args)))
2088 (alias,nargs,len(args)))
2090 return None
2089 return None
2091 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2090 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2092 # Now call the macro, evaluating in the user's namespace
2091 # Now call the macro, evaluating in the user's namespace
2093 #print 'new command: <%r>' % cmd # dbg
2092 #print 'new command: <%r>' % cmd # dbg
2094 return cmd
2093 return cmd
2095
2094
2096 def call_alias(self,alias,rest=''):
2095 def call_alias(self,alias,rest=''):
2097 """Call an alias given its name and the rest of the line.
2096 """Call an alias given its name and the rest of the line.
2098
2097
2099 This is only used to provide backwards compatibility for users of
2098 This is only used to provide backwards compatibility for users of
2100 ipalias(), use of which is not recommended for anymore."""
2099 ipalias(), use of which is not recommended for anymore."""
2101
2100
2102 # Now call the macro, evaluating in the user's namespace
2101 # Now call the macro, evaluating in the user's namespace
2103 cmd = self.transform_alias(alias, rest)
2102 cmd = self.transform_alias(alias, rest)
2104 try:
2103 try:
2105 self.system(cmd)
2104 self.system(cmd)
2106 except:
2105 except:
2107 self.showtraceback()
2106 self.showtraceback()
2108
2107
2109 def indent_current_str(self):
2108 def indent_current_str(self):
2110 """return the current level of indentation as a string"""
2109 """return the current level of indentation as a string"""
2111 return self.indent_current_nsp * ' '
2110 return self.indent_current_nsp * ' '
2112
2111
2113 def autoindent_update(self,line):
2112 def autoindent_update(self,line):
2114 """Keep track of the indent level."""
2113 """Keep track of the indent level."""
2115
2114
2116 #debugx('line')
2115 #debugx('line')
2117 #debugx('self.indent_current_nsp')
2116 #debugx('self.indent_current_nsp')
2118 if self.autoindent:
2117 if self.autoindent:
2119 if line:
2118 if line:
2120 inisp = num_ini_spaces(line)
2119 inisp = num_ini_spaces(line)
2121 if inisp < self.indent_current_nsp:
2120 if inisp < self.indent_current_nsp:
2122 self.indent_current_nsp = inisp
2121 self.indent_current_nsp = inisp
2123
2122
2124 if line[-1] == ':':
2123 if line[-1] == ':':
2125 self.indent_current_nsp += 4
2124 self.indent_current_nsp += 4
2126 elif dedent_re.match(line):
2125 elif dedent_re.match(line):
2127 self.indent_current_nsp -= 4
2126 self.indent_current_nsp -= 4
2128 else:
2127 else:
2129 self.indent_current_nsp = 0
2128 self.indent_current_nsp = 0
2130
2129
2131 def push(self, variables, interactive=True):
2130 def push(self, variables, interactive=True):
2132 """Inject a group of variables into the IPython user namespace.
2131 """Inject a group of variables into the IPython user namespace.
2133
2132
2134 Parameters
2133 Parameters
2135 ----------
2134 ----------
2136 variables : dict, str or list/tuple of str
2135 variables : dict, str or list/tuple of str
2137 The variables to inject into the user's namespace. If a dict,
2136 The variables to inject into the user's namespace. If a dict,
2138 a simple update is done. If a str, the string is assumed to
2137 a simple update is done. If a str, the string is assumed to
2139 have variable names separated by spaces. A list/tuple of str
2138 have variable names separated by spaces. A list/tuple of str
2140 can also be used to give the variable names. If just the variable
2139 can also be used to give the variable names. If just the variable
2141 names are give (list/tuple/str) then the variable values looked
2140 names are give (list/tuple/str) then the variable values looked
2142 up in the callers frame.
2141 up in the callers frame.
2143 interactive : bool
2142 interactive : bool
2144 If True (default), the variables will be listed with the ``who``
2143 If True (default), the variables will be listed with the ``who``
2145 magic.
2144 magic.
2146 """
2145 """
2147 vdict = None
2146 vdict = None
2148
2147
2149 # We need a dict of name/value pairs to do namespace updates.
2148 # We need a dict of name/value pairs to do namespace updates.
2150 if isinstance(variables, dict):
2149 if isinstance(variables, dict):
2151 vdict = variables
2150 vdict = variables
2152 elif isinstance(variables, (basestring, list, tuple)):
2151 elif isinstance(variables, (basestring, list, tuple)):
2153 if isinstance(variables, basestring):
2152 if isinstance(variables, basestring):
2154 vlist = variables.split()
2153 vlist = variables.split()
2155 else:
2154 else:
2156 vlist = variables
2155 vlist = variables
2157 vdict = {}
2156 vdict = {}
2158 cf = sys._getframe(1)
2157 cf = sys._getframe(1)
2159 for name in vlist:
2158 for name in vlist:
2160 try:
2159 try:
2161 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
2160 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
2162 except:
2161 except:
2163 print ('Could not get variable %s from %s' %
2162 print ('Could not get variable %s from %s' %
2164 (name,cf.f_code.co_name))
2163 (name,cf.f_code.co_name))
2165 else:
2164 else:
2166 raise ValueError('variables must be a dict/str/list/tuple')
2165 raise ValueError('variables must be a dict/str/list/tuple')
2167
2166
2168 # Propagate variables to user namespace
2167 # Propagate variables to user namespace
2169 self.user_ns.update(vdict)
2168 self.user_ns.update(vdict)
2170
2169
2171 # And configure interactive visibility
2170 # And configure interactive visibility
2172 config_ns = self.user_config_ns
2171 config_ns = self.user_config_ns
2173 if interactive:
2172 if interactive:
2174 for name, val in vdict.iteritems():
2173 for name, val in vdict.iteritems():
2175 config_ns.pop(name, None)
2174 config_ns.pop(name, None)
2176 else:
2175 else:
2177 for name,val in vdict.iteritems():
2176 for name,val in vdict.iteritems():
2178 config_ns[name] = val
2177 config_ns[name] = val
2179
2178
2180 def cleanup_ipy_script(self, script):
2179 def cleanup_ipy_script(self, script):
2181 """Make a script safe for self.runlines()
2180 """Make a script safe for self.runlines()
2182
2181
2183 Notes
2182 Notes
2184 -----
2183 -----
2185 This was copied over from the old ipapi and probably can be done
2184 This was copied over from the old ipapi and probably can be done
2186 away with once we move to block based interpreter.
2185 away with once we move to block based interpreter.
2187
2186
2188 - Removes empty lines Suffixes all indented blocks that end with
2187 - Removes empty lines Suffixes all indented blocks that end with
2189 - unindented lines with empty lines
2188 - unindented lines with empty lines
2190 """
2189 """
2191
2190
2192 res = []
2191 res = []
2193 lines = script.splitlines()
2192 lines = script.splitlines()
2194
2193
2195 level = 0
2194 level = 0
2196 for l in lines:
2195 for l in lines:
2197 lstripped = l.lstrip()
2196 lstripped = l.lstrip()
2198 stripped = l.strip()
2197 stripped = l.strip()
2199 if not stripped:
2198 if not stripped:
2200 continue
2199 continue
2201 newlevel = len(l) - len(lstripped)
2200 newlevel = len(l) - len(lstripped)
2202 def is_secondary_block_start(s):
2201 def is_secondary_block_start(s):
2203 if not s.endswith(':'):
2202 if not s.endswith(':'):
2204 return False
2203 return False
2205 if (s.startswith('elif') or
2204 if (s.startswith('elif') or
2206 s.startswith('else') or
2205 s.startswith('else') or
2207 s.startswith('except') or
2206 s.startswith('except') or
2208 s.startswith('finally')):
2207 s.startswith('finally')):
2209 return True
2208 return True
2210
2209
2211 if level > 0 and newlevel == 0 and \
2210 if level > 0 and newlevel == 0 and \
2212 not is_secondary_block_start(stripped):
2211 not is_secondary_block_start(stripped):
2213 # add empty line
2212 # add empty line
2214 res.append('')
2213 res.append('')
2215
2214
2216 res.append(l)
2215 res.append(l)
2217 level = newlevel
2216 level = newlevel
2218 return '\n'.join(res) + '\n'
2217 return '\n'.join(res) + '\n'
2219
2218
2220 def runlines(self, lines, clean=False):
2219 def runlines(self, lines, clean=False):
2221 """Run a string of one or more lines of source.
2220 """Run a string of one or more lines of source.
2222
2221
2223 This method is capable of running a string containing multiple source
2222 This method is capable of running a string containing multiple source
2224 lines, as if they had been entered at the IPython prompt. Since it
2223 lines, as if they had been entered at the IPython prompt. Since it
2225 exposes IPython's processing machinery, the given strings can contain
2224 exposes IPython's processing machinery, the given strings can contain
2226 magic calls (%magic), special shell access (!cmd), etc.
2225 magic calls (%magic), special shell access (!cmd), etc.
2227 """
2226 """
2228
2227
2229 if isinstance(lines, (list, tuple)):
2228 if isinstance(lines, (list, tuple)):
2230 lines = '\n'.join(lines)
2229 lines = '\n'.join(lines)
2231
2230
2232 if clean:
2231 if clean:
2233 lines = self.cleanup_ipy_script(lines)
2232 lines = self.cleanup_ipy_script(lines)
2234
2233
2235 # We must start with a clean buffer, in case this is run from an
2234 # We must start with a clean buffer, in case this is run from an
2236 # interactive IPython session (via a magic, for example).
2235 # interactive IPython session (via a magic, for example).
2237 self.resetbuffer()
2236 self.resetbuffer()
2238 lines = lines.splitlines()
2237 lines = lines.splitlines()
2239 more = 0
2238 more = 0
2240
2239
2241 with self.builtin_trap:
2240 with self.builtin_trap:
2242 for line in lines:
2241 for line in lines:
2243 # skip blank lines so we don't mess up the prompt counter, but do
2242 # skip blank lines so we don't mess up the prompt counter, but do
2244 # NOT skip even a blank line if we are in a code block (more is
2243 # NOT skip even a blank line if we are in a code block (more is
2245 # true)
2244 # true)
2246
2245
2247 if line or more:
2246 if line or more:
2248 # push to raw history, so hist line numbers stay in sync
2247 # push to raw history, so hist line numbers stay in sync
2249 self.input_hist_raw.append("# " + line + "\n")
2248 self.input_hist_raw.append("# " + line + "\n")
2250 more = self.push_line(self.prefilter(line,more))
2249 more = self.push_line(self.prefilter(line,more))
2251 # IPython's runsource returns None if there was an error
2250 # IPython's runsource returns None if there was an error
2252 # compiling the code. This allows us to stop processing right
2251 # compiling the code. This allows us to stop processing right
2253 # away, so the user gets the error message at the right place.
2252 # away, so the user gets the error message at the right place.
2254 if more is None:
2253 if more is None:
2255 break
2254 break
2256 else:
2255 else:
2257 self.input_hist_raw.append("\n")
2256 self.input_hist_raw.append("\n")
2258 # final newline in case the input didn't have it, so that the code
2257 # final newline in case the input didn't have it, so that the code
2259 # actually does get executed
2258 # actually does get executed
2260 if more:
2259 if more:
2261 self.push_line('\n')
2260 self.push_line('\n')
2262
2261
2263 def runsource(self, source, filename='<input>', symbol='single'):
2262 def runsource(self, source, filename='<input>', symbol='single'):
2264 """Compile and run some source in the interpreter.
2263 """Compile and run some source in the interpreter.
2265
2264
2266 Arguments are as for compile_command().
2265 Arguments are as for compile_command().
2267
2266
2268 One several things can happen:
2267 One several things can happen:
2269
2268
2270 1) The input is incorrect; compile_command() raised an
2269 1) The input is incorrect; compile_command() raised an
2271 exception (SyntaxError or OverflowError). A syntax traceback
2270 exception (SyntaxError or OverflowError). A syntax traceback
2272 will be printed by calling the showsyntaxerror() method.
2271 will be printed by calling the showsyntaxerror() method.
2273
2272
2274 2) The input is incomplete, and more input is required;
2273 2) The input is incomplete, and more input is required;
2275 compile_command() returned None. Nothing happens.
2274 compile_command() returned None. Nothing happens.
2276
2275
2277 3) The input is complete; compile_command() returned a code
2276 3) The input is complete; compile_command() returned a code
2278 object. The code is executed by calling self.runcode() (which
2277 object. The code is executed by calling self.runcode() (which
2279 also handles run-time exceptions, except for SystemExit).
2278 also handles run-time exceptions, except for SystemExit).
2280
2279
2281 The return value is:
2280 The return value is:
2282
2281
2283 - True in case 2
2282 - True in case 2
2284
2283
2285 - False in the other cases, unless an exception is raised, where
2284 - False in the other cases, unless an exception is raised, where
2286 None is returned instead. This can be used by external callers to
2285 None is returned instead. This can be used by external callers to
2287 know whether to continue feeding input or not.
2286 know whether to continue feeding input or not.
2288
2287
2289 The return value can be used to decide whether to use sys.ps1 or
2288 The return value can be used to decide whether to use sys.ps1 or
2290 sys.ps2 to prompt the next line."""
2289 sys.ps2 to prompt the next line."""
2291
2290
2292 # if the source code has leading blanks, add 'if 1:\n' to it
2291 # if the source code has leading blanks, add 'if 1:\n' to it
2293 # this allows execution of indented pasted code. It is tempting
2292 # this allows execution of indented pasted code. It is tempting
2294 # to add '\n' at the end of source to run commands like ' a=1'
2293 # to add '\n' at the end of source to run commands like ' a=1'
2295 # directly, but this fails for more complicated scenarios
2294 # directly, but this fails for more complicated scenarios
2296 source=source.encode(self.stdin_encoding)
2295 source=source.encode(self.stdin_encoding)
2297 if source[:1] in [' ', '\t']:
2296 if source[:1] in [' ', '\t']:
2298 source = 'if 1:\n%s' % source
2297 source = 'if 1:\n%s' % source
2299
2298
2300 try:
2299 try:
2301 code = self.compile(source,filename,symbol)
2300 code = self.compile(source,filename,symbol)
2302 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2301 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2303 # Case 1
2302 # Case 1
2304 self.showsyntaxerror(filename)
2303 self.showsyntaxerror(filename)
2305 return None
2304 return None
2306
2305
2307 if code is None:
2306 if code is None:
2308 # Case 2
2307 # Case 2
2309 return True
2308 return True
2310
2309
2311 # Case 3
2310 # Case 3
2312 # We store the code object so that threaded shells and
2311 # We store the code object so that threaded shells and
2313 # custom exception handlers can access all this info if needed.
2312 # custom exception handlers can access all this info if needed.
2314 # The source corresponding to this can be obtained from the
2313 # The source corresponding to this can be obtained from the
2315 # buffer attribute as '\n'.join(self.buffer).
2314 # buffer attribute as '\n'.join(self.buffer).
2316 self.code_to_run = code
2315 self.code_to_run = code
2317 # now actually execute the code object
2316 # now actually execute the code object
2318 if self.runcode(code) == 0:
2317 if self.runcode(code) == 0:
2319 return False
2318 return False
2320 else:
2319 else:
2321 return None
2320 return None
2322
2321
2323 def runcode(self,code_obj):
2322 def runcode(self,code_obj):
2324 """Execute a code object.
2323 """Execute a code object.
2325
2324
2326 When an exception occurs, self.showtraceback() is called to display a
2325 When an exception occurs, self.showtraceback() is called to display a
2327 traceback.
2326 traceback.
2328
2327
2329 Return value: a flag indicating whether the code to be run completed
2328 Return value: a flag indicating whether the code to be run completed
2330 successfully:
2329 successfully:
2331
2330
2332 - 0: successful execution.
2331 - 0: successful execution.
2333 - 1: an error occurred.
2332 - 1: an error occurred.
2334 """
2333 """
2335
2334
2336 # Set our own excepthook in case the user code tries to call it
2335 # Set our own excepthook in case the user code tries to call it
2337 # directly, so that the IPython crash handler doesn't get triggered
2336 # directly, so that the IPython crash handler doesn't get triggered
2338 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2337 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2339
2338
2340 # we save the original sys.excepthook in the instance, in case config
2339 # we save the original sys.excepthook in the instance, in case config
2341 # code (such as magics) needs access to it.
2340 # code (such as magics) needs access to it.
2342 self.sys_excepthook = old_excepthook
2341 self.sys_excepthook = old_excepthook
2343 outflag = 1 # happens in more places, so it's easier as default
2342 outflag = 1 # happens in more places, so it's easier as default
2344 try:
2343 try:
2345 try:
2344 try:
2346 self.hooks.pre_runcode_hook()
2345 self.hooks.pre_runcode_hook()
2347 exec code_obj in self.user_global_ns, self.user_ns
2346 exec code_obj in self.user_global_ns, self.user_ns
2348 finally:
2347 finally:
2349 # Reset our crash handler in place
2348 # Reset our crash handler in place
2350 sys.excepthook = old_excepthook
2349 sys.excepthook = old_excepthook
2351 except SystemExit:
2350 except SystemExit:
2352 self.resetbuffer()
2351 self.resetbuffer()
2353 self.showtraceback()
2352 self.showtraceback()
2354 warn("Type %exit or %quit to exit IPython "
2353 warn("Type %exit or %quit to exit IPython "
2355 "(%Exit or %Quit do so unconditionally).",level=1)
2354 "(%Exit or %Quit do so unconditionally).",level=1)
2356 except self.custom_exceptions:
2355 except self.custom_exceptions:
2357 etype,value,tb = sys.exc_info()
2356 etype,value,tb = sys.exc_info()
2358 self.CustomTB(etype,value,tb)
2357 self.CustomTB(etype,value,tb)
2359 except:
2358 except:
2360 self.showtraceback()
2359 self.showtraceback()
2361 else:
2360 else:
2362 outflag = 0
2361 outflag = 0
2363 if softspace(sys.stdout, 0):
2362 if softspace(sys.stdout, 0):
2364 print
2363 print
2365 # Flush out code object which has been run (and source)
2364 # Flush out code object which has been run (and source)
2366 self.code_to_run = None
2365 self.code_to_run = None
2367 return outflag
2366 return outflag
2368
2367
2369 def push_line(self, line):
2368 def push_line(self, line):
2370 """Push a line to the interpreter.
2369 """Push a line to the interpreter.
2371
2370
2372 The line should not have a trailing newline; it may have
2371 The line should not have a trailing newline; it may have
2373 internal newlines. The line is appended to a buffer and the
2372 internal newlines. The line is appended to a buffer and the
2374 interpreter's runsource() method is called with the
2373 interpreter's runsource() method is called with the
2375 concatenated contents of the buffer as source. If this
2374 concatenated contents of the buffer as source. If this
2376 indicates that the command was executed or invalid, the buffer
2375 indicates that the command was executed or invalid, the buffer
2377 is reset; otherwise, the command is incomplete, and the buffer
2376 is reset; otherwise, the command is incomplete, and the buffer
2378 is left as it was after the line was appended. The return
2377 is left as it was after the line was appended. The return
2379 value is 1 if more input is required, 0 if the line was dealt
2378 value is 1 if more input is required, 0 if the line was dealt
2380 with in some way (this is the same as runsource()).
2379 with in some way (this is the same as runsource()).
2381 """
2380 """
2382
2381
2383 # autoindent management should be done here, and not in the
2382 # autoindent management should be done here, and not in the
2384 # interactive loop, since that one is only seen by keyboard input. We
2383 # interactive loop, since that one is only seen by keyboard input. We
2385 # need this done correctly even for code run via runlines (which uses
2384 # need this done correctly even for code run via runlines (which uses
2386 # push).
2385 # push).
2387
2386
2388 #print 'push line: <%s>' % line # dbg
2387 #print 'push line: <%s>' % line # dbg
2389 for subline in line.splitlines():
2388 for subline in line.splitlines():
2390 self.autoindent_update(subline)
2389 self.autoindent_update(subline)
2391 self.buffer.append(line)
2390 self.buffer.append(line)
2392 more = self.runsource('\n'.join(self.buffer), self.filename)
2391 more = self.runsource('\n'.join(self.buffer), self.filename)
2393 if not more:
2392 if not more:
2394 self.resetbuffer()
2393 self.resetbuffer()
2395 return more
2394 return more
2396
2395
2397 def split_user_input(self, line):
2396 def split_user_input(self, line):
2398 # This is really a hold-over to support ipapi and some extensions
2397 # This is really a hold-over to support ipapi and some extensions
2399 return prefilter.splitUserInput(line)
2398 return prefilter.splitUserInput(line)
2400
2399
2401 def resetbuffer(self):
2400 def resetbuffer(self):
2402 """Reset the input buffer."""
2401 """Reset the input buffer."""
2403 self.buffer[:] = []
2402 self.buffer[:] = []
2404
2403
2405 def raw_input(self,prompt='',continue_prompt=False):
2404 def raw_input(self,prompt='',continue_prompt=False):
2406 """Write a prompt and read a line.
2405 """Write a prompt and read a line.
2407
2406
2408 The returned line does not include the trailing newline.
2407 The returned line does not include the trailing newline.
2409 When the user enters the EOF key sequence, EOFError is raised.
2408 When the user enters the EOF key sequence, EOFError is raised.
2410
2409
2411 Optional inputs:
2410 Optional inputs:
2412
2411
2413 - prompt(''): a string to be printed to prompt the user.
2412 - prompt(''): a string to be printed to prompt the user.
2414
2413
2415 - continue_prompt(False): whether this line is the first one or a
2414 - continue_prompt(False): whether this line is the first one or a
2416 continuation in a sequence of inputs.
2415 continuation in a sequence of inputs.
2417 """
2416 """
2418
2417
2419 # Code run by the user may have modified the readline completer state.
2418 # Code run by the user may have modified the readline completer state.
2420 # We must ensure that our completer is back in place.
2419 # We must ensure that our completer is back in place.
2421 if self.has_readline:
2420 if self.has_readline:
2422 self.set_completer()
2421 self.set_completer()
2423
2422
2424 try:
2423 try:
2425 line = raw_input_original(prompt).decode(self.stdin_encoding)
2424 line = raw_input_original(prompt).decode(self.stdin_encoding)
2426 except ValueError:
2425 except ValueError:
2427 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2426 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2428 " or sys.stdout.close()!\nExiting IPython!")
2427 " or sys.stdout.close()!\nExiting IPython!")
2429 self.ask_exit()
2428 self.ask_exit()
2430 return ""
2429 return ""
2431
2430
2432 # Try to be reasonably smart about not re-indenting pasted input more
2431 # Try to be reasonably smart about not re-indenting pasted input more
2433 # than necessary. We do this by trimming out the auto-indent initial
2432 # than necessary. We do this by trimming out the auto-indent initial
2434 # spaces, if the user's actual input started itself with whitespace.
2433 # spaces, if the user's actual input started itself with whitespace.
2435 #debugx('self.buffer[-1]')
2434 #debugx('self.buffer[-1]')
2436
2435
2437 if self.autoindent:
2436 if self.autoindent:
2438 if num_ini_spaces(line) > self.indent_current_nsp:
2437 if num_ini_spaces(line) > self.indent_current_nsp:
2439 line = line[self.indent_current_nsp:]
2438 line = line[self.indent_current_nsp:]
2440 self.indent_current_nsp = 0
2439 self.indent_current_nsp = 0
2441
2440
2442 # store the unfiltered input before the user has any chance to modify
2441 # store the unfiltered input before the user has any chance to modify
2443 # it.
2442 # it.
2444 if line.strip():
2443 if line.strip():
2445 if continue_prompt:
2444 if continue_prompt:
2446 self.input_hist_raw[-1] += '%s\n' % line
2445 self.input_hist_raw[-1] += '%s\n' % line
2447 if self.has_readline: # and some config option is set?
2446 if self.has_readline: # and some config option is set?
2448 try:
2447 try:
2449 histlen = self.readline.get_current_history_length()
2448 histlen = self.readline.get_current_history_length()
2450 if histlen > 1:
2449 if histlen > 1:
2451 newhist = self.input_hist_raw[-1].rstrip()
2450 newhist = self.input_hist_raw[-1].rstrip()
2452 self.readline.remove_history_item(histlen-1)
2451 self.readline.remove_history_item(histlen-1)
2453 self.readline.replace_history_item(histlen-2,
2452 self.readline.replace_history_item(histlen-2,
2454 newhist.encode(self.stdin_encoding))
2453 newhist.encode(self.stdin_encoding))
2455 except AttributeError:
2454 except AttributeError:
2456 pass # re{move,place}_history_item are new in 2.4.
2455 pass # re{move,place}_history_item are new in 2.4.
2457 else:
2456 else:
2458 self.input_hist_raw.append('%s\n' % line)
2457 self.input_hist_raw.append('%s\n' % line)
2459 # only entries starting at first column go to shadow history
2458 # only entries starting at first column go to shadow history
2460 if line.lstrip() == line:
2459 if line.lstrip() == line:
2461 self.shadowhist.add(line.strip())
2460 self.shadowhist.add(line.strip())
2462 elif not continue_prompt:
2461 elif not continue_prompt:
2463 self.input_hist_raw.append('\n')
2462 self.input_hist_raw.append('\n')
2464 try:
2463 try:
2465 lineout = self.prefilter(line,continue_prompt)
2464 lineout = self.prefilter(line,continue_prompt)
2466 except:
2465 except:
2467 # blanket except, in case a user-defined prefilter crashes, so it
2466 # blanket except, in case a user-defined prefilter crashes, so it
2468 # can't take all of ipython with it.
2467 # can't take all of ipython with it.
2469 self.showtraceback()
2468 self.showtraceback()
2470 return ''
2469 return ''
2471 else:
2470 else:
2472 return lineout
2471 return lineout
2473
2472
2474 def _prefilter(self, line, continue_prompt):
2473 def _prefilter(self, line, continue_prompt):
2475 """Calls different preprocessors, depending on the form of line."""
2474 """Calls different preprocessors, depending on the form of line."""
2476
2475
2477 # All handlers *must* return a value, even if it's blank ('').
2476 # All handlers *must* return a value, even if it's blank ('').
2478
2477
2479 # Lines are NOT logged here. Handlers should process the line as
2478 # Lines are NOT logged here. Handlers should process the line as
2480 # needed, update the cache AND log it (so that the input cache array
2479 # needed, update the cache AND log it (so that the input cache array
2481 # stays synced).
2480 # stays synced).
2482
2481
2483 #.....................................................................
2482 #.....................................................................
2484 # Code begins
2483 # Code begins
2485
2484
2486 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2485 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2487
2486
2488 # save the line away in case we crash, so the post-mortem handler can
2487 # save the line away in case we crash, so the post-mortem handler can
2489 # record it
2488 # record it
2490 self._last_input_line = line
2489 self._last_input_line = line
2491
2490
2492 #print '***line: <%s>' % line # dbg
2491 #print '***line: <%s>' % line # dbg
2493
2492
2494 if not line:
2493 if not line:
2495 # Return immediately on purely empty lines, so that if the user
2494 # Return immediately on purely empty lines, so that if the user
2496 # previously typed some whitespace that started a continuation
2495 # previously typed some whitespace that started a continuation
2497 # prompt, he can break out of that loop with just an empty line.
2496 # prompt, he can break out of that loop with just an empty line.
2498 # This is how the default python prompt works.
2497 # This is how the default python prompt works.
2499
2498
2500 # Only return if the accumulated input buffer was just whitespace!
2499 # Only return if the accumulated input buffer was just whitespace!
2501 if ''.join(self.buffer).isspace():
2500 if ''.join(self.buffer).isspace():
2502 self.buffer[:] = []
2501 self.buffer[:] = []
2503 return ''
2502 return ''
2504
2503
2505 line_info = prefilter.LineInfo(line, continue_prompt)
2504 line_info = prefilter.LineInfo(line, continue_prompt)
2506
2505
2507 # the input history needs to track even empty lines
2506 # the input history needs to track even empty lines
2508 stripped = line.strip()
2507 stripped = line.strip()
2509
2508
2510 if not stripped:
2509 if not stripped:
2511 if not continue_prompt:
2510 if not continue_prompt:
2512 self.outputcache.prompt_count -= 1
2511 self.outputcache.prompt_count -= 1
2513 return self.handle_normal(line_info)
2512 return self.handle_normal(line_info)
2514
2513
2515 # print '***cont',continue_prompt # dbg
2514 # print '***cont',continue_prompt # dbg
2516 # special handlers are only allowed for single line statements
2515 # special handlers are only allowed for single line statements
2517 if continue_prompt and not self.multi_line_specials:
2516 if continue_prompt and not self.multi_line_specials:
2518 return self.handle_normal(line_info)
2517 return self.handle_normal(line_info)
2519
2518
2520
2519
2521 # See whether any pre-existing handler can take care of it
2520 # See whether any pre-existing handler can take care of it
2522 rewritten = self.hooks.input_prefilter(stripped)
2521 rewritten = self.hooks.input_prefilter(stripped)
2523 if rewritten != stripped: # ok, some prefilter did something
2522 if rewritten != stripped: # ok, some prefilter did something
2524 rewritten = line_info.pre + rewritten # add indentation
2523 rewritten = line_info.pre + rewritten # add indentation
2525 return self.handle_normal(prefilter.LineInfo(rewritten,
2524 return self.handle_normal(prefilter.LineInfo(rewritten,
2526 continue_prompt))
2525 continue_prompt))
2527
2526
2528 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2527 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2529
2528
2530 return prefilter.prefilter(line_info, self)
2529 return prefilter.prefilter(line_info, self)
2531
2530
2532
2531
2533 def _prefilter_dumb(self, line, continue_prompt):
2532 def _prefilter_dumb(self, line, continue_prompt):
2534 """simple prefilter function, for debugging"""
2533 """simple prefilter function, for debugging"""
2535 return self.handle_normal(line,continue_prompt)
2534 return self.handle_normal(line,continue_prompt)
2536
2535
2537
2536
2538 def multiline_prefilter(self, line, continue_prompt):
2537 def multiline_prefilter(self, line, continue_prompt):
2539 """ Run _prefilter for each line of input
2538 """ Run _prefilter for each line of input
2540
2539
2541 Covers cases where there are multiple lines in the user entry,
2540 Covers cases where there are multiple lines in the user entry,
2542 which is the case when the user goes back to a multiline history
2541 which is the case when the user goes back to a multiline history
2543 entry and presses enter.
2542 entry and presses enter.
2544
2543
2545 """
2544 """
2546 out = []
2545 out = []
2547 for l in line.rstrip('\n').split('\n'):
2546 for l in line.rstrip('\n').split('\n'):
2548 out.append(self._prefilter(l, continue_prompt))
2547 out.append(self._prefilter(l, continue_prompt))
2549 return '\n'.join(out)
2548 return '\n'.join(out)
2550
2549
2551 # Set the default prefilter() function (this can be user-overridden)
2550 # Set the default prefilter() function (this can be user-overridden)
2552 prefilter = multiline_prefilter
2551 prefilter = multiline_prefilter
2553
2552
2554 def handle_normal(self,line_info):
2553 def handle_normal(self,line_info):
2555 """Handle normal input lines. Use as a template for handlers."""
2554 """Handle normal input lines. Use as a template for handlers."""
2556
2555
2557 # With autoindent on, we need some way to exit the input loop, and I
2556 # With autoindent on, we need some way to exit the input loop, and I
2558 # don't want to force the user to have to backspace all the way to
2557 # don't want to force the user to have to backspace all the way to
2559 # clear the line. The rule will be in this case, that either two
2558 # clear the line. The rule will be in this case, that either two
2560 # lines of pure whitespace in a row, or a line of pure whitespace but
2559 # lines of pure whitespace in a row, or a line of pure whitespace but
2561 # of a size different to the indent level, will exit the input loop.
2560 # of a size different to the indent level, will exit the input loop.
2562 line = line_info.line
2561 line = line_info.line
2563 continue_prompt = line_info.continue_prompt
2562 continue_prompt = line_info.continue_prompt
2564
2563
2565 if (continue_prompt and self.autoindent and line.isspace() and
2564 if (continue_prompt and self.autoindent and line.isspace() and
2566 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2565 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2567 (self.buffer[-1]).isspace() )):
2566 (self.buffer[-1]).isspace() )):
2568 line = ''
2567 line = ''
2569
2568
2570 self.log(line,line,continue_prompt)
2569 self.log(line,line,continue_prompt)
2571 return line
2570 return line
2572
2571
2573 def handle_alias(self,line_info):
2572 def handle_alias(self,line_info):
2574 """Handle alias input lines. """
2573 """Handle alias input lines. """
2575 tgt = self.alias_table[line_info.iFun]
2574 tgt = self.alias_table[line_info.iFun]
2576 # print "=>",tgt #dbg
2575 # print "=>",tgt #dbg
2577 if callable(tgt):
2576 if callable(tgt):
2578 if '$' in line_info.line:
2577 if '$' in line_info.line:
2579 call_meth = '(_ip, _ip.var_expand(%s))'
2578 call_meth = '(_ip, _ip.var_expand(%s))'
2580 else:
2579 else:
2581 call_meth = '(_ip,%s)'
2580 call_meth = '(_ip,%s)'
2582 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2581 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2583 line_info.iFun,
2582 line_info.iFun,
2584 make_quoted_expr(line_info.line))
2583 make_quoted_expr(line_info.line))
2585 else:
2584 else:
2586 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2585 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2587
2586
2588 # pre is needed, because it carries the leading whitespace. Otherwise
2587 # pre is needed, because it carries the leading whitespace. Otherwise
2589 # aliases won't work in indented sections.
2588 # aliases won't work in indented sections.
2590 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2589 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2591 make_quoted_expr( transformed ))
2590 make_quoted_expr( transformed ))
2592
2591
2593 self.log(line_info.line,line_out,line_info.continue_prompt)
2592 self.log(line_info.line,line_out,line_info.continue_prompt)
2594 #print 'line out:',line_out # dbg
2593 #print 'line out:',line_out # dbg
2595 return line_out
2594 return line_out
2596
2595
2597 def handle_shell_escape(self, line_info):
2596 def handle_shell_escape(self, line_info):
2598 """Execute the line in a shell, empty return value"""
2597 """Execute the line in a shell, empty return value"""
2599 #print 'line in :', `line` # dbg
2598 #print 'line in :', `line` # dbg
2600 line = line_info.line
2599 line = line_info.line
2601 if line.lstrip().startswith('!!'):
2600 if line.lstrip().startswith('!!'):
2602 # rewrite LineInfo's line, iFun and theRest to properly hold the
2601 # rewrite LineInfo's line, iFun and theRest to properly hold the
2603 # call to %sx and the actual command to be executed, so
2602 # call to %sx and the actual command to be executed, so
2604 # handle_magic can work correctly. Note that this works even if
2603 # handle_magic can work correctly. Note that this works even if
2605 # the line is indented, so it handles multi_line_specials
2604 # the line is indented, so it handles multi_line_specials
2606 # properly.
2605 # properly.
2607 new_rest = line.lstrip()[2:]
2606 new_rest = line.lstrip()[2:]
2608 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2607 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2609 line_info.iFun = 'sx'
2608 line_info.iFun = 'sx'
2610 line_info.theRest = new_rest
2609 line_info.theRest = new_rest
2611 return self.handle_magic(line_info)
2610 return self.handle_magic(line_info)
2612 else:
2611 else:
2613 cmd = line.lstrip().lstrip('!')
2612 cmd = line.lstrip().lstrip('!')
2614 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2613 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2615 make_quoted_expr(cmd))
2614 make_quoted_expr(cmd))
2616 # update cache/log and return
2615 # update cache/log and return
2617 self.log(line,line_out,line_info.continue_prompt)
2616 self.log(line,line_out,line_info.continue_prompt)
2618 return line_out
2617 return line_out
2619
2618
2620 def handle_magic(self, line_info):
2619 def handle_magic(self, line_info):
2621 """Execute magic functions."""
2620 """Execute magic functions."""
2622 iFun = line_info.iFun
2621 iFun = line_info.iFun
2623 theRest = line_info.theRest
2622 theRest = line_info.theRest
2624 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2623 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2625 make_quoted_expr(iFun + " " + theRest))
2624 make_quoted_expr(iFun + " " + theRest))
2626 self.log(line_info.line,cmd,line_info.continue_prompt)
2625 self.log(line_info.line,cmd,line_info.continue_prompt)
2627 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2626 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2628 return cmd
2627 return cmd
2629
2628
2630 def handle_auto(self, line_info):
2629 def handle_auto(self, line_info):
2631 """Hande lines which can be auto-executed, quoting if requested."""
2630 """Hande lines which can be auto-executed, quoting if requested."""
2632
2631
2633 line = line_info.line
2632 line = line_info.line
2634 iFun = line_info.iFun
2633 iFun = line_info.iFun
2635 theRest = line_info.theRest
2634 theRest = line_info.theRest
2636 pre = line_info.pre
2635 pre = line_info.pre
2637 continue_prompt = line_info.continue_prompt
2636 continue_prompt = line_info.continue_prompt
2638 obj = line_info.ofind(self)['obj']
2637 obj = line_info.ofind(self)['obj']
2639
2638
2640 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2639 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2641
2640
2642 # This should only be active for single-line input!
2641 # This should only be active for single-line input!
2643 if continue_prompt:
2642 if continue_prompt:
2644 self.log(line,line,continue_prompt)
2643 self.log(line,line,continue_prompt)
2645 return line
2644 return line
2646
2645
2647 force_auto = isinstance(obj, IPyAutocall)
2646 force_auto = isinstance(obj, IPyAutocall)
2648 auto_rewrite = True
2647 auto_rewrite = True
2649
2648
2650 if pre == self.ESC_QUOTE:
2649 if pre == self.ESC_QUOTE:
2651 # Auto-quote splitting on whitespace
2650 # Auto-quote splitting on whitespace
2652 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2651 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2653 elif pre == self.ESC_QUOTE2:
2652 elif pre == self.ESC_QUOTE2:
2654 # Auto-quote whole string
2653 # Auto-quote whole string
2655 newcmd = '%s("%s")' % (iFun,theRest)
2654 newcmd = '%s("%s")' % (iFun,theRest)
2656 elif pre == self.ESC_PAREN:
2655 elif pre == self.ESC_PAREN:
2657 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2656 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2658 else:
2657 else:
2659 # Auto-paren.
2658 # Auto-paren.
2660 # We only apply it to argument-less calls if the autocall
2659 # We only apply it to argument-less calls if the autocall
2661 # parameter is set to 2. We only need to check that autocall is <
2660 # parameter is set to 2. We only need to check that autocall is <
2662 # 2, since this function isn't called unless it's at least 1.
2661 # 2, since this function isn't called unless it's at least 1.
2663 if not theRest and (self.autocall < 2) and not force_auto:
2662 if not theRest and (self.autocall < 2) and not force_auto:
2664 newcmd = '%s %s' % (iFun,theRest)
2663 newcmd = '%s %s' % (iFun,theRest)
2665 auto_rewrite = False
2664 auto_rewrite = False
2666 else:
2665 else:
2667 if not force_auto and theRest.startswith('['):
2666 if not force_auto and theRest.startswith('['):
2668 if hasattr(obj,'__getitem__'):
2667 if hasattr(obj,'__getitem__'):
2669 # Don't autocall in this case: item access for an object
2668 # Don't autocall in this case: item access for an object
2670 # which is BOTH callable and implements __getitem__.
2669 # which is BOTH callable and implements __getitem__.
2671 newcmd = '%s %s' % (iFun,theRest)
2670 newcmd = '%s %s' % (iFun,theRest)
2672 auto_rewrite = False
2671 auto_rewrite = False
2673 else:
2672 else:
2674 # if the object doesn't support [] access, go ahead and
2673 # if the object doesn't support [] access, go ahead and
2675 # autocall
2674 # autocall
2676 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2675 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2677 elif theRest.endswith(';'):
2676 elif theRest.endswith(';'):
2678 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2677 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2679 else:
2678 else:
2680 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2679 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2681
2680
2682 if auto_rewrite:
2681 if auto_rewrite:
2683 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2682 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2684
2683
2685 try:
2684 try:
2686 # plain ascii works better w/ pyreadline, on some machines, so
2685 # plain ascii works better w/ pyreadline, on some machines, so
2687 # we use it and only print uncolored rewrite if we have unicode
2686 # we use it and only print uncolored rewrite if we have unicode
2688 rw = str(rw)
2687 rw = str(rw)
2689 print >>Term.cout, rw
2688 print >>Term.cout, rw
2690 except UnicodeEncodeError:
2689 except UnicodeEncodeError:
2691 print "-------------->" + newcmd
2690 print "-------------->" + newcmd
2692
2691
2693 # log what is now valid Python, not the actual user input (without the
2692 # log what is now valid Python, not the actual user input (without the
2694 # final newline)
2693 # final newline)
2695 self.log(line,newcmd,continue_prompt)
2694 self.log(line,newcmd,continue_prompt)
2696 return newcmd
2695 return newcmd
2697
2696
2698 def handle_help(self, line_info):
2697 def handle_help(self, line_info):
2699 """Try to get some help for the object.
2698 """Try to get some help for the object.
2700
2699
2701 obj? or ?obj -> basic information.
2700 obj? or ?obj -> basic information.
2702 obj?? or ??obj -> more details.
2701 obj?? or ??obj -> more details.
2703 """
2702 """
2704
2703
2705 line = line_info.line
2704 line = line_info.line
2706 # We need to make sure that we don't process lines which would be
2705 # We need to make sure that we don't process lines which would be
2707 # otherwise valid python, such as "x=1 # what?"
2706 # otherwise valid python, such as "x=1 # what?"
2708 try:
2707 try:
2709 codeop.compile_command(line)
2708 codeop.compile_command(line)
2710 except SyntaxError:
2709 except SyntaxError:
2711 # We should only handle as help stuff which is NOT valid syntax
2710 # We should only handle as help stuff which is NOT valid syntax
2712 if line[0]==self.ESC_HELP:
2711 if line[0]==self.ESC_HELP:
2713 line = line[1:]
2712 line = line[1:]
2714 elif line[-1]==self.ESC_HELP:
2713 elif line[-1]==self.ESC_HELP:
2715 line = line[:-1]
2714 line = line[:-1]
2716 self.log(line,'#?'+line,line_info.continue_prompt)
2715 self.log(line,'#?'+line,line_info.continue_prompt)
2717 if line:
2716 if line:
2718 #print 'line:<%r>' % line # dbg
2717 #print 'line:<%r>' % line # dbg
2719 self.magic_pinfo(line)
2718 self.magic_pinfo(line)
2720 else:
2719 else:
2721 page(self.usage,screen_lines=self.usable_screen_length)
2720 page(self.usage,screen_lines=self.usable_screen_length)
2722 return '' # Empty string is needed here!
2721 return '' # Empty string is needed here!
2723 except:
2722 except:
2724 # Pass any other exceptions through to the normal handler
2723 # Pass any other exceptions through to the normal handler
2725 return self.handle_normal(line_info)
2724 return self.handle_normal(line_info)
2726 else:
2725 else:
2727 # If the code compiles ok, we should handle it normally
2726 # If the code compiles ok, we should handle it normally
2728 return self.handle_normal(line_info)
2727 return self.handle_normal(line_info)
2729
2728
2730 def handle_emacs(self, line_info):
2729 def handle_emacs(self, line_info):
2731 """Handle input lines marked by python-mode."""
2730 """Handle input lines marked by python-mode."""
2732
2731
2733 # Currently, nothing is done. Later more functionality can be added
2732 # Currently, nothing is done. Later more functionality can be added
2734 # here if needed.
2733 # here if needed.
2735
2734
2736 # The input cache shouldn't be updated
2735 # The input cache shouldn't be updated
2737 return line_info.line
2736 return line_info.line
2738
2737
2739 def var_expand(self,cmd,depth=0):
2738 def var_expand(self,cmd,depth=0):
2740 """Expand python variables in a string.
2739 """Expand python variables in a string.
2741
2740
2742 The depth argument indicates how many frames above the caller should
2741 The depth argument indicates how many frames above the caller should
2743 be walked to look for the local namespace where to expand variables.
2742 be walked to look for the local namespace where to expand variables.
2744
2743
2745 The global namespace for expansion is always the user's interactive
2744 The global namespace for expansion is always the user's interactive
2746 namespace.
2745 namespace.
2747 """
2746 """
2748
2747
2749 return str(ItplNS(cmd,
2748 return str(ItplNS(cmd,
2750 self.user_ns, # globals
2749 self.user_ns, # globals
2751 # Skip our own frame in searching for locals:
2750 # Skip our own frame in searching for locals:
2752 sys._getframe(depth+1).f_locals # locals
2751 sys._getframe(depth+1).f_locals # locals
2753 ))
2752 ))
2754
2753
2755 def mktempfile(self,data=None):
2754 def mktempfile(self,data=None):
2756 """Make a new tempfile and return its filename.
2755 """Make a new tempfile and return its filename.
2757
2756
2758 This makes a call to tempfile.mktemp, but it registers the created
2757 This makes a call to tempfile.mktemp, but it registers the created
2759 filename internally so ipython cleans it up at exit time.
2758 filename internally so ipython cleans it up at exit time.
2760
2759
2761 Optional inputs:
2760 Optional inputs:
2762
2761
2763 - data(None): if data is given, it gets written out to the temp file
2762 - data(None): if data is given, it gets written out to the temp file
2764 immediately, and the file is closed again."""
2763 immediately, and the file is closed again."""
2765
2764
2766 filename = tempfile.mktemp('.py','ipython_edit_')
2765 filename = tempfile.mktemp('.py','ipython_edit_')
2767 self.tempfiles.append(filename)
2766 self.tempfiles.append(filename)
2768
2767
2769 if data:
2768 if data:
2770 tmp_file = open(filename,'w')
2769 tmp_file = open(filename,'w')
2771 tmp_file.write(data)
2770 tmp_file.write(data)
2772 tmp_file.close()
2771 tmp_file.close()
2773 return filename
2772 return filename
2774
2773
2775 def write(self,data):
2774 def write(self,data):
2776 """Write a string to the default output"""
2775 """Write a string to the default output"""
2777 Term.cout.write(data)
2776 Term.cout.write(data)
2778
2777
2779 def write_err(self,data):
2778 def write_err(self,data):
2780 """Write a string to the default error output"""
2779 """Write a string to the default error output"""
2781 Term.cerr.write(data)
2780 Term.cerr.write(data)
2782
2781
2783 def ask_exit(self):
2782 def ask_exit(self):
2784 """ Call for exiting. Can be overiden and used as a callback. """
2783 """ Call for exiting. Can be overiden and used as a callback. """
2785 self.exit_now = True
2784 self.exit_now = True
2786
2785
2787 def exit(self):
2786 def exit(self):
2788 """Handle interactive exit.
2787 """Handle interactive exit.
2789
2788
2790 This method calls the ask_exit callback."""
2789 This method calls the ask_exit callback."""
2791 if self.confirm_exit:
2790 if self.confirm_exit:
2792 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2791 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2793 self.ask_exit()
2792 self.ask_exit()
2794 else:
2793 else:
2795 self.ask_exit()
2794 self.ask_exit()
2796
2795
2797 def safe_execfile(self,fname,*where,**kw):
2796 def safe_execfile(self,fname,*where,**kw):
2798 """A safe version of the builtin execfile().
2797 """A safe version of the builtin execfile().
2799
2798
2800 This version will never throw an exception, and knows how to handle
2799 This version will never throw an exception, and knows how to handle
2801 ipython logs as well.
2800 ipython logs as well.
2802
2801
2803 :Parameters:
2802 :Parameters:
2804 fname : string
2803 fname : string
2805 Name of the file to be executed.
2804 Name of the file to be executed.
2806
2805
2807 where : tuple
2806 where : tuple
2808 One or two namespaces, passed to execfile() as (globals,locals).
2807 One or two namespaces, passed to execfile() as (globals,locals).
2809 If only one is given, it is passed as both.
2808 If only one is given, it is passed as both.
2810
2809
2811 :Keywords:
2810 :Keywords:
2812 islog : boolean (False)
2811 islog : boolean (False)
2813
2812
2814 quiet : boolean (True)
2813 quiet : boolean (True)
2815
2814
2816 exit_ignore : boolean (False)
2815 exit_ignore : boolean (False)
2817 """
2816 """
2818
2817
2819 def syspath_cleanup():
2818 def syspath_cleanup():
2820 """Internal cleanup routine for sys.path."""
2819 """Internal cleanup routine for sys.path."""
2821 if add_dname:
2820 if add_dname:
2822 try:
2821 try:
2823 sys.path.remove(dname)
2822 sys.path.remove(dname)
2824 except ValueError:
2823 except ValueError:
2825 # For some reason the user has already removed it, ignore.
2824 # For some reason the user has already removed it, ignore.
2826 pass
2825 pass
2827
2826
2828 fname = os.path.expanduser(fname)
2827 fname = os.path.expanduser(fname)
2829
2828
2830 # Find things also in current directory. This is needed to mimic the
2829 # Find things also in current directory. This is needed to mimic the
2831 # behavior of running a script from the system command line, where
2830 # behavior of running a script from the system command line, where
2832 # Python inserts the script's directory into sys.path
2831 # Python inserts the script's directory into sys.path
2833 dname = os.path.dirname(os.path.abspath(fname))
2832 dname = os.path.dirname(os.path.abspath(fname))
2834 add_dname = False
2833 add_dname = False
2835 if dname not in sys.path:
2834 if dname not in sys.path:
2836 sys.path.insert(0,dname)
2835 sys.path.insert(0,dname)
2837 add_dname = True
2836 add_dname = True
2838
2837
2839 try:
2838 try:
2840 xfile = open(fname)
2839 xfile = open(fname)
2841 except:
2840 except:
2842 print >> Term.cerr, \
2841 print >> Term.cerr, \
2843 'Could not open file <%s> for safe execution.' % fname
2842 'Could not open file <%s> for safe execution.' % fname
2844 syspath_cleanup()
2843 syspath_cleanup()
2845 return None
2844 return None
2846
2845
2847 kw.setdefault('islog',0)
2846 kw.setdefault('islog',0)
2848 kw.setdefault('quiet',1)
2847 kw.setdefault('quiet',1)
2849 kw.setdefault('exit_ignore',0)
2848 kw.setdefault('exit_ignore',0)
2850
2849
2851 first = xfile.readline()
2850 first = xfile.readline()
2852 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2851 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2853 xfile.close()
2852 xfile.close()
2854 # line by line execution
2853 # line by line execution
2855 if first.startswith(loghead) or kw['islog']:
2854 if first.startswith(loghead) or kw['islog']:
2856 print 'Loading log file <%s> one line at a time...' % fname
2855 print 'Loading log file <%s> one line at a time...' % fname
2857 if kw['quiet']:
2856 if kw['quiet']:
2858 stdout_save = sys.stdout
2857 stdout_save = sys.stdout
2859 sys.stdout = StringIO.StringIO()
2858 sys.stdout = StringIO.StringIO()
2860 try:
2859 try:
2861 globs,locs = where[0:2]
2860 globs,locs = where[0:2]
2862 except:
2861 except:
2863 try:
2862 try:
2864 globs = locs = where[0]
2863 globs = locs = where[0]
2865 except:
2864 except:
2866 globs = locs = globals()
2865 globs = locs = globals()
2867 badblocks = []
2866 badblocks = []
2868
2867
2869 # we also need to identify indented blocks of code when replaying
2868 # we also need to identify indented blocks of code when replaying
2870 # logs and put them together before passing them to an exec
2869 # logs and put them together before passing them to an exec
2871 # statement. This takes a bit of regexp and look-ahead work in the
2870 # statement. This takes a bit of regexp and look-ahead work in the
2872 # file. It's easiest if we swallow the whole thing in memory
2871 # file. It's easiest if we swallow the whole thing in memory
2873 # first, and manually walk through the lines list moving the
2872 # first, and manually walk through the lines list moving the
2874 # counter ourselves.
2873 # counter ourselves.
2875 indent_re = re.compile('\s+\S')
2874 indent_re = re.compile('\s+\S')
2876 xfile = open(fname)
2875 xfile = open(fname)
2877 filelines = xfile.readlines()
2876 filelines = xfile.readlines()
2878 xfile.close()
2877 xfile.close()
2879 nlines = len(filelines)
2878 nlines = len(filelines)
2880 lnum = 0
2879 lnum = 0
2881 while lnum < nlines:
2880 while lnum < nlines:
2882 line = filelines[lnum]
2881 line = filelines[lnum]
2883 lnum += 1
2882 lnum += 1
2884 # don't re-insert logger status info into cache
2883 # don't re-insert logger status info into cache
2885 if line.startswith('#log#'):
2884 if line.startswith('#log#'):
2886 continue
2885 continue
2887 else:
2886 else:
2888 # build a block of code (maybe a single line) for execution
2887 # build a block of code (maybe a single line) for execution
2889 block = line
2888 block = line
2890 try:
2889 try:
2891 next = filelines[lnum] # lnum has already incremented
2890 next = filelines[lnum] # lnum has already incremented
2892 except:
2891 except:
2893 next = None
2892 next = None
2894 while next and indent_re.match(next):
2893 while next and indent_re.match(next):
2895 block += next
2894 block += next
2896 lnum += 1
2895 lnum += 1
2897 try:
2896 try:
2898 next = filelines[lnum]
2897 next = filelines[lnum]
2899 except:
2898 except:
2900 next = None
2899 next = None
2901 # now execute the block of one or more lines
2900 # now execute the block of one or more lines
2902 try:
2901 try:
2903 exec block in globs,locs
2902 exec block in globs,locs
2904 except SystemExit:
2903 except SystemExit:
2905 pass
2904 pass
2906 except:
2905 except:
2907 badblocks.append(block.rstrip())
2906 badblocks.append(block.rstrip())
2908 if kw['quiet']: # restore stdout
2907 if kw['quiet']: # restore stdout
2909 sys.stdout.close()
2908 sys.stdout.close()
2910 sys.stdout = stdout_save
2909 sys.stdout = stdout_save
2911 print 'Finished replaying log file <%s>' % fname
2910 print 'Finished replaying log file <%s>' % fname
2912 if badblocks:
2911 if badblocks:
2913 print >> sys.stderr, ('\nThe following lines/blocks in file '
2912 print >> sys.stderr, ('\nThe following lines/blocks in file '
2914 '<%s> reported errors:' % fname)
2913 '<%s> reported errors:' % fname)
2915
2914
2916 for badline in badblocks:
2915 for badline in badblocks:
2917 print >> sys.stderr, badline
2916 print >> sys.stderr, badline
2918 else: # regular file execution
2917 else: # regular file execution
2919 try:
2918 try:
2920 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2919 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2921 # Work around a bug in Python for Windows. The bug was
2920 # Work around a bug in Python for Windows. The bug was
2922 # fixed in in Python 2.5 r54159 and 54158, but that's still
2921 # fixed in in Python 2.5 r54159 and 54158, but that's still
2923 # SVN Python as of March/07. For details, see:
2922 # SVN Python as of March/07. For details, see:
2924 # http://projects.scipy.org/ipython/ipython/ticket/123
2923 # http://projects.scipy.org/ipython/ipython/ticket/123
2925 try:
2924 try:
2926 globs,locs = where[0:2]
2925 globs,locs = where[0:2]
2927 except:
2926 except:
2928 try:
2927 try:
2929 globs = locs = where[0]
2928 globs = locs = where[0]
2930 except:
2929 except:
2931 globs = locs = globals()
2930 globs = locs = globals()
2932 exec file(fname) in globs,locs
2931 exec file(fname) in globs,locs
2933 else:
2932 else:
2934 execfile(fname,*where)
2933 execfile(fname,*where)
2935 except SyntaxError:
2934 except SyntaxError:
2936 self.showsyntaxerror()
2935 self.showsyntaxerror()
2937 warn('Failure executing file: <%s>' % fname)
2936 warn('Failure executing file: <%s>' % fname)
2938 except SystemExit,status:
2937 except SystemExit,status:
2939 # Code that correctly sets the exit status flag to success (0)
2938 # Code that correctly sets the exit status flag to success (0)
2940 # shouldn't be bothered with a traceback. Note that a plain
2939 # shouldn't be bothered with a traceback. Note that a plain
2941 # sys.exit() does NOT set the message to 0 (it's empty) so that
2940 # sys.exit() does NOT set the message to 0 (it's empty) so that
2942 # will still get a traceback. Note that the structure of the
2941 # will still get a traceback. Note that the structure of the
2943 # SystemExit exception changed between Python 2.4 and 2.5, so
2942 # SystemExit exception changed between Python 2.4 and 2.5, so
2944 # the checks must be done in a version-dependent way.
2943 # the checks must be done in a version-dependent way.
2945 show = False
2944 show = False
2946
2945
2947 if sys.version_info[:2] > (2,5):
2946 if sys.version_info[:2] > (2,5):
2948 if status.message!=0 and not kw['exit_ignore']:
2947 if status.message!=0 and not kw['exit_ignore']:
2949 show = True
2948 show = True
2950 else:
2949 else:
2951 if status.code and not kw['exit_ignore']:
2950 if status.code and not kw['exit_ignore']:
2952 show = True
2951 show = True
2953 if show:
2952 if show:
2954 self.showtraceback()
2953 self.showtraceback()
2955 warn('Failure executing file: <%s>' % fname)
2954 warn('Failure executing file: <%s>' % fname)
2956 except:
2955 except:
2957 self.showtraceback()
2956 self.showtraceback()
2958 warn('Failure executing file: <%s>' % fname)
2957 warn('Failure executing file: <%s>' % fname)
2959
2958
2960 syspath_cleanup()
2959 syspath_cleanup()
2961
2960
2962 #************************* end of file <iplib.py> *****************************
2961 #************************* end of file <iplib.py> *****************************
@@ -1,150 +1,150 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
2
3 """A class for handling client connections to the controller."""
3 """A class for handling client connections to the controller."""
4
4
5 __docformat__ = "restructuredtext en"
5 __docformat__ = "restructuredtext en"
6
6
7 #-------------------------------------------------------------------------------
7 #-------------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
8 # Copyright (C) 2008 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-------------------------------------------------------------------------------
12 #-------------------------------------------------------------------------------
13
13
14 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-------------------------------------------------------------------------------
16 #-------------------------------------------------------------------------------
17
17
18 from twisted.internet import defer
18 from twisted.internet import defer
19
19
20 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
20 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
21
21
22 from IPython.kernel.config import config_manager as kernel_config_manager
22 from IPython.kernel.config import config_manager as kernel_config_manager
23 from IPython.config.cutils import import_item
23 from IPython.utils.importstring import import_item
24 from IPython.kernel.fcutil import find_furl
24 from IPython.kernel.fcutil import find_furl
25
25
26 co = kernel_config_manager.get_config_obj()
26 co = kernel_config_manager.get_config_obj()
27 client_co = co['client']
27 client_co = co['client']
28
28
29 #-------------------------------------------------------------------------------
29 #-------------------------------------------------------------------------------
30 # The ClientConnector class
30 # The ClientConnector class
31 #-------------------------------------------------------------------------------
31 #-------------------------------------------------------------------------------
32
32
33 class ClientConnector(object):
33 class ClientConnector(object):
34 """
34 """
35 This class gets remote references from furls and returns the wrapped clients.
35 This class gets remote references from furls and returns the wrapped clients.
36
36
37 This class is also used in `client.py` and `asyncclient.py` to create
37 This class is also used in `client.py` and `asyncclient.py` to create
38 a single per client-process Tub.
38 a single per client-process Tub.
39 """
39 """
40
40
41 def __init__(self):
41 def __init__(self):
42 self._remote_refs = {}
42 self._remote_refs = {}
43 self.tub = Tub()
43 self.tub = Tub()
44 self.tub.startService()
44 self.tub.startService()
45
45
46 def get_reference(self, furl_or_file):
46 def get_reference(self, furl_or_file):
47 """
47 """
48 Get a remote reference using a furl or a file containing a furl.
48 Get a remote reference using a furl or a file containing a furl.
49
49
50 Remote references are cached locally so once a remote reference
50 Remote references are cached locally so once a remote reference
51 has been retrieved for a given furl, the cached version is
51 has been retrieved for a given furl, the cached version is
52 returned.
52 returned.
53
53
54 :Parameters:
54 :Parameters:
55 furl_or_file : str
55 furl_or_file : str
56 A furl or a filename containing a furl
56 A furl or a filename containing a furl
57
57
58 :Returns:
58 :Returns:
59 A deferred to a remote reference
59 A deferred to a remote reference
60 """
60 """
61 furl = find_furl(furl_or_file)
61 furl = find_furl(furl_or_file)
62 if furl in self._remote_refs:
62 if furl in self._remote_refs:
63 d = defer.succeed(self._remote_refs[furl])
63 d = defer.succeed(self._remote_refs[furl])
64 else:
64 else:
65 d = self.tub.getReference(furl)
65 d = self.tub.getReference(furl)
66 d.addCallback(self.save_ref, furl)
66 d.addCallback(self.save_ref, furl)
67 return d
67 return d
68
68
69 def save_ref(self, ref, furl):
69 def save_ref(self, ref, furl):
70 """
70 """
71 Cache a remote reference by its furl.
71 Cache a remote reference by its furl.
72 """
72 """
73 self._remote_refs[furl] = ref
73 self._remote_refs[furl] = ref
74 return ref
74 return ref
75
75
76 def get_task_client(self, furl_or_file=''):
76 def get_task_client(self, furl_or_file=''):
77 """
77 """
78 Get the task controller client.
78 Get the task controller client.
79
79
80 This method is a simple wrapper around `get_client` that allow
80 This method is a simple wrapper around `get_client` that allow
81 `furl_or_file` to be empty, in which case, the furls is taken
81 `furl_or_file` to be empty, in which case, the furls is taken
82 from the default furl file given in the configuration.
82 from the default furl file given in the configuration.
83
83
84 :Parameters:
84 :Parameters:
85 furl_or_file : str
85 furl_or_file : str
86 A furl or a filename containing a furl. If empty, the
86 A furl or a filename containing a furl. If empty, the
87 default furl_file will be used
87 default furl_file will be used
88
88
89 :Returns:
89 :Returns:
90 A deferred to the actual client class
90 A deferred to the actual client class
91 """
91 """
92 task_co = client_co['client_interfaces']['task']
92 task_co = client_co['client_interfaces']['task']
93 if furl_or_file:
93 if furl_or_file:
94 ff = furl_or_file
94 ff = furl_or_file
95 else:
95 else:
96 ff = task_co['furl_file']
96 ff = task_co['furl_file']
97 return self.get_client(ff)
97 return self.get_client(ff)
98
98
99 def get_multiengine_client(self, furl_or_file=''):
99 def get_multiengine_client(self, furl_or_file=''):
100 """
100 """
101 Get the multiengine controller client.
101 Get the multiengine controller client.
102
102
103 This method is a simple wrapper around `get_client` that allow
103 This method is a simple wrapper around `get_client` that allow
104 `furl_or_file` to be empty, in which case, the furls is taken
104 `furl_or_file` to be empty, in which case, the furls is taken
105 from the default furl file given in the configuration.
105 from the default furl file given in the configuration.
106
106
107 :Parameters:
107 :Parameters:
108 furl_or_file : str
108 furl_or_file : str
109 A furl or a filename containing a furl. If empty, the
109 A furl or a filename containing a furl. If empty, the
110 default furl_file will be used
110 default furl_file will be used
111
111
112 :Returns:
112 :Returns:
113 A deferred to the actual client class
113 A deferred to the actual client class
114 """
114 """
115 task_co = client_co['client_interfaces']['multiengine']
115 task_co = client_co['client_interfaces']['multiengine']
116 if furl_or_file:
116 if furl_or_file:
117 ff = furl_or_file
117 ff = furl_or_file
118 else:
118 else:
119 ff = task_co['furl_file']
119 ff = task_co['furl_file']
120 return self.get_client(ff)
120 return self.get_client(ff)
121
121
122 def get_client(self, furl_or_file):
122 def get_client(self, furl_or_file):
123 """
123 """
124 Get a remote reference and wrap it in a client by furl.
124 Get a remote reference and wrap it in a client by furl.
125
125
126 This method first gets a remote reference and then calls its
126 This method first gets a remote reference and then calls its
127 `get_client_name` method to find the apprpriate client class
127 `get_client_name` method to find the apprpriate client class
128 that should be used to wrap the remote reference.
128 that should be used to wrap the remote reference.
129
129
130 :Parameters:
130 :Parameters:
131 furl_or_file : str
131 furl_or_file : str
132 A furl or a filename containing a furl
132 A furl or a filename containing a furl
133
133
134 :Returns:
134 :Returns:
135 A deferred to the actual client class
135 A deferred to the actual client class
136 """
136 """
137 furl = find_furl(furl_or_file)
137 furl = find_furl(furl_or_file)
138 d = self.get_reference(furl)
138 d = self.get_reference(furl)
139 def wrap_remote_reference(rr):
139 def wrap_remote_reference(rr):
140 d = rr.callRemote('get_client_name')
140 d = rr.callRemote('get_client_name')
141 d.addCallback(lambda name: import_item(name))
141 d.addCallback(lambda name: import_item(name))
142 def adapt(client_interface):
142 def adapt(client_interface):
143 client = client_interface(rr)
143 client = client_interface(rr)
144 client.tub = self.tub
144 client.tub = self.tub
145 return client
145 return client
146 d.addCallback(adapt)
146 d.addCallback(adapt)
147
147
148 return d
148 return d
149 d.addCallback(wrap_remote_reference)
149 d.addCallback(wrap_remote_reference)
150 return d
150 return d
@@ -1,416 +1,416 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 """The IPython controller."""
4 """The IPython controller."""
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 # Python looks for an empty string at the beginning of sys.path to enable
19 # Python looks for an empty string at the beginning of sys.path to enable
20 # importing from the cwd.
20 # importing from the cwd.
21 import sys
21 import sys
22 sys.path.insert(0, '')
22 sys.path.insert(0, '')
23
23
24 from optparse import OptionParser
24 from optparse import OptionParser
25 import os
25 import os
26 import time
26 import time
27 import tempfile
27 import tempfile
28
28
29 from twisted.application import internet, service
29 from twisted.application import internet, service
30 from twisted.internet import reactor, error, defer
30 from twisted.internet import reactor, error, defer
31 from twisted.python import log
31 from twisted.python import log
32
32
33 from IPython.kernel.fcutil import Tub, UnauthenticatedTub, have_crypto
33 from IPython.kernel.fcutil import Tub, UnauthenticatedTub, have_crypto
34
34
35 # from IPython.utils import growl
35 # from IPython.utils import growl
36 # growl.start("IPython1 Controller")
36 # growl.start("IPython1 Controller")
37
37
38 from IPython.kernel.error import SecurityError
38 from IPython.kernel.error import SecurityError
39 from IPython.kernel import controllerservice
39 from IPython.kernel import controllerservice
40 from IPython.kernel.fcutil import check_furl_file_security
40 from IPython.kernel.fcutil import check_furl_file_security
41
41
42 # Create various ipython directories if they don't exist.
42 # Create various ipython directories if they don't exist.
43 # This must be done before IPython.kernel.config is imported.
43 # This must be done before IPython.kernel.config is imported.
44 from IPython.core.oldusersetup import user_setup
44 from IPython.core.oldusersetup import user_setup
45 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
45 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
46 if os.name == 'posix':
46 if os.name == 'posix':
47 rc_suffix = ''
47 rc_suffix = ''
48 else:
48 else:
49 rc_suffix = '.ini'
49 rc_suffix = '.ini'
50 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
50 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
51 get_log_dir()
51 get_log_dir()
52 get_security_dir()
52 get_security_dir()
53
53
54 from IPython.kernel.config import config_manager as kernel_config_manager
54 from IPython.kernel.config import config_manager as kernel_config_manager
55 from IPython.config.cutils import import_item
55 from IPython.utils.importstring import import_item
56
56
57
57
58 #-------------------------------------------------------------------------------
58 #-------------------------------------------------------------------------------
59 # Code
59 # Code
60 #-------------------------------------------------------------------------------
60 #-------------------------------------------------------------------------------
61
61
62 def get_temp_furlfile(filename):
62 def get_temp_furlfile(filename):
63 return tempfile.mktemp(dir=os.path.dirname(filename),
63 return tempfile.mktemp(dir=os.path.dirname(filename),
64 prefix=os.path.basename(filename))
64 prefix=os.path.basename(filename))
65
65
66 def make_tub(ip, port, secure, cert_file):
66 def make_tub(ip, port, secure, cert_file):
67 """
67 """
68 Create a listening tub given an ip, port, and cert_file location.
68 Create a listening tub given an ip, port, and cert_file location.
69
69
70 :Parameters:
70 :Parameters:
71 ip : str
71 ip : str
72 The ip address that the tub should listen on. Empty means all
72 The ip address that the tub should listen on. Empty means all
73 port : int
73 port : int
74 The port that the tub should listen on. A value of 0 means
74 The port that the tub should listen on. A value of 0 means
75 pick a random port
75 pick a random port
76 secure: boolean
76 secure: boolean
77 Will the connection be secure (in the foolscap sense)
77 Will the connection be secure (in the foolscap sense)
78 cert_file:
78 cert_file:
79 A filename of a file to be used for theSSL certificate
79 A filename of a file to be used for theSSL certificate
80 """
80 """
81 if secure:
81 if secure:
82 if have_crypto:
82 if have_crypto:
83 tub = Tub(certFile=cert_file)
83 tub = Tub(certFile=cert_file)
84 else:
84 else:
85 raise SecurityError("""
85 raise SecurityError("""
86 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
86 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
87 Try running without security using 'ipcontroller -xy'.
87 Try running without security using 'ipcontroller -xy'.
88 """)
88 """)
89 else:
89 else:
90 tub = UnauthenticatedTub()
90 tub = UnauthenticatedTub()
91
91
92 # Set the strport based on the ip and port and start listening
92 # Set the strport based on the ip and port and start listening
93 if ip == '':
93 if ip == '':
94 strport = "tcp:%i" % port
94 strport = "tcp:%i" % port
95 else:
95 else:
96 strport = "tcp:%i:interface=%s" % (port, ip)
96 strport = "tcp:%i:interface=%s" % (port, ip)
97 listener = tub.listenOn(strport)
97 listener = tub.listenOn(strport)
98
98
99 return tub, listener
99 return tub, listener
100
100
101 def make_client_service(controller_service, config):
101 def make_client_service(controller_service, config):
102 """
102 """
103 Create a service that will listen for clients.
103 Create a service that will listen for clients.
104
104
105 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
105 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
106 registered with it.
106 registered with it.
107 """
107 """
108
108
109 # Now create the foolscap tub
109 # Now create the foolscap tub
110 ip = config['controller']['client_tub']['ip']
110 ip = config['controller']['client_tub']['ip']
111 port = config['controller']['client_tub'].as_int('port')
111 port = config['controller']['client_tub'].as_int('port')
112 location = config['controller']['client_tub']['location']
112 location = config['controller']['client_tub']['location']
113 secure = config['controller']['client_tub']['secure']
113 secure = config['controller']['client_tub']['secure']
114 cert_file = config['controller']['client_tub']['cert_file']
114 cert_file = config['controller']['client_tub']['cert_file']
115 client_tub, client_listener = make_tub(ip, port, secure, cert_file)
115 client_tub, client_listener = make_tub(ip, port, secure, cert_file)
116
116
117 # Set the location in the trivial case of localhost
117 # Set the location in the trivial case of localhost
118 if ip == 'localhost' or ip == '127.0.0.1':
118 if ip == 'localhost' or ip == '127.0.0.1':
119 location = "127.0.0.1"
119 location = "127.0.0.1"
120
120
121 if not secure:
121 if not secure:
122 log.msg("WARNING: you are running the controller with no client security")
122 log.msg("WARNING: you are running the controller with no client security")
123
123
124 def set_location_and_register():
124 def set_location_and_register():
125 """Set the location for the tub and return a deferred."""
125 """Set the location for the tub and return a deferred."""
126
126
127 def register(empty, ref, furl_file):
127 def register(empty, ref, furl_file):
128 # We create and then move to make sure that when the file
128 # We create and then move to make sure that when the file
129 # appears to other processes, the buffer has the flushed
129 # appears to other processes, the buffer has the flushed
130 # and the file has been closed
130 # and the file has been closed
131 temp_furl_file = get_temp_furlfile(furl_file)
131 temp_furl_file = get_temp_furlfile(furl_file)
132 client_tub.registerReference(ref, furlFile=temp_furl_file)
132 client_tub.registerReference(ref, furlFile=temp_furl_file)
133 os.rename(temp_furl_file, furl_file)
133 os.rename(temp_furl_file, furl_file)
134
134
135 if location == '':
135 if location == '':
136 d = client_tub.setLocationAutomatically()
136 d = client_tub.setLocationAutomatically()
137 else:
137 else:
138 d = defer.maybeDeferred(client_tub.setLocation, "%s:%i" % (location, client_listener.getPortnum()))
138 d = defer.maybeDeferred(client_tub.setLocation, "%s:%i" % (location, client_listener.getPortnum()))
139
139
140 for ciname, ci in config['controller']['controller_interfaces'].iteritems():
140 for ciname, ci in config['controller']['controller_interfaces'].iteritems():
141 log.msg("Adapting Controller to interface: %s" % ciname)
141 log.msg("Adapting Controller to interface: %s" % ciname)
142 furl_file = ci['furl_file']
142 furl_file = ci['furl_file']
143 log.msg("Saving furl for interface [%s] to file: %s" % (ciname, furl_file))
143 log.msg("Saving furl for interface [%s] to file: %s" % (ciname, furl_file))
144 check_furl_file_security(furl_file, secure)
144 check_furl_file_security(furl_file, secure)
145 adapted_controller = import_item(ci['controller_interface'])(controller_service)
145 adapted_controller = import_item(ci['controller_interface'])(controller_service)
146 d.addCallback(register, import_item(ci['fc_interface'])(adapted_controller),
146 d.addCallback(register, import_item(ci['fc_interface'])(adapted_controller),
147 furl_file=ci['furl_file'])
147 furl_file=ci['furl_file'])
148
148
149 reactor.callWhenRunning(set_location_and_register)
149 reactor.callWhenRunning(set_location_and_register)
150 return client_tub
150 return client_tub
151
151
152
152
153 def make_engine_service(controller_service, config):
153 def make_engine_service(controller_service, config):
154 """
154 """
155 Create a service that will listen for engines.
155 Create a service that will listen for engines.
156
156
157 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
157 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
158 registered with it.
158 registered with it.
159 """
159 """
160
160
161 # Now create the foolscap tub
161 # Now create the foolscap tub
162 ip = config['controller']['engine_tub']['ip']
162 ip = config['controller']['engine_tub']['ip']
163 port = config['controller']['engine_tub'].as_int('port')
163 port = config['controller']['engine_tub'].as_int('port')
164 location = config['controller']['engine_tub']['location']
164 location = config['controller']['engine_tub']['location']
165 secure = config['controller']['engine_tub']['secure']
165 secure = config['controller']['engine_tub']['secure']
166 cert_file = config['controller']['engine_tub']['cert_file']
166 cert_file = config['controller']['engine_tub']['cert_file']
167 engine_tub, engine_listener = make_tub(ip, port, secure, cert_file)
167 engine_tub, engine_listener = make_tub(ip, port, secure, cert_file)
168
168
169 # Set the location in the trivial case of localhost
169 # Set the location in the trivial case of localhost
170 if ip == 'localhost' or ip == '127.0.0.1':
170 if ip == 'localhost' or ip == '127.0.0.1':
171 location = "127.0.0.1"
171 location = "127.0.0.1"
172
172
173 if not secure:
173 if not secure:
174 log.msg("WARNING: you are running the controller with no engine security")
174 log.msg("WARNING: you are running the controller with no engine security")
175
175
176 def set_location_and_register():
176 def set_location_and_register():
177 """Set the location for the tub and return a deferred."""
177 """Set the location for the tub and return a deferred."""
178
178
179 def register(empty, ref, furl_file):
179 def register(empty, ref, furl_file):
180 # We create and then move to make sure that when the file
180 # We create and then move to make sure that when the file
181 # appears to other processes, the buffer has the flushed
181 # appears to other processes, the buffer has the flushed
182 # and the file has been closed
182 # and the file has been closed
183 temp_furl_file = get_temp_furlfile(furl_file)
183 temp_furl_file = get_temp_furlfile(furl_file)
184 engine_tub.registerReference(ref, furlFile=temp_furl_file)
184 engine_tub.registerReference(ref, furlFile=temp_furl_file)
185 os.rename(temp_furl_file, furl_file)
185 os.rename(temp_furl_file, furl_file)
186
186
187 if location == '':
187 if location == '':
188 d = engine_tub.setLocationAutomatically()
188 d = engine_tub.setLocationAutomatically()
189 else:
189 else:
190 d = defer.maybeDeferred(engine_tub.setLocation, "%s:%i" % (location, engine_listener.getPortnum()))
190 d = defer.maybeDeferred(engine_tub.setLocation, "%s:%i" % (location, engine_listener.getPortnum()))
191
191
192 furl_file = config['controller']['engine_furl_file']
192 furl_file = config['controller']['engine_furl_file']
193 engine_fc_interface = import_item(config['controller']['engine_fc_interface'])
193 engine_fc_interface = import_item(config['controller']['engine_fc_interface'])
194 log.msg("Saving furl for the engine to file: %s" % furl_file)
194 log.msg("Saving furl for the engine to file: %s" % furl_file)
195 check_furl_file_security(furl_file, secure)
195 check_furl_file_security(furl_file, secure)
196 fc_controller = engine_fc_interface(controller_service)
196 fc_controller = engine_fc_interface(controller_service)
197 d.addCallback(register, fc_controller, furl_file=furl_file)
197 d.addCallback(register, fc_controller, furl_file=furl_file)
198
198
199 reactor.callWhenRunning(set_location_and_register)
199 reactor.callWhenRunning(set_location_and_register)
200 return engine_tub
200 return engine_tub
201
201
202 def start_controller():
202 def start_controller():
203 """
203 """
204 Start the controller by creating the service hierarchy and starting the reactor.
204 Start the controller by creating the service hierarchy and starting the reactor.
205
205
206 This method does the following:
206 This method does the following:
207
207
208 * It starts the controller logging
208 * It starts the controller logging
209 * In execute an import statement for the controller
209 * In execute an import statement for the controller
210 * It creates 2 `foolscap.Tub` instances for the client and the engines
210 * It creates 2 `foolscap.Tub` instances for the client and the engines
211 and registers `foolscap.Referenceables` with the tubs to expose the
211 and registers `foolscap.Referenceables` with the tubs to expose the
212 controller to engines and clients.
212 controller to engines and clients.
213 """
213 """
214 config = kernel_config_manager.get_config_obj()
214 config = kernel_config_manager.get_config_obj()
215
215
216 # Start logging
216 # Start logging
217 logfile = config['controller']['logfile']
217 logfile = config['controller']['logfile']
218 if logfile:
218 if logfile:
219 logfile = logfile + str(os.getpid()) + '.log'
219 logfile = logfile + str(os.getpid()) + '.log'
220 try:
220 try:
221 openLogFile = open(logfile, 'w')
221 openLogFile = open(logfile, 'w')
222 except:
222 except:
223 openLogFile = sys.stdout
223 openLogFile = sys.stdout
224 else:
224 else:
225 openLogFile = sys.stdout
225 openLogFile = sys.stdout
226 log.startLogging(openLogFile)
226 log.startLogging(openLogFile)
227
227
228 # Execute any user defined import statements
228 # Execute any user defined import statements
229 cis = config['controller']['import_statement']
229 cis = config['controller']['import_statement']
230 if cis:
230 if cis:
231 try:
231 try:
232 exec cis in globals(), locals()
232 exec cis in globals(), locals()
233 except:
233 except:
234 log.msg("Error running import_statement: %s" % cis)
234 log.msg("Error running import_statement: %s" % cis)
235
235
236 # Delete old furl files unless the reuse_furls is set
236 # Delete old furl files unless the reuse_furls is set
237 reuse = config['controller']['reuse_furls']
237 reuse = config['controller']['reuse_furls']
238 if not reuse:
238 if not reuse:
239 paths = (config['controller']['engine_furl_file'],
239 paths = (config['controller']['engine_furl_file'],
240 config['controller']['controller_interfaces']['task']['furl_file'],
240 config['controller']['controller_interfaces']['task']['furl_file'],
241 config['controller']['controller_interfaces']['multiengine']['furl_file']
241 config['controller']['controller_interfaces']['multiengine']['furl_file']
242 )
242 )
243 for p in paths:
243 for p in paths:
244 if os.path.isfile(p):
244 if os.path.isfile(p):
245 os.remove(p)
245 os.remove(p)
246
246
247 # Create the service hierarchy
247 # Create the service hierarchy
248 main_service = service.MultiService()
248 main_service = service.MultiService()
249 # The controller service
249 # The controller service
250 controller_service = controllerservice.ControllerService()
250 controller_service = controllerservice.ControllerService()
251 controller_service.setServiceParent(main_service)
251 controller_service.setServiceParent(main_service)
252 # The client tub and all its refereceables
252 # The client tub and all its refereceables
253 client_service = make_client_service(controller_service, config)
253 client_service = make_client_service(controller_service, config)
254 client_service.setServiceParent(main_service)
254 client_service.setServiceParent(main_service)
255 # The engine tub
255 # The engine tub
256 engine_service = make_engine_service(controller_service, config)
256 engine_service = make_engine_service(controller_service, config)
257 engine_service.setServiceParent(main_service)
257 engine_service.setServiceParent(main_service)
258 # Start the controller service and set things running
258 # Start the controller service and set things running
259 main_service.startService()
259 main_service.startService()
260 reactor.run()
260 reactor.run()
261
261
262 def init_config():
262 def init_config():
263 """
263 """
264 Initialize the configuration using default and command line options.
264 Initialize the configuration using default and command line options.
265 """
265 """
266
266
267 parser = OptionParser("""ipcontroller [options]
267 parser = OptionParser("""ipcontroller [options]
268
268
269 Start an IPython controller.
269 Start an IPython controller.
270
270
271 Use the IPYTHONDIR environment variable to change your IPython directory
271 Use the IPYTHONDIR environment variable to change your IPython directory
272 from the default of .ipython or _ipython. The log and security
272 from the default of .ipython or _ipython. The log and security
273 subdirectories of your IPython directory will be used by this script
273 subdirectories of your IPython directory will be used by this script
274 for log files and security files.""")
274 for log files and security files.""")
275
275
276 # Client related options
276 # Client related options
277 parser.add_option(
277 parser.add_option(
278 "--client-ip",
278 "--client-ip",
279 type="string",
279 type="string",
280 dest="client_ip",
280 dest="client_ip",
281 help="the IP address or hostname the controller will listen on for client connections"
281 help="the IP address or hostname the controller will listen on for client connections"
282 )
282 )
283 parser.add_option(
283 parser.add_option(
284 "--client-port",
284 "--client-port",
285 type="int",
285 type="int",
286 dest="client_port",
286 dest="client_port",
287 help="the port the controller will listen on for client connections"
287 help="the port the controller will listen on for client connections"
288 )
288 )
289 parser.add_option(
289 parser.add_option(
290 '--client-location',
290 '--client-location',
291 type="string",
291 type="string",
292 dest="client_location",
292 dest="client_location",
293 help="hostname or ip for clients to connect to"
293 help="hostname or ip for clients to connect to"
294 )
294 )
295 parser.add_option(
295 parser.add_option(
296 "-x",
296 "-x",
297 action="store_false",
297 action="store_false",
298 dest="client_secure",
298 dest="client_secure",
299 help="turn off all client security"
299 help="turn off all client security"
300 )
300 )
301 parser.add_option(
301 parser.add_option(
302 '--client-cert-file',
302 '--client-cert-file',
303 type="string",
303 type="string",
304 dest="client_cert_file",
304 dest="client_cert_file",
305 help="file to store the client SSL certificate"
305 help="file to store the client SSL certificate"
306 )
306 )
307 parser.add_option(
307 parser.add_option(
308 '--task-furl-file',
308 '--task-furl-file',
309 type="string",
309 type="string",
310 dest="task_furl_file",
310 dest="task_furl_file",
311 help="file to store the FURL for task clients to connect with"
311 help="file to store the FURL for task clients to connect with"
312 )
312 )
313 parser.add_option(
313 parser.add_option(
314 '--multiengine-furl-file',
314 '--multiengine-furl-file',
315 type="string",
315 type="string",
316 dest="multiengine_furl_file",
316 dest="multiengine_furl_file",
317 help="file to store the FURL for multiengine clients to connect with"
317 help="file to store the FURL for multiengine clients to connect with"
318 )
318 )
319 # Engine related options
319 # Engine related options
320 parser.add_option(
320 parser.add_option(
321 "--engine-ip",
321 "--engine-ip",
322 type="string",
322 type="string",
323 dest="engine_ip",
323 dest="engine_ip",
324 help="the IP address or hostname the controller will listen on for engine connections"
324 help="the IP address or hostname the controller will listen on for engine connections"
325 )
325 )
326 parser.add_option(
326 parser.add_option(
327 "--engine-port",
327 "--engine-port",
328 type="int",
328 type="int",
329 dest="engine_port",
329 dest="engine_port",
330 help="the port the controller will listen on for engine connections"
330 help="the port the controller will listen on for engine connections"
331 )
331 )
332 parser.add_option(
332 parser.add_option(
333 '--engine-location',
333 '--engine-location',
334 type="string",
334 type="string",
335 dest="engine_location",
335 dest="engine_location",
336 help="hostname or ip for engines to connect to"
336 help="hostname or ip for engines to connect to"
337 )
337 )
338 parser.add_option(
338 parser.add_option(
339 "-y",
339 "-y",
340 action="store_false",
340 action="store_false",
341 dest="engine_secure",
341 dest="engine_secure",
342 help="turn off all engine security"
342 help="turn off all engine security"
343 )
343 )
344 parser.add_option(
344 parser.add_option(
345 '--engine-cert-file',
345 '--engine-cert-file',
346 type="string",
346 type="string",
347 dest="engine_cert_file",
347 dest="engine_cert_file",
348 help="file to store the engine SSL certificate"
348 help="file to store the engine SSL certificate"
349 )
349 )
350 parser.add_option(
350 parser.add_option(
351 '--engine-furl-file',
351 '--engine-furl-file',
352 type="string",
352 type="string",
353 dest="engine_furl_file",
353 dest="engine_furl_file",
354 help="file to store the FURL for engines to connect with"
354 help="file to store the FURL for engines to connect with"
355 )
355 )
356 parser.add_option(
356 parser.add_option(
357 "-l", "--logfile",
357 "-l", "--logfile",
358 type="string",
358 type="string",
359 dest="logfile",
359 dest="logfile",
360 help="log file name (default is stdout)"
360 help="log file name (default is stdout)"
361 )
361 )
362 parser.add_option(
362 parser.add_option(
363 "-r",
363 "-r",
364 action="store_true",
364 action="store_true",
365 dest="reuse_furls",
365 dest="reuse_furls",
366 help="try to reuse all furl files"
366 help="try to reuse all furl files"
367 )
367 )
368
368
369 (options, args) = parser.parse_args()
369 (options, args) = parser.parse_args()
370
370
371 config = kernel_config_manager.get_config_obj()
371 config = kernel_config_manager.get_config_obj()
372
372
373 # Update with command line options
373 # Update with command line options
374 if options.client_ip is not None:
374 if options.client_ip is not None:
375 config['controller']['client_tub']['ip'] = options.client_ip
375 config['controller']['client_tub']['ip'] = options.client_ip
376 if options.client_port is not None:
376 if options.client_port is not None:
377 config['controller']['client_tub']['port'] = options.client_port
377 config['controller']['client_tub']['port'] = options.client_port
378 if options.client_location is not None:
378 if options.client_location is not None:
379 config['controller']['client_tub']['location'] = options.client_location
379 config['controller']['client_tub']['location'] = options.client_location
380 if options.client_secure is not None:
380 if options.client_secure is not None:
381 config['controller']['client_tub']['secure'] = options.client_secure
381 config['controller']['client_tub']['secure'] = options.client_secure
382 if options.client_cert_file is not None:
382 if options.client_cert_file is not None:
383 config['controller']['client_tub']['cert_file'] = options.client_cert_file
383 config['controller']['client_tub']['cert_file'] = options.client_cert_file
384 if options.task_furl_file is not None:
384 if options.task_furl_file is not None:
385 config['controller']['controller_interfaces']['task']['furl_file'] = options.task_furl_file
385 config['controller']['controller_interfaces']['task']['furl_file'] = options.task_furl_file
386 if options.multiengine_furl_file is not None:
386 if options.multiengine_furl_file is not None:
387 config['controller']['controller_interfaces']['multiengine']['furl_file'] = options.multiengine_furl_file
387 config['controller']['controller_interfaces']['multiengine']['furl_file'] = options.multiengine_furl_file
388 if options.engine_ip is not None:
388 if options.engine_ip is not None:
389 config['controller']['engine_tub']['ip'] = options.engine_ip
389 config['controller']['engine_tub']['ip'] = options.engine_ip
390 if options.engine_port is not None:
390 if options.engine_port is not None:
391 config['controller']['engine_tub']['port'] = options.engine_port
391 config['controller']['engine_tub']['port'] = options.engine_port
392 if options.engine_location is not None:
392 if options.engine_location is not None:
393 config['controller']['engine_tub']['location'] = options.engine_location
393 config['controller']['engine_tub']['location'] = options.engine_location
394 if options.engine_secure is not None:
394 if options.engine_secure is not None:
395 config['controller']['engine_tub']['secure'] = options.engine_secure
395 config['controller']['engine_tub']['secure'] = options.engine_secure
396 if options.engine_cert_file is not None:
396 if options.engine_cert_file is not None:
397 config['controller']['engine_tub']['cert_file'] = options.engine_cert_file
397 config['controller']['engine_tub']['cert_file'] = options.engine_cert_file
398 if options.engine_furl_file is not None:
398 if options.engine_furl_file is not None:
399 config['controller']['engine_furl_file'] = options.engine_furl_file
399 config['controller']['engine_furl_file'] = options.engine_furl_file
400 if options.reuse_furls is not None:
400 if options.reuse_furls is not None:
401 config['controller']['reuse_furls'] = options.reuse_furls
401 config['controller']['reuse_furls'] = options.reuse_furls
402
402
403 if options.logfile is not None:
403 if options.logfile is not None:
404 config['controller']['logfile'] = options.logfile
404 config['controller']['logfile'] = options.logfile
405
405
406 kernel_config_manager.update_config_obj(config)
406 kernel_config_manager.update_config_obj(config)
407
407
408 def main():
408 def main():
409 """
409 """
410 After creating the configuration information, start the controller.
410 After creating the configuration information, start the controller.
411 """
411 """
412 init_config()
412 init_config()
413 start_controller()
413 start_controller()
414
414
415 if __name__ == "__main__":
415 if __name__ == "__main__":
416 main()
416 main()
@@ -1,193 +1,193 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 """Start the IPython Engine."""
4 """Start the IPython Engine."""
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 # Python looks for an empty string at the beginning of sys.path to enable
19 # Python looks for an empty string at the beginning of sys.path to enable
20 # importing from the cwd.
20 # importing from the cwd.
21 import sys
21 import sys
22 sys.path.insert(0, '')
22 sys.path.insert(0, '')
23
23
24 from optparse import OptionParser
24 from optparse import OptionParser
25 import os
25 import os
26
26
27 from twisted.application import service
27 from twisted.application import service
28 from twisted.internet import reactor
28 from twisted.internet import reactor
29 from twisted.python import log
29 from twisted.python import log
30
30
31 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
31 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
32
32
33 from IPython.kernel.core.config import config_manager as core_config_manager
33 from IPython.kernel.core.config import config_manager as core_config_manager
34 from IPython.config.cutils import import_item
34 from IPython.utils.importstring import import_item
35 from IPython.kernel.engineservice import EngineService
35 from IPython.kernel.engineservice import EngineService
36
36
37 # Create various ipython directories if they don't exist.
37 # Create various ipython directories if they don't exist.
38 # This must be done before IPython.kernel.config is imported.
38 # This must be done before IPython.kernel.config is imported.
39 from IPython.core.oldusersetup import user_setup
39 from IPython.core.oldusersetup import user_setup
40 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
40 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
41 if os.name == 'posix':
41 if os.name == 'posix':
42 rc_suffix = ''
42 rc_suffix = ''
43 else:
43 else:
44 rc_suffix = '.ini'
44 rc_suffix = '.ini'
45 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
45 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
46 get_log_dir()
46 get_log_dir()
47 get_security_dir()
47 get_security_dir()
48
48
49 from IPython.kernel.config import config_manager as kernel_config_manager
49 from IPython.kernel.config import config_manager as kernel_config_manager
50 from IPython.kernel.engineconnector import EngineConnector
50 from IPython.kernel.engineconnector import EngineConnector
51
51
52
52
53 #-------------------------------------------------------------------------------
53 #-------------------------------------------------------------------------------
54 # Code
54 # Code
55 #-------------------------------------------------------------------------------
55 #-------------------------------------------------------------------------------
56
56
57 def start_engine():
57 def start_engine():
58 """
58 """
59 Start the engine, by creating it and starting the Twisted reactor.
59 Start the engine, by creating it and starting the Twisted reactor.
60
60
61 This method does:
61 This method does:
62
62
63 * If it exists, runs the `mpi_import_statement` to call `MPI_Init`
63 * If it exists, runs the `mpi_import_statement` to call `MPI_Init`
64 * Starts the engine logging
64 * Starts the engine logging
65 * Creates an IPython shell and wraps it in an `EngineService`
65 * Creates an IPython shell and wraps it in an `EngineService`
66 * Creates a `foolscap.Tub` to use in connecting to a controller.
66 * Creates a `foolscap.Tub` to use in connecting to a controller.
67 * Uses the tub and the `EngineService` along with a Foolscap URL
67 * Uses the tub and the `EngineService` along with a Foolscap URL
68 (or FURL) to connect to the controller and register the engine
68 (or FURL) to connect to the controller and register the engine
69 with the controller
69 with the controller
70 """
70 """
71 kernel_config = kernel_config_manager.get_config_obj()
71 kernel_config = kernel_config_manager.get_config_obj()
72 core_config = core_config_manager.get_config_obj()
72 core_config = core_config_manager.get_config_obj()
73
73
74
74
75 # Execute the mpi import statement that needs to call MPI_Init
75 # Execute the mpi import statement that needs to call MPI_Init
76 global mpi
76 global mpi
77 mpikey = kernel_config['mpi']['default']
77 mpikey = kernel_config['mpi']['default']
78 mpi_import_statement = kernel_config['mpi'].get(mpikey, None)
78 mpi_import_statement = kernel_config['mpi'].get(mpikey, None)
79 if mpi_import_statement is not None:
79 if mpi_import_statement is not None:
80 try:
80 try:
81 exec mpi_import_statement in globals()
81 exec mpi_import_statement in globals()
82 except:
82 except:
83 mpi = None
83 mpi = None
84 else:
84 else:
85 mpi = None
85 mpi = None
86
86
87 # Start logging
87 # Start logging
88 logfile = kernel_config['engine']['logfile']
88 logfile = kernel_config['engine']['logfile']
89 if logfile:
89 if logfile:
90 logfile = logfile + str(os.getpid()) + '.log'
90 logfile = logfile + str(os.getpid()) + '.log'
91 try:
91 try:
92 openLogFile = open(logfile, 'w')
92 openLogFile = open(logfile, 'w')
93 except:
93 except:
94 openLogFile = sys.stdout
94 openLogFile = sys.stdout
95 else:
95 else:
96 openLogFile = sys.stdout
96 openLogFile = sys.stdout
97 log.startLogging(openLogFile)
97 log.startLogging(openLogFile)
98
98
99 # Create the underlying shell class and EngineService
99 # Create the underlying shell class and EngineService
100 shell_class = import_item(core_config['shell']['shell_class'])
100 shell_class = import_item(core_config['shell']['shell_class'])
101 engine_service = EngineService(shell_class, mpi=mpi)
101 engine_service = EngineService(shell_class, mpi=mpi)
102 shell_import_statement = core_config['shell']['import_statement']
102 shell_import_statement = core_config['shell']['import_statement']
103 if shell_import_statement:
103 if shell_import_statement:
104 try:
104 try:
105 engine_service.execute(shell_import_statement)
105 engine_service.execute(shell_import_statement)
106 except:
106 except:
107 log.msg("Error running import_statement: %s" % shell_import_statement)
107 log.msg("Error running import_statement: %s" % shell_import_statement)
108
108
109 # Create the service hierarchy
109 # Create the service hierarchy
110 main_service = service.MultiService()
110 main_service = service.MultiService()
111 engine_service.setServiceParent(main_service)
111 engine_service.setServiceParent(main_service)
112 tub_service = Tub()
112 tub_service = Tub()
113 tub_service.setServiceParent(main_service)
113 tub_service.setServiceParent(main_service)
114 # This needs to be called before the connection is initiated
114 # This needs to be called before the connection is initiated
115 main_service.startService()
115 main_service.startService()
116
116
117 # This initiates the connection to the controller and calls
117 # This initiates the connection to the controller and calls
118 # register_engine to tell the controller we are ready to do work
118 # register_engine to tell the controller we are ready to do work
119 engine_connector = EngineConnector(tub_service)
119 engine_connector = EngineConnector(tub_service)
120 furl_file = kernel_config['engine']['furl_file']
120 furl_file = kernel_config['engine']['furl_file']
121 log.msg("Using furl file: %s" % furl_file)
121 log.msg("Using furl file: %s" % furl_file)
122
122
123 def call_connect(engine_service, furl_file):
123 def call_connect(engine_service, furl_file):
124 d = engine_connector.connect_to_controller(engine_service, furl_file)
124 d = engine_connector.connect_to_controller(engine_service, furl_file)
125 def handle_error(f):
125 def handle_error(f):
126 # If this print statement is replaced by a log.err(f) I get
126 # If this print statement is replaced by a log.err(f) I get
127 # an unhandled error, which makes no sense. I shouldn't have
127 # an unhandled error, which makes no sense. I shouldn't have
128 # to use a print statement here. My only thought is that
128 # to use a print statement here. My only thought is that
129 # at the beginning of the process the logging is still starting up
129 # at the beginning of the process the logging is still starting up
130 print "error connecting to controller:", f.getErrorMessage()
130 print "error connecting to controller:", f.getErrorMessage()
131 reactor.callLater(0.1, reactor.stop)
131 reactor.callLater(0.1, reactor.stop)
132 d.addErrback(handle_error)
132 d.addErrback(handle_error)
133
133
134 reactor.callWhenRunning(call_connect, engine_service, furl_file)
134 reactor.callWhenRunning(call_connect, engine_service, furl_file)
135 reactor.run()
135 reactor.run()
136
136
137
137
138 def init_config():
138 def init_config():
139 """
139 """
140 Initialize the configuration using default and command line options.
140 Initialize the configuration using default and command line options.
141 """
141 """
142
142
143 parser = OptionParser("""ipengine [options]
143 parser = OptionParser("""ipengine [options]
144
144
145 Start an IPython engine.
145 Start an IPython engine.
146
146
147 Use the IPYTHONDIR environment variable to change your IPython directory
147 Use the IPYTHONDIR environment variable to change your IPython directory
148 from the default of .ipython or _ipython. The log and security
148 from the default of .ipython or _ipython. The log and security
149 subdirectories of your IPython directory will be used by this script
149 subdirectories of your IPython directory will be used by this script
150 for log files and security files.""")
150 for log files and security files.""")
151
151
152 parser.add_option(
152 parser.add_option(
153 "--furl-file",
153 "--furl-file",
154 type="string",
154 type="string",
155 dest="furl_file",
155 dest="furl_file",
156 help="The filename containing the FURL of the controller"
156 help="The filename containing the FURL of the controller"
157 )
157 )
158 parser.add_option(
158 parser.add_option(
159 "--mpi",
159 "--mpi",
160 type="string",
160 type="string",
161 dest="mpi",
161 dest="mpi",
162 help="How to enable MPI (mpi4py, pytrilinos, or empty string to disable)"
162 help="How to enable MPI (mpi4py, pytrilinos, or empty string to disable)"
163 )
163 )
164 parser.add_option(
164 parser.add_option(
165 "-l",
165 "-l",
166 "--logfile",
166 "--logfile",
167 type="string",
167 type="string",
168 dest="logfile",
168 dest="logfile",
169 help="log file name (default is stdout)"
169 help="log file name (default is stdout)"
170 )
170 )
171
171
172 (options, args) = parser.parse_args()
172 (options, args) = parser.parse_args()
173
173
174 kernel_config = kernel_config_manager.get_config_obj()
174 kernel_config = kernel_config_manager.get_config_obj()
175 # Now override with command line options
175 # Now override with command line options
176 if options.furl_file is not None:
176 if options.furl_file is not None:
177 kernel_config['engine']['furl_file'] = options.furl_file
177 kernel_config['engine']['furl_file'] = options.furl_file
178 if options.logfile is not None:
178 if options.logfile is not None:
179 kernel_config['engine']['logfile'] = options.logfile
179 kernel_config['engine']['logfile'] = options.logfile
180 if options.mpi is not None:
180 if options.mpi is not None:
181 kernel_config['mpi']['default'] = options.mpi
181 kernel_config['mpi']['default'] = options.mpi
182
182
183
183
184 def main():
184 def main():
185 """
185 """
186 After creating the configuration information, start the engine.
186 After creating the configuration information, start the engine.
187 """
187 """
188 init_config()
188 init_config()
189 start_engine()
189 start_engine()
190
190
191
191
192 if __name__ == "__main__":
192 if __name__ == "__main__":
193 main()
193 main()
@@ -1,670 +1,687 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.utils.traitlets.
4 Tests for IPython.utils.traitlets.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
10 and is licensed under the BSD license. Also, many of the ideas also come
10 and is licensed under the BSD license. Also, many of the ideas also come
11 from enthought.traits even though our implementation is very different.
11 from enthought.traits even though our implementation is very different.
12 """
12 """
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Copyright (C) 2008-2009 The IPython Development Team
15 # Copyright (C) 2008-2009 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 import sys
25 import sys
26 import os
26 import os
27
27
28
28
29 from unittest import TestCase
29 from unittest import TestCase
30
30
31 from IPython.utils.traitlets import (
31 from IPython.utils.traitlets import (
32 HasTraitlets, MetaHasTraitlets, TraitletType, Any,
32 HasTraitlets, MetaHasTraitlets, TraitletType, Any,
33 Int, Long, Float, Complex, Str, Unicode, Bool, TraitletError,
33 Int, Long, Float, Complex, Str, Unicode, Bool, TraitletError,
34 Undefined, Type, This, Instance
34 Undefined, Type, This, Instance
35 )
35 )
36
36
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Helper classes for testing
39 # Helper classes for testing
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42
42
43 class HasTraitletsStub(HasTraitlets):
43 class HasTraitletsStub(HasTraitlets):
44
44
45 def _notify_traitlet(self, name, old, new):
45 def _notify_traitlet(self, name, old, new):
46 self._notify_name = name
46 self._notify_name = name
47 self._notify_old = old
47 self._notify_old = old
48 self._notify_new = new
48 self._notify_new = new
49
49
50
50
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52 # Test classes
52 # Test classes
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54
54
55
55
56 class TestTraitletType(TestCase):
56 class TestTraitletType(TestCase):
57
57
58 def test_get_undefined(self):
58 def test_get_undefined(self):
59 class A(HasTraitlets):
59 class A(HasTraitlets):
60 a = TraitletType
60 a = TraitletType
61 a = A()
61 a = A()
62 self.assertEquals(a.a, Undefined)
62 self.assertEquals(a.a, Undefined)
63
63
64 def test_set(self):
64 def test_set(self):
65 class A(HasTraitletsStub):
65 class A(HasTraitletsStub):
66 a = TraitletType
66 a = TraitletType
67
67
68 a = A()
68 a = A()
69 a.a = 10
69 a.a = 10
70 self.assertEquals(a.a, 10)
70 self.assertEquals(a.a, 10)
71 self.assertEquals(a._notify_name, 'a')
71 self.assertEquals(a._notify_name, 'a')
72 self.assertEquals(a._notify_old, Undefined)
72 self.assertEquals(a._notify_old, Undefined)
73 self.assertEquals(a._notify_new, 10)
73 self.assertEquals(a._notify_new, 10)
74
74
75 def test_validate(self):
75 def test_validate(self):
76 class MyTT(TraitletType):
76 class MyTT(TraitletType):
77 def validate(self, inst, value):
77 def validate(self, inst, value):
78 return -1
78 return -1
79 class A(HasTraitletsStub):
79 class A(HasTraitletsStub):
80 tt = MyTT
80 tt = MyTT
81
81
82 a = A()
82 a = A()
83 a.tt = 10
83 a.tt = 10
84 self.assertEquals(a.tt, -1)
84 self.assertEquals(a.tt, -1)
85
85
86 def test_default_validate(self):
86 def test_default_validate(self):
87 class MyIntTT(TraitletType):
87 class MyIntTT(TraitletType):
88 def validate(self, obj, value):
88 def validate(self, obj, value):
89 if isinstance(value, int):
89 if isinstance(value, int):
90 return value
90 return value
91 self.error(obj, value)
91 self.error(obj, value)
92 class A(HasTraitlets):
92 class A(HasTraitlets):
93 tt = MyIntTT(10)
93 tt = MyIntTT(10)
94 a = A()
94 a = A()
95 self.assertEquals(a.tt, 10)
95 self.assertEquals(a.tt, 10)
96
96
97 # Defaults are validated when the HasTraitlets is instantiated
97 # Defaults are validated when the HasTraitlets is instantiated
98 class B(HasTraitlets):
98 class B(HasTraitlets):
99 tt = MyIntTT('bad default')
99 tt = MyIntTT('bad default')
100 self.assertRaises(TraitletError, B)
100 self.assertRaises(TraitletError, B)
101
101
102 def test_is_valid_for(self):
102 def test_is_valid_for(self):
103 class MyTT(TraitletType):
103 class MyTT(TraitletType):
104 def is_valid_for(self, value):
104 def is_valid_for(self, value):
105 return True
105 return True
106 class A(HasTraitlets):
106 class A(HasTraitlets):
107 tt = MyTT
107 tt = MyTT
108
108
109 a = A()
109 a = A()
110 a.tt = 10
110 a.tt = 10
111 self.assertEquals(a.tt, 10)
111 self.assertEquals(a.tt, 10)
112
112
113 def test_value_for(self):
113 def test_value_for(self):
114 class MyTT(TraitletType):
114 class MyTT(TraitletType):
115 def value_for(self, value):
115 def value_for(self, value):
116 return 20
116 return 20
117 class A(HasTraitlets):
117 class A(HasTraitlets):
118 tt = MyTT
118 tt = MyTT
119
119
120 a = A()
120 a = A()
121 a.tt = 10
121 a.tt = 10
122 self.assertEquals(a.tt, 20)
122 self.assertEquals(a.tt, 20)
123
123
124 def test_info(self):
124 def test_info(self):
125 class A(HasTraitlets):
125 class A(HasTraitlets):
126 tt = TraitletType
126 tt = TraitletType
127 a = A()
127 a = A()
128 self.assertEquals(A.tt.info(), 'any value')
128 self.assertEquals(A.tt.info(), 'any value')
129
129
130 def test_error(self):
130 def test_error(self):
131 class A(HasTraitlets):
131 class A(HasTraitlets):
132 tt = TraitletType
132 tt = TraitletType
133 a = A()
133 a = A()
134 self.assertRaises(TraitletError, A.tt.error, a, 10)
134 self.assertRaises(TraitletError, A.tt.error, a, 10)
135
135
136
136
137 class TestHasTraitletsMeta(TestCase):
137 class TestHasTraitletsMeta(TestCase):
138
138
139 def test_metaclass(self):
139 def test_metaclass(self):
140 self.assertEquals(type(HasTraitlets), MetaHasTraitlets)
140 self.assertEquals(type(HasTraitlets), MetaHasTraitlets)
141
141
142 class A(HasTraitlets):
142 class A(HasTraitlets):
143 a = Int
143 a = Int
144
144
145 a = A()
145 a = A()
146 self.assertEquals(type(a.__class__), MetaHasTraitlets)
146 self.assertEquals(type(a.__class__), MetaHasTraitlets)
147 self.assertEquals(a.a,0)
147 self.assertEquals(a.a,0)
148 a.a = 10
148 a.a = 10
149 self.assertEquals(a.a,10)
149 self.assertEquals(a.a,10)
150
150
151 class B(HasTraitlets):
151 class B(HasTraitlets):
152 b = Int()
152 b = Int()
153
153
154 b = B()
154 b = B()
155 self.assertEquals(b.b,0)
155 self.assertEquals(b.b,0)
156 b.b = 10
156 b.b = 10
157 self.assertEquals(b.b,10)
157 self.assertEquals(b.b,10)
158
158
159 class C(HasTraitlets):
159 class C(HasTraitlets):
160 c = Int(30)
160 c = Int(30)
161
161
162 c = C()
162 c = C()
163 self.assertEquals(c.c,30)
163 self.assertEquals(c.c,30)
164 c.c = 10
164 c.c = 10
165 self.assertEquals(c.c,10)
165 self.assertEquals(c.c,10)
166
166
167 def test_this_class(self):
167 def test_this_class(self):
168 class A(HasTraitlets):
168 class A(HasTraitlets):
169 t = This()
169 t = This()
170 tt = This()
170 tt = This()
171 class B(A):
171 class B(A):
172 tt = This()
172 tt = This()
173 ttt = This()
173 ttt = This()
174 self.assertEquals(A.t.this_class, A)
174 self.assertEquals(A.t.this_class, A)
175 self.assertEquals(B.t.this_class, A)
175 self.assertEquals(B.t.this_class, A)
176 self.assertEquals(B.tt.this_class, B)
176 self.assertEquals(B.tt.this_class, B)
177 self.assertEquals(B.ttt.this_class, B)
177 self.assertEquals(B.ttt.this_class, B)
178
178
179 class TestHasTraitletsNotify(TestCase):
179 class TestHasTraitletsNotify(TestCase):
180
180
181 def setUp(self):
181 def setUp(self):
182 self._notify1 = []
182 self._notify1 = []
183 self._notify2 = []
183 self._notify2 = []
184
184
185 def notify1(self, name, old, new):
185 def notify1(self, name, old, new):
186 self._notify1.append((name, old, new))
186 self._notify1.append((name, old, new))
187
187
188 def notify2(self, name, old, new):
188 def notify2(self, name, old, new):
189 self._notify2.append((name, old, new))
189 self._notify2.append((name, old, new))
190
190
191 def test_notify_all(self):
191 def test_notify_all(self):
192
192
193 class A(HasTraitlets):
193 class A(HasTraitlets):
194 a = Int
194 a = Int
195 b = Float
195 b = Float
196
196
197 a = A()
197 a = A()
198 a.on_traitlet_change(self.notify1)
198 a.on_traitlet_change(self.notify1)
199 a.a = 0
199 a.a = 0
200 self.assertEquals(len(self._notify1),0)
200 self.assertEquals(len(self._notify1),0)
201 a.b = 0.0
201 a.b = 0.0
202 self.assertEquals(len(self._notify1),0)
202 self.assertEquals(len(self._notify1),0)
203 a.a = 10
203 a.a = 10
204 self.assert_(('a',0,10) in self._notify1)
204 self.assert_(('a',0,10) in self._notify1)
205 a.b = 10.0
205 a.b = 10.0
206 self.assert_(('b',0.0,10.0) in self._notify1)
206 self.assert_(('b',0.0,10.0) in self._notify1)
207 self.assertRaises(TraitletError,setattr,a,'a','bad string')
207 self.assertRaises(TraitletError,setattr,a,'a','bad string')
208 self.assertRaises(TraitletError,setattr,a,'b','bad string')
208 self.assertRaises(TraitletError,setattr,a,'b','bad string')
209 self._notify1 = []
209 self._notify1 = []
210 a.on_traitlet_change(self.notify1,remove=True)
210 a.on_traitlet_change(self.notify1,remove=True)
211 a.a = 20
211 a.a = 20
212 a.b = 20.0
212 a.b = 20.0
213 self.assertEquals(len(self._notify1),0)
213 self.assertEquals(len(self._notify1),0)
214
214
215 def test_notify_one(self):
215 def test_notify_one(self):
216
216
217 class A(HasTraitlets):
217 class A(HasTraitlets):
218 a = Int
218 a = Int
219 b = Float
219 b = Float
220
220
221 a = A()
221 a = A()
222 a.on_traitlet_change(self.notify1, 'a')
222 a.on_traitlet_change(self.notify1, 'a')
223 a.a = 0
223 a.a = 0
224 self.assertEquals(len(self._notify1),0)
224 self.assertEquals(len(self._notify1),0)
225 a.a = 10
225 a.a = 10
226 self.assert_(('a',0,10) in self._notify1)
226 self.assert_(('a',0,10) in self._notify1)
227 self.assertRaises(TraitletError,setattr,a,'a','bad string')
227 self.assertRaises(TraitletError,setattr,a,'a','bad string')
228
228
229 def test_subclass(self):
229 def test_subclass(self):
230
230
231 class A(HasTraitlets):
231 class A(HasTraitlets):
232 a = Int
232 a = Int
233
233
234 class B(A):
234 class B(A):
235 b = Float
235 b = Float
236
236
237 b = B()
237 b = B()
238 self.assertEquals(b.a,0)
238 self.assertEquals(b.a,0)
239 self.assertEquals(b.b,0.0)
239 self.assertEquals(b.b,0.0)
240 b.a = 100
240 b.a = 100
241 b.b = 100.0
241 b.b = 100.0
242 self.assertEquals(b.a,100)
242 self.assertEquals(b.a,100)
243 self.assertEquals(b.b,100.0)
243 self.assertEquals(b.b,100.0)
244
244
245 def test_notify_subclass(self):
245 def test_notify_subclass(self):
246
246
247 class A(HasTraitlets):
247 class A(HasTraitlets):
248 a = Int
248 a = Int
249
249
250 class B(A):
250 class B(A):
251 b = Float
251 b = Float
252
252
253 b = B()
253 b = B()
254 b.on_traitlet_change(self.notify1, 'a')
254 b.on_traitlet_change(self.notify1, 'a')
255 b.on_traitlet_change(self.notify2, 'b')
255 b.on_traitlet_change(self.notify2, 'b')
256 b.a = 0
256 b.a = 0
257 b.b = 0.0
257 b.b = 0.0
258 self.assertEquals(len(self._notify1),0)
258 self.assertEquals(len(self._notify1),0)
259 self.assertEquals(len(self._notify2),0)
259 self.assertEquals(len(self._notify2),0)
260 b.a = 10
260 b.a = 10
261 b.b = 10.0
261 b.b = 10.0
262 self.assert_(('a',0,10) in self._notify1)
262 self.assert_(('a',0,10) in self._notify1)
263 self.assert_(('b',0.0,10.0) in self._notify2)
263 self.assert_(('b',0.0,10.0) in self._notify2)
264
264
265 def test_static_notify(self):
265 def test_static_notify(self):
266
266
267 class A(HasTraitlets):
267 class A(HasTraitlets):
268 a = Int
268 a = Int
269 _notify1 = []
269 _notify1 = []
270 def _a_changed(self, name, old, new):
270 def _a_changed(self, name, old, new):
271 self._notify1.append((name, old, new))
271 self._notify1.append((name, old, new))
272
272
273 a = A()
273 a = A()
274 a.a = 0
274 a.a = 0
275 # This is broken!!!
275 # This is broken!!!
276 self.assertEquals(len(a._notify1),0)
276 self.assertEquals(len(a._notify1),0)
277 a.a = 10
277 a.a = 10
278 self.assert_(('a',0,10) in a._notify1)
278 self.assert_(('a',0,10) in a._notify1)
279
279
280 class B(A):
280 class B(A):
281 b = Float
281 b = Float
282 _notify2 = []
282 _notify2 = []
283 def _b_changed(self, name, old, new):
283 def _b_changed(self, name, old, new):
284 self._notify2.append((name, old, new))
284 self._notify2.append((name, old, new))
285
285
286 b = B()
286 b = B()
287 b.a = 10
287 b.a = 10
288 b.b = 10.0
288 b.b = 10.0
289 self.assert_(('a',0,10) in b._notify1)
289 self.assert_(('a',0,10) in b._notify1)
290 self.assert_(('b',0.0,10.0) in b._notify2)
290 self.assert_(('b',0.0,10.0) in b._notify2)
291
291
292 def test_notify_args(self):
292 def test_notify_args(self):
293
293
294 def callback0():
294 def callback0():
295 self.cb = ()
295 self.cb = ()
296 def callback1(name):
296 def callback1(name):
297 self.cb = (name,)
297 self.cb = (name,)
298 def callback2(name, new):
298 def callback2(name, new):
299 self.cb = (name, new)
299 self.cb = (name, new)
300 def callback3(name, old, new):
300 def callback3(name, old, new):
301 self.cb = (name, old, new)
301 self.cb = (name, old, new)
302
302
303 class A(HasTraitlets):
303 class A(HasTraitlets):
304 a = Int
304 a = Int
305
305
306 a = A()
306 a = A()
307 a.on_traitlet_change(callback0, 'a')
307 a.on_traitlet_change(callback0, 'a')
308 a.a = 10
308 a.a = 10
309 self.assertEquals(self.cb,())
309 self.assertEquals(self.cb,())
310 a.on_traitlet_change(callback0, 'a', remove=True)
310 a.on_traitlet_change(callback0, 'a', remove=True)
311
311
312 a.on_traitlet_change(callback1, 'a')
312 a.on_traitlet_change(callback1, 'a')
313 a.a = 100
313 a.a = 100
314 self.assertEquals(self.cb,('a',))
314 self.assertEquals(self.cb,('a',))
315 a.on_traitlet_change(callback1, 'a', remove=True)
315 a.on_traitlet_change(callback1, 'a', remove=True)
316
316
317 a.on_traitlet_change(callback2, 'a')
317 a.on_traitlet_change(callback2, 'a')
318 a.a = 1000
318 a.a = 1000
319 self.assertEquals(self.cb,('a',1000))
319 self.assertEquals(self.cb,('a',1000))
320 a.on_traitlet_change(callback2, 'a', remove=True)
320 a.on_traitlet_change(callback2, 'a', remove=True)
321
321
322 a.on_traitlet_change(callback3, 'a')
322 a.on_traitlet_change(callback3, 'a')
323 a.a = 10000
323 a.a = 10000
324 self.assertEquals(self.cb,('a',1000,10000))
324 self.assertEquals(self.cb,('a',1000,10000))
325 a.on_traitlet_change(callback3, 'a', remove=True)
325 a.on_traitlet_change(callback3, 'a', remove=True)
326
326
327 self.assertEquals(len(a._traitlet_notifiers['a']),0)
327 self.assertEquals(len(a._traitlet_notifiers['a']),0)
328
328
329
329
330 class TestHasTraitlets(TestCase):
330 class TestHasTraitlets(TestCase):
331
331
332 def test_traitlet_names(self):
332 def test_traitlet_names(self):
333 class A(HasTraitlets):
333 class A(HasTraitlets):
334 i = Int
334 i = Int
335 f = Float
335 f = Float
336 a = A()
336 a = A()
337 self.assertEquals(a.traitlet_names(),['i','f'])
337 self.assertEquals(a.traitlet_names(),['i','f'])
338
338
339 def test_traitlet_metadata(self):
339 def test_traitlet_metadata(self):
340 class A(HasTraitlets):
340 class A(HasTraitlets):
341 i = Int(config_key='MY_VALUE')
341 i = Int(config_key='MY_VALUE')
342 a = A()
342 a = A()
343 self.assertEquals(a.traitlet_metadata('i','config_key'), 'MY_VALUE')
343 self.assertEquals(a.traitlet_metadata('i','config_key'), 'MY_VALUE')
344
344
345 def test_traitlets(self):
345 def test_traitlets(self):
346 class A(HasTraitlets):
346 class A(HasTraitlets):
347 i = Int
347 i = Int
348 f = Float
348 f = Float
349 a = A()
349 a = A()
350 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
350 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
351
351
352 def test_traitlets_metadata(self):
352 def test_traitlets_metadata(self):
353 class A(HasTraitlets):
353 class A(HasTraitlets):
354 i = Int(config_key='VALUE1', other_thing='VALUE2')
354 i = Int(config_key='VALUE1', other_thing='VALUE2')
355 f = Float(config_key='VALUE3', other_thing='VALUE2')
355 f = Float(config_key='VALUE3', other_thing='VALUE2')
356 a = A()
356 a = A()
357 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
357 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
358 traitlets = a.traitlets(config_key=lambda v: True)
358 traitlets = a.traitlets(config_key=lambda v: True)
359 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
359 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
360 traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2')
360 traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2')
361 self.assertEquals(traitlets, dict(i=A.i))
361 self.assertEquals(traitlets, dict(i=A.i))
362 traitlets = a.traitlets('config_key')
362 traitlets = a.traitlets('config_key')
363 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
363 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
364
364
365 #-----------------------------------------------------------------------------
365 #-----------------------------------------------------------------------------
366 # Tests for specific traitlet types
366 # Tests for specific traitlet types
367 #-----------------------------------------------------------------------------
367 #-----------------------------------------------------------------------------
368
368
369
369
370 class TestType(TestCase):
370 class TestType(TestCase):
371
371
372 def test_default(self):
372 def test_default(self):
373
373
374 class B(object): pass
374 class B(object): pass
375 class A(HasTraitlets):
375 class A(HasTraitlets):
376 klass = Type
376 klass = Type
377
377
378 a = A()
378 a = A()
379 self.assertEquals(a.klass, None)
379 self.assertEquals(a.klass, None)
380
380 a.klass = B
381 a.klass = B
381 self.assertEquals(a.klass, B)
382 self.assertEquals(a.klass, B)
382 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
383 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
383
384
384 def test_value(self):
385 def test_value(self):
385
386
386 class B(object): pass
387 class B(object): pass
387 class C(object): pass
388 class C(object): pass
388 class A(HasTraitlets):
389 class A(HasTraitlets):
389 klass = Type(B)
390 klass = Type(B)
390
391
391 a = A()
392 a = A()
392 self.assertEquals(a.klass, B)
393 self.assertEquals(a.klass, B)
393 self.assertRaises(TraitletError, setattr, a, 'klass', C)
394 self.assertRaises(TraitletError, setattr, a, 'klass', C)
394 self.assertRaises(TraitletError, setattr, a, 'klass', object)
395 self.assertRaises(TraitletError, setattr, a, 'klass', object)
395 a.klass = B
396 a.klass = B
396
397
397 def test_allow_none(self):
398 def test_allow_none(self):
398
399
399 class B(object): pass
400 class B(object): pass
400 class C(B): pass
401 class C(B): pass
401 class A(HasTraitlets):
402 class A(HasTraitlets):
402 klass = Type(B, allow_none=False)
403 klass = Type(B, allow_none=False)
403
404
404 a = A()
405 a = A()
405 self.assertEquals(a.klass, B)
406 self.assertEquals(a.klass, B)
406 self.assertRaises(TraitletError, setattr, a, 'klass', None)
407 self.assertRaises(TraitletError, setattr, a, 'klass', None)
407 a.klass = C
408 a.klass = C
408 self.assertEquals(a.klass, C)
409 self.assertEquals(a.klass, C)
409
410
410 def test_validate_klass(self):
411 def test_validate_klass(self):
411
412
412 def inner():
413 class A(HasTraitlets):
413 class A(HasTraitlets):
414 klass = Type('no strings allowed')
414 klass = Type('no strings allowed')
415
415
416 self.assertRaises(TraitletError, inner)
416 self.assertRaises(ImportError, A)
417
418 class A(HasTraitlets):
419 klass = Type('rub.adub.Duck')
420
421 self.assertRaises(ImportError, A)
417
422
418 def test_validate_default(self):
423 def test_validate_default(self):
419
424
420 class B(object): pass
425 class B(object): pass
421 class A(HasTraitlets):
426 class A(HasTraitlets):
422 klass = Type('bad default', B)
427 klass = Type('bad default', B)
423
428
424 self.assertRaises(TraitletError, A)
429 self.assertRaises(ImportError, A)
425
430
426 class C(HasTraitlets):
431 class C(HasTraitlets):
427 klass = Type(None, B, allow_none=False)
432 klass = Type(None, B, allow_none=False)
428
433
429 self.assertRaises(TraitletError, C)
434 self.assertRaises(TraitletError, C)
430
435
436 def test_str_klass(self):
437
438 class A(HasTraitlets):
439 klass = Type('IPython.utils.ipstruct.Struct')
440
441 from IPython.utils.ipstruct import Struct
442 a = A()
443 a.klass = Struct
444 self.assertEquals(a.klass, Struct)
445
446 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
447
431 class TestInstance(TestCase):
448 class TestInstance(TestCase):
432
449
433 def test_basic(self):
450 def test_basic(self):
434 class Foo(object): pass
451 class Foo(object): pass
435 class Bar(Foo): pass
452 class Bar(Foo): pass
436 class Bah(object): pass
453 class Bah(object): pass
437
454
438 class A(HasTraitlets):
455 class A(HasTraitlets):
439 inst = Instance(Foo)
456 inst = Instance(Foo)
440
457
441 a = A()
458 a = A()
442 self.assert_(a.inst is None)
459 self.assert_(a.inst is None)
443 a.inst = Foo()
460 a.inst = Foo()
444 self.assert_(isinstance(a.inst, Foo))
461 self.assert_(isinstance(a.inst, Foo))
445 a.inst = Bar()
462 a.inst = Bar()
446 self.assert_(isinstance(a.inst, Foo))
463 self.assert_(isinstance(a.inst, Foo))
447 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
464 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
448 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
465 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
449 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
466 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
450
467
451 def test_unique_default_value(self):
468 def test_unique_default_value(self):
452 class Foo(object): pass
469 class Foo(object): pass
453 class A(HasTraitlets):
470 class A(HasTraitlets):
454 inst = Instance(Foo,(),{})
471 inst = Instance(Foo,(),{})
455
472
456 a = A()
473 a = A()
457 b = A()
474 b = A()
458 self.assert_(a.inst is not b.inst)
475 self.assert_(a.inst is not b.inst)
459
476
460 def test_args_kw(self):
477 def test_args_kw(self):
461 class Foo(object):
478 class Foo(object):
462 def __init__(self, c): self.c = c
479 def __init__(self, c): self.c = c
463 class Bar(object): pass
480 class Bar(object): pass
464 class Bah(object):
481 class Bah(object):
465 def __init__(self, c, d):
482 def __init__(self, c, d):
466 self.c = c; self.d = d
483 self.c = c; self.d = d
467
484
468 class A(HasTraitlets):
485 class A(HasTraitlets):
469 inst = Instance(Foo, (10,))
486 inst = Instance(Foo, (10,))
470 a = A()
487 a = A()
471 self.assertEquals(a.inst.c, 10)
488 self.assertEquals(a.inst.c, 10)
472
489
473 class B(HasTraitlets):
490 class B(HasTraitlets):
474 inst = Instance(Bah, args=(10,), kw=dict(d=20))
491 inst = Instance(Bah, args=(10,), kw=dict(d=20))
475 b = B()
492 b = B()
476 self.assertEquals(b.inst.c, 10)
493 self.assertEquals(b.inst.c, 10)
477 self.assertEquals(b.inst.d, 20)
494 self.assertEquals(b.inst.d, 20)
478
495
479 class C(HasTraitlets):
496 class C(HasTraitlets):
480 inst = Instance(Foo)
497 inst = Instance(Foo)
481 c = C()
498 c = C()
482 self.assert_(c.inst is None)
499 self.assert_(c.inst is None)
483
500
484 def test_bad_default(self):
501 def test_bad_default(self):
485 class Foo(object): pass
502 class Foo(object): pass
486
503
487 class A(HasTraitlets):
504 class A(HasTraitlets):
488 inst = Instance(Foo, allow_none=False)
505 inst = Instance(Foo, allow_none=False)
489
506
490 self.assertRaises(TraitletError, A)
507 self.assertRaises(TraitletError, A)
491
508
492 def test_instance(self):
509 def test_instance(self):
493 class Foo(object): pass
510 class Foo(object): pass
494
511
495 def inner():
512 def inner():
496 class A(HasTraitlets):
513 class A(HasTraitlets):
497 inst = Instance(Foo())
514 inst = Instance(Foo())
498
515
499 self.assertRaises(TraitletError, inner)
516 self.assertRaises(TraitletError, inner)
500
517
501
518
502 class TestThis(TestCase):
519 class TestThis(TestCase):
503
520
504 def test_this_class(self):
521 def test_this_class(self):
505 class Foo(HasTraitlets):
522 class Foo(HasTraitlets):
506 this = This
523 this = This
507
524
508 f = Foo()
525 f = Foo()
509 self.assertEquals(f.this, None)
526 self.assertEquals(f.this, None)
510 g = Foo()
527 g = Foo()
511 f.this = g
528 f.this = g
512 self.assertEquals(f.this, g)
529 self.assertEquals(f.this, g)
513 self.assertRaises(TraitletError, setattr, f, 'this', 10)
530 self.assertRaises(TraitletError, setattr, f, 'this', 10)
514
531
515 def test_this_inst(self):
532 def test_this_inst(self):
516 class Foo(HasTraitlets):
533 class Foo(HasTraitlets):
517 this = This()
534 this = This()
518
535
519 f = Foo()
536 f = Foo()
520 f.this = Foo()
537 f.this = Foo()
521 self.assert_(isinstance(f.this, Foo))
538 self.assert_(isinstance(f.this, Foo))
522
539
523 def test_subclass(self):
540 def test_subclass(self):
524 class Foo(HasTraitlets):
541 class Foo(HasTraitlets):
525 t = This()
542 t = This()
526 class Bar(Foo):
543 class Bar(Foo):
527 pass
544 pass
528 f = Foo()
545 f = Foo()
529 b = Bar()
546 b = Bar()
530 f.t = b
547 f.t = b
531 b.t = f
548 b.t = f
532 self.assertEquals(f.t, b)
549 self.assertEquals(f.t, b)
533 self.assertEquals(b.t, f)
550 self.assertEquals(b.t, f)
534
551
535 def test_subclass_override(self):
552 def test_subclass_override(self):
536 class Foo(HasTraitlets):
553 class Foo(HasTraitlets):
537 t = This()
554 t = This()
538 class Bar(Foo):
555 class Bar(Foo):
539 t = This()
556 t = This()
540 f = Foo()
557 f = Foo()
541 b = Bar()
558 b = Bar()
542 f.t = b
559 f.t = b
543 self.assertEquals(f.t, b)
560 self.assertEquals(f.t, b)
544 self.assertRaises(TraitletError, setattr, b, 't', f)
561 self.assertRaises(TraitletError, setattr, b, 't', f)
545
562
546 class TraitletTestBase(TestCase):
563 class TraitletTestBase(TestCase):
547 """A best testing class for basic traitlet types."""
564 """A best testing class for basic traitlet types."""
548
565
549 def assign(self, value):
566 def assign(self, value):
550 self.obj.value = value
567 self.obj.value = value
551
568
552 def coerce(self, value):
569 def coerce(self, value):
553 return value
570 return value
554
571
555 def test_good_values(self):
572 def test_good_values(self):
556 if hasattr(self, '_good_values'):
573 if hasattr(self, '_good_values'):
557 for value in self._good_values:
574 for value in self._good_values:
558 self.assign(value)
575 self.assign(value)
559 self.assertEquals(self.obj.value, self.coerce(value))
576 self.assertEquals(self.obj.value, self.coerce(value))
560
577
561 def test_bad_values(self):
578 def test_bad_values(self):
562 if hasattr(self, '_bad_values'):
579 if hasattr(self, '_bad_values'):
563 for value in self._bad_values:
580 for value in self._bad_values:
564 self.assertRaises(TraitletError, self.assign, value)
581 self.assertRaises(TraitletError, self.assign, value)
565
582
566 def test_default_value(self):
583 def test_default_value(self):
567 if hasattr(self, '_default_value'):
584 if hasattr(self, '_default_value'):
568 self.assertEquals(self._default_value, self.obj.value)
585 self.assertEquals(self._default_value, self.obj.value)
569
586
570
587
571 class AnyTraitlet(HasTraitlets):
588 class AnyTraitlet(HasTraitlets):
572
589
573 value = Any
590 value = Any
574
591
575 class AnyTraitTest(TraitletTestBase):
592 class AnyTraitTest(TraitletTestBase):
576
593
577 obj = AnyTraitlet()
594 obj = AnyTraitlet()
578
595
579 _default_value = None
596 _default_value = None
580 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
597 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
581 _bad_values = []
598 _bad_values = []
582
599
583
600
584 class IntTraitlet(HasTraitlets):
601 class IntTraitlet(HasTraitlets):
585
602
586 value = Int(99)
603 value = Int(99)
587
604
588 class TestInt(TraitletTestBase):
605 class TestInt(TraitletTestBase):
589
606
590 obj = IntTraitlet()
607 obj = IntTraitlet()
591 _default_value = 99
608 _default_value = 99
592 _good_values = [10, -10]
609 _good_values = [10, -10]
593 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
610 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
594 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
611 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
595 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
612 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
596
613
597
614
598 class LongTraitlet(HasTraitlets):
615 class LongTraitlet(HasTraitlets):
599
616
600 value = Long(99L)
617 value = Long(99L)
601
618
602 class TestLong(TraitletTestBase):
619 class TestLong(TraitletTestBase):
603
620
604 obj = LongTraitlet()
621 obj = LongTraitlet()
605
622
606 _default_value = 99L
623 _default_value = 99L
607 _good_values = [10, -10, 10L, -10L]
624 _good_values = [10, -10, 10L, -10L]
608 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
625 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
609 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
626 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
610 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
627 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
611 u'-10.1']
628 u'-10.1']
612
629
613
630
614 class FloatTraitlet(HasTraitlets):
631 class FloatTraitlet(HasTraitlets):
615
632
616 value = Float(99.0)
633 value = Float(99.0)
617
634
618 class TestFloat(TraitletTestBase):
635 class TestFloat(TraitletTestBase):
619
636
620 obj = FloatTraitlet()
637 obj = FloatTraitlet()
621
638
622 _default_value = 99.0
639 _default_value = 99.0
623 _good_values = [10, -10, 10.1, -10.1]
640 _good_values = [10, -10, 10.1, -10.1]
624 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
641 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
625 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
642 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
626 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
643 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
627
644
628
645
629 class ComplexTraitlet(HasTraitlets):
646 class ComplexTraitlet(HasTraitlets):
630
647
631 value = Complex(99.0-99.0j)
648 value = Complex(99.0-99.0j)
632
649
633 class TestComplex(TraitletTestBase):
650 class TestComplex(TraitletTestBase):
634
651
635 obj = ComplexTraitlet()
652 obj = ComplexTraitlet()
636
653
637 _default_value = 99.0-99.0j
654 _default_value = 99.0-99.0j
638 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
655 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
639 10.1j, 10.1+10.1j, 10.1-10.1j]
656 10.1j, 10.1+10.1j, 10.1-10.1j]
640 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
657 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
641
658
642
659
643 class StringTraitlet(HasTraitlets):
660 class StringTraitlet(HasTraitlets):
644
661
645 value = Str('string')
662 value = Str('string')
646
663
647 class TestString(TraitletTestBase):
664 class TestString(TraitletTestBase):
648
665
649 obj = StringTraitlet()
666 obj = StringTraitlet()
650
667
651 _default_value = 'string'
668 _default_value = 'string'
652 _good_values = ['10', '-10', '10L',
669 _good_values = ['10', '-10', '10L',
653 '-10L', '10.1', '-10.1', 'string']
670 '-10L', '10.1', '-10.1', 'string']
654 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
671 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
655 ['ten'],{'ten': 10},(10,), None, u'string']
672 ['ten'],{'ten': 10},(10,), None, u'string']
656
673
657
674
658 class UnicodeTraitlet(HasTraitlets):
675 class UnicodeTraitlet(HasTraitlets):
659
676
660 value = Unicode(u'unicode')
677 value = Unicode(u'unicode')
661
678
662 class TestUnicode(TraitletTestBase):
679 class TestUnicode(TraitletTestBase):
663
680
664 obj = UnicodeTraitlet()
681 obj = UnicodeTraitlet()
665
682
666 _default_value = u'unicode'
683 _default_value = u'unicode'
667 _good_values = ['10', '-10', '10L', '-10L', '10.1',
684 _good_values = ['10', '-10', '10L', '-10L', '10.1',
668 '-10.1', '', u'', 'string', u'string', ]
685 '-10.1', '', u'', 'string', u'string', ]
669 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
686 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
670 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
687 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
@@ -1,925 +1,974 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight Traits like module.
4 A lightweight Traits like module.
5
5
6 This is designed to provide a lightweight, simple, pure Python version of
6 This is designed to provide a lightweight, simple, pure Python version of
7 many of the capabilities of enthought.traits. This includes:
7 many of the capabilities of enthought.traits. This includes:
8
8
9 * Validation
9 * Validation
10 * Type specification with defaults
10 * Type specification with defaults
11 * Static and dynamic notification
11 * Static and dynamic notification
12 * Basic predefined types
12 * Basic predefined types
13 * An API that is similar to enthought.traits
13 * An API that is similar to enthought.traits
14
14
15 We don't support:
15 We don't support:
16
16
17 * Delegation
17 * Delegation
18 * Automatic GUI generation
18 * Automatic GUI generation
19 * A full set of trait types. Most importantly, we don't provide container
19 * A full set of trait types. Most importantly, we don't provide container
20 traitlets (list, dict, tuple) that can trigger notifications if their
20 traitlets (list, dict, tuple) that can trigger notifications if their
21 contents change.
21 contents change.
22 * API compatibility with enthought.traits
22 * API compatibility with enthought.traits
23
23
24 There are also some important difference in our design:
24 There are also some important difference in our design:
25
25
26 * enthought.traits does not validate default values. We do.
26 * enthought.traits does not validate default values. We do.
27
27
28 We choose to create this module because we need these capabilities, but
28 We choose to create this module because we need these capabilities, but
29 we need them to be pure Python so they work in all Python implementations,
29 we need them to be pure Python so they work in all Python implementations,
30 including Jython and IronPython.
30 including Jython and IronPython.
31
31
32 Authors:
32 Authors:
33
33
34 * Brian Granger
34 * Brian Granger
35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
36 and is licensed under the BSD license. Also, many of the ideas also come
36 and is licensed under the BSD license. Also, many of the ideas also come
37 from enthought.traits even though our implementation is very different.
37 from enthought.traits even though our implementation is very different.
38 """
38 """
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Copyright (C) 2008-2009 The IPython Development Team
41 # Copyright (C) 2008-2009 The IPython Development Team
42 #
42 #
43 # Distributed under the terms of the BSD License. The full license is in
43 # Distributed under the terms of the BSD License. The full license is in
44 # the file COPYING, distributed as part of this software.
44 # the file COPYING, distributed as part of this software.
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48 # Imports
48 # Imports
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 import inspect
52 import inspect
53 import sys
53 import sys
54 import types
54 import types
55 from types import (
55 from types import (
56 InstanceType, ClassType, FunctionType,
56 InstanceType, ClassType, FunctionType,
57 ListType, TupleType
57 ListType, TupleType
58 )
58 )
59
59
60 from IPython.utils.importstring import import_item
61
60 ClassTypes = (ClassType, type)
62 ClassTypes = (ClassType, type)
61
63
62 SequenceTypes = (ListType, TupleType)
64 SequenceTypes = (ListType, TupleType)
63
65
64 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
65 # Basic classes
67 # Basic classes
66 #-----------------------------------------------------------------------------
68 #-----------------------------------------------------------------------------
67
69
68
70
69 class NoDefaultSpecified ( object ): pass
71 class NoDefaultSpecified ( object ): pass
70 NoDefaultSpecified = NoDefaultSpecified()
72 NoDefaultSpecified = NoDefaultSpecified()
71
73
72
74
73 class Undefined ( object ): pass
75 class Undefined ( object ): pass
74 Undefined = Undefined()
76 Undefined = Undefined()
75
77
76
78
77 class TraitletError(Exception):
79 class TraitletError(Exception):
78 pass
80 pass
79
81
80
82
81 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
82 # Utilities
84 # Utilities
83 #-----------------------------------------------------------------------------
85 #-----------------------------------------------------------------------------
84
86
85
87
86 def class_of ( object ):
88 def class_of ( object ):
87 """ Returns a string containing the class name of an object with the
89 """ Returns a string containing the class name of an object with the
88 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
90 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
89 'a PlotValue').
91 'a PlotValue').
90 """
92 """
91 if isinstance( object, basestring ):
93 if isinstance( object, basestring ):
92 return add_article( object )
94 return add_article( object )
93
95
94 return add_article( object.__class__.__name__ )
96 return add_article( object.__class__.__name__ )
95
97
96
98
97 def add_article ( name ):
99 def add_article ( name ):
98 """ Returns a string containing the correct indefinite article ('a' or 'an')
100 """ Returns a string containing the correct indefinite article ('a' or 'an')
99 prefixed to the specified string.
101 prefixed to the specified string.
100 """
102 """
101 if name[:1].lower() in 'aeiou':
103 if name[:1].lower() in 'aeiou':
102 return 'an ' + name
104 return 'an ' + name
103
105
104 return 'a ' + name
106 return 'a ' + name
105
107
106
108
107 def repr_type(obj):
109 def repr_type(obj):
108 """ Return a string representation of a value and its type for readable
110 """ Return a string representation of a value and its type for readable
109 error messages.
111 error messages.
110 """
112 """
111 the_type = type(obj)
113 the_type = type(obj)
112 if the_type is InstanceType:
114 if the_type is InstanceType:
113 # Old-style class.
115 # Old-style class.
114 the_type = obj.__class__
116 the_type = obj.__class__
115 msg = '%r %r' % (obj, the_type)
117 msg = '%r %r' % (obj, the_type)
116 return msg
118 return msg
117
119
118
120
119 def parse_notifier_name(name):
121 def parse_notifier_name(name):
120 """Convert the name argument to a list of names.
122 """Convert the name argument to a list of names.
121
123
122 Examples
124 Examples
123 --------
125 --------
124
126
125 >>> parse_notifier_name('a')
127 >>> parse_notifier_name('a')
126 ['a']
128 ['a']
127 >>> parse_notifier_name(['a','b'])
129 >>> parse_notifier_name(['a','b'])
128 ['a', 'b']
130 ['a', 'b']
129 >>> parse_notifier_name(None)
131 >>> parse_notifier_name(None)
130 ['anytraitlet']
132 ['anytraitlet']
131 """
133 """
132 if isinstance(name, str):
134 if isinstance(name, str):
133 return [name]
135 return [name]
134 elif name is None:
136 elif name is None:
135 return ['anytraitlet']
137 return ['anytraitlet']
136 elif isinstance(name, (list, tuple)):
138 elif isinstance(name, (list, tuple)):
137 for n in name:
139 for n in name:
138 assert isinstance(n, str), "names must be strings"
140 assert isinstance(n, str), "names must be strings"
139 return name
141 return name
140
142
141
143
142 class _SimpleTest:
144 class _SimpleTest:
143 def __init__ ( self, value ): self.value = value
145 def __init__ ( self, value ): self.value = value
144 def __call__ ( self, test ):
146 def __call__ ( self, test ):
145 print test, self.value
146 return test == self.value
147 return test == self.value
147 def __repr__(self):
148 def __repr__(self):
148 return "<SimpleTest(%r)" % self.value
149 return "<SimpleTest(%r)" % self.value
149 def __str__(self):
150 def __str__(self):
150 return self.__repr__()
151 return self.__repr__()
151
152
152
153
153 #-----------------------------------------------------------------------------
154 #-----------------------------------------------------------------------------
154 # Base TraitletType for all traitlets
155 # Base TraitletType for all traitlets
155 #-----------------------------------------------------------------------------
156 #-----------------------------------------------------------------------------
156
157
157
158
158 class TraitletType(object):
159 class TraitletType(object):
159 """A base class for all traitlet descriptors.
160 """A base class for all traitlet descriptors.
160
161
161 Notes
162 Notes
162 -----
163 -----
163 Our implementation of traitlets is based on Python's descriptor
164 Our implementation of traitlets is based on Python's descriptor
164 prototol. This class is the base class for all such descriptors. The
165 prototol. This class is the base class for all such descriptors. The
165 only magic we use is a custom metaclass for the main :class:`HasTraitlets`
166 only magic we use is a custom metaclass for the main :class:`HasTraitlets`
166 class that does the following:
167 class that does the following:
167
168
168 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
169 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
169 instance in the class dict to the name of the attribute.
170 instance in the class dict to the name of the attribute.
170 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
171 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
171 instance in the class dict to the *class* that declared the traitlet.
172 instance in the class dict to the *class* that declared the traitlet.
172 This is used by the :class:`This` traitlet to allow subclasses to
173 This is used by the :class:`This` traitlet to allow subclasses to
173 accept superclasses for :class:`This` values.
174 accept superclasses for :class:`This` values.
174 """
175 """
175
176
176
177
177 metadata = {}
178 metadata = {}
178 default_value = Undefined
179 default_value = Undefined
179 info_text = 'any value'
180 info_text = 'any value'
180
181
181 def __init__(self, default_value=NoDefaultSpecified, **metadata):
182 def __init__(self, default_value=NoDefaultSpecified, **metadata):
182 """Create a TraitletType.
183 """Create a TraitletType.
183 """
184 """
184 if default_value is not NoDefaultSpecified:
185 if default_value is not NoDefaultSpecified:
185 self.default_value = default_value
186 self.default_value = default_value
186
187
187 if len(metadata) > 0:
188 if len(metadata) > 0:
188 if len(self.metadata) > 0:
189 if len(self.metadata) > 0:
189 self._metadata = self.metadata.copy()
190 self._metadata = self.metadata.copy()
190 self._metadata.update(metadata)
191 self._metadata.update(metadata)
191 else:
192 else:
192 self._metadata = metadata
193 self._metadata = metadata
193 else:
194 else:
194 self._metadata = self.metadata
195 self._metadata = self.metadata
195
196
196 self.init()
197 self.init()
197
198
198 def init(self):
199 def init(self):
199 pass
200 pass
200
201
201 def get_default_value(self):
202 def get_default_value(self):
202 """Create a new instance of the default value."""
203 """Create a new instance of the default value."""
203 dv = self.default_value
204 dv = self.default_value
204 return dv
205 return dv
205
206
207 def instance_init(self, obj):
208 """This is called by :meth:`HasTraitlets.__new__` to finish init'ing.
209
210 Some stages of initialization must be delayed until the parent
211 :class:`HasTraitlets` instance has been created. This method is
212 called in :meth:`HasTraitlets.__new__` after the instance has been
213 created.
214
215 This method trigger the creation and validation of default values
216 and also things like the resolution of str given class names in
217 :class:`Type` and :class`Instance`.
218
219 Parameters
220 ----------
221 obj : :class:`HasTraitlets` instance
222 The parent :class:`HasTraitlets` instance that has just been
223 created.
224 """
225 self.set_default_value(obj)
226
206 def set_default_value(self, obj):
227 def set_default_value(self, obj):
228 """Set the default value on a per instance basis.
229
230 This method is called by :meth:`instance_init` to create and
231 validate the default value. The creation and validation of
232 default values must be delayed until the parent :class:`HasTraitlets`
233 class has been instantiated.
234 """
207 dv = self.get_default_value()
235 dv = self.get_default_value()
208 newdv = self._validate(obj, dv)
236 newdv = self._validate(obj, dv)
209 obj._traitlet_values[self.name] = newdv
237 obj._traitlet_values[self.name] = newdv
210
238
211
212 def __get__(self, obj, cls=None):
239 def __get__(self, obj, cls=None):
213 """Get the value of the traitlet by self.name for the instance.
240 """Get the value of the traitlet by self.name for the instance.
214
241
215 Default values are instantiated when :meth:`HasTraitlets.__new__`
242 Default values are instantiated when :meth:`HasTraitlets.__new__`
216 is called. Thus by the time this method gets called either the
243 is called. Thus by the time this method gets called either the
217 default value or a user defined value (they called :meth:`__set__`)
244 default value or a user defined value (they called :meth:`__set__`)
218 is in the :class:`HasTraitlets` instance.
245 is in the :class:`HasTraitlets` instance.
219 """
246 """
220 if obj is None:
247 if obj is None:
221 return self
248 return self
222 else:
249 else:
223 try:
250 try:
224 value = obj._traitlet_values[self.name]
251 value = obj._traitlet_values[self.name]
225 except:
252 except:
226 # HasTraitlets should call set_default_value to populate
253 # HasTraitlets should call set_default_value to populate
227 # this. So this should never be reached.
254 # this. So this should never be reached.
228 raise TraitletError('Unexpected error in TraitletType: '
255 raise TraitletError('Unexpected error in TraitletType: '
229 'default value not set properly')
256 'default value not set properly')
230 else:
257 else:
231 return value
258 return value
232
259
233 def __set__(self, obj, value):
260 def __set__(self, obj, value):
234 new_value = self._validate(obj, value)
261 new_value = self._validate(obj, value)
235 old_value = self.__get__(obj)
262 old_value = self.__get__(obj)
236 if old_value != new_value:
263 if old_value != new_value:
237 obj._traitlet_values[self.name] = new_value
264 obj._traitlet_values[self.name] = new_value
238 obj._notify_traitlet(self.name, old_value, new_value)
265 obj._notify_traitlet(self.name, old_value, new_value)
239
266
240 def _validate(self, obj, value):
267 def _validate(self, obj, value):
241 if hasattr(self, 'validate'):
268 if hasattr(self, 'validate'):
242 return self.validate(obj, value)
269 return self.validate(obj, value)
243 elif hasattr(self, 'is_valid_for'):
270 elif hasattr(self, 'is_valid_for'):
244 valid = self.is_valid_for(value)
271 valid = self.is_valid_for(value)
245 if valid:
272 if valid:
246 return value
273 return value
247 else:
274 else:
248 raise TraitletError('invalid value for type: %r' % value)
275 raise TraitletError('invalid value for type: %r' % value)
249 elif hasattr(self, 'value_for'):
276 elif hasattr(self, 'value_for'):
250 return self.value_for(value)
277 return self.value_for(value)
251 else:
278 else:
252 return value
279 return value
253
280
254 def info(self):
281 def info(self):
255 return self.info_text
282 return self.info_text
256
283
257 def error(self, obj, value):
284 def error(self, obj, value):
258 if obj is not None:
285 if obj is not None:
259 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
286 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
260 % (self.name, class_of(obj),
287 % (self.name, class_of(obj),
261 self.info(), repr_type(value))
288 self.info(), repr_type(value))
262 else:
289 else:
263 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
290 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
264 % (self.name, self.info(), repr_type(value))
291 % (self.name, self.info(), repr_type(value))
265 raise TraitletError(e)
292 raise TraitletError(e)
266
293
267 def get_metadata(self, key):
294 def get_metadata(self, key):
268 return getattr(self, '_metadata', {}).get(key, None)
295 return getattr(self, '_metadata', {}).get(key, None)
269
296
270 def set_metadata(self, key, value):
297 def set_metadata(self, key, value):
271 getattr(self, '_metadata', {})[key] = value
298 getattr(self, '_metadata', {})[key] = value
272
299
273
300
274 #-----------------------------------------------------------------------------
301 #-----------------------------------------------------------------------------
275 # The HasTraitlets implementation
302 # The HasTraitlets implementation
276 #-----------------------------------------------------------------------------
303 #-----------------------------------------------------------------------------
277
304
278
305
279 class MetaHasTraitlets(type):
306 class MetaHasTraitlets(type):
280 """A metaclass for HasTraitlets.
307 """A metaclass for HasTraitlets.
281
308
282 This metaclass makes sure that any TraitletType class attributes are
309 This metaclass makes sure that any TraitletType class attributes are
283 instantiated and sets their name attribute.
310 instantiated and sets their name attribute.
284 """
311 """
285
312
286 def __new__(mcls, name, bases, classdict):
313 def __new__(mcls, name, bases, classdict):
287 """Create the HasTraitlets class.
314 """Create the HasTraitlets class.
288
315
289 This instantiates all TraitletTypes in the class dict and sets their
316 This instantiates all TraitletTypes in the class dict and sets their
290 :attr:`name` attribute.
317 :attr:`name` attribute.
291 """
318 """
292 # print "========================="
293 # print "MetaHasTraitlets.__new__"
294 # print "mcls, ", mcls
295 # print "name, ", name
296 # print "bases, ", bases
297 # print "classdict, ", classdict
298 for k,v in classdict.iteritems():
319 for k,v in classdict.iteritems():
299 if isinstance(v, TraitletType):
320 if isinstance(v, TraitletType):
300 v.name = k
321 v.name = k
301 elif inspect.isclass(v):
322 elif inspect.isclass(v):
302 if issubclass(v, TraitletType):
323 if issubclass(v, TraitletType):
303 vinst = v()
324 vinst = v()
304 vinst.name = k
325 vinst.name = k
305 classdict[k] = vinst
326 classdict[k] = vinst
306 return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict)
327 return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict)
307
328
308 def __init__(cls, name, bases, classdict):
329 def __init__(cls, name, bases, classdict):
309 """Finish initializing the HasTraitlets class.
330 """Finish initializing the HasTraitlets class.
310
331
311 This sets the :attr:`this_class` attribute of each TraitletType in the
332 This sets the :attr:`this_class` attribute of each TraitletType in the
312 class dict to the newly created class ``cls``.
333 class dict to the newly created class ``cls``.
313 """
334 """
314 # print "========================="
315 # print "MetaHasTraitlets.__init__"
316 # print "cls, ", cls
317 # print "name, ", name
318 # print "bases, ", bases
319 # print "classdict, ", classdict
320 for k, v in classdict.iteritems():
335 for k, v in classdict.iteritems():
321 if isinstance(v, TraitletType):
336 if isinstance(v, TraitletType):
322 v.this_class = cls
337 v.this_class = cls
323 super(MetaHasTraitlets, cls).__init__(name, bases, classdict)
338 super(MetaHasTraitlets, cls).__init__(name, bases, classdict)
324
339
325 class HasTraitlets(object):
340 class HasTraitlets(object):
326
341
327 __metaclass__ = MetaHasTraitlets
342 __metaclass__ = MetaHasTraitlets
328
343
329 def __new__(cls, *args, **kw):
344 def __new__(cls, *args, **kw):
330 inst = super(HasTraitlets, cls).__new__(cls, *args, **kw)
345 inst = super(HasTraitlets, cls).__new__(cls, *args, **kw)
331 inst._traitlet_values = {}
346 inst._traitlet_values = {}
332 inst._traitlet_notifiers = {}
347 inst._traitlet_notifiers = {}
333 # Here we tell all the TraitletType instances to set their default
348 # Here we tell all the TraitletType instances to set their default
334 # values on the instance.
349 # values on the instance.
335 for key in dir(cls):
350 for key in dir(cls):
336 value = getattr(cls, key)
351 value = getattr(cls, key)
337 if isinstance(value, TraitletType):
352 if isinstance(value, TraitletType):
338 value.set_default_value(inst)
353 value.instance_init(inst)
339 return inst
354 return inst
340
355
341 # def __init__(self):
356 # def __init__(self):
342 # self._traitlet_values = {}
357 # self._traitlet_values = {}
343 # self._traitlet_notifiers = {}
358 # self._traitlet_notifiers = {}
344
359
345 def _notify_traitlet(self, name, old_value, new_value):
360 def _notify_traitlet(self, name, old_value, new_value):
346
361
347 # First dynamic ones
362 # First dynamic ones
348 callables = self._traitlet_notifiers.get(name,[])
363 callables = self._traitlet_notifiers.get(name,[])
349 more_callables = self._traitlet_notifiers.get('anytraitlet',[])
364 more_callables = self._traitlet_notifiers.get('anytraitlet',[])
350 callables.extend(more_callables)
365 callables.extend(more_callables)
351
366
352 # Now static ones
367 # Now static ones
353 try:
368 try:
354 cb = getattr(self, '_%s_changed' % name)
369 cb = getattr(self, '_%s_changed' % name)
355 except:
370 except:
356 pass
371 pass
357 else:
372 else:
358 callables.append(cb)
373 callables.append(cb)
359
374
360 # Call them all now
375 # Call them all now
361 for c in callables:
376 for c in callables:
362 # Traits catches and logs errors here. I allow them to raise
377 # Traits catches and logs errors here. I allow them to raise
363 if callable(c):
378 if callable(c):
364 argspec = inspect.getargspec(c)
379 argspec = inspect.getargspec(c)
365 nargs = len(argspec[0])
380 nargs = len(argspec[0])
366 # Bound methods have an additional 'self' argument
381 # Bound methods have an additional 'self' argument
367 # I don't know how to treat unbound methods, but they
382 # I don't know how to treat unbound methods, but they
368 # can't really be used for callbacks.
383 # can't really be used for callbacks.
369 if isinstance(c, types.MethodType):
384 if isinstance(c, types.MethodType):
370 offset = -1
385 offset = -1
371 else:
386 else:
372 offset = 0
387 offset = 0
373 if nargs + offset == 0:
388 if nargs + offset == 0:
374 c()
389 c()
375 elif nargs + offset == 1:
390 elif nargs + offset == 1:
376 c(name)
391 c(name)
377 elif nargs + offset == 2:
392 elif nargs + offset == 2:
378 c(name, new_value)
393 c(name, new_value)
379 elif nargs + offset == 3:
394 elif nargs + offset == 3:
380 c(name, old_value, new_value)
395 c(name, old_value, new_value)
381 else:
396 else:
382 raise TraitletError('a traitlet changed callback '
397 raise TraitletError('a traitlet changed callback '
383 'must have 0-3 arguments.')
398 'must have 0-3 arguments.')
384 else:
399 else:
385 raise TraitletError('a traitlet changed callback '
400 raise TraitletError('a traitlet changed callback '
386 'must be callable.')
401 'must be callable.')
387
402
388
403
389 def _add_notifiers(self, handler, name):
404 def _add_notifiers(self, handler, name):
390 if not self._traitlet_notifiers.has_key(name):
405 if not self._traitlet_notifiers.has_key(name):
391 nlist = []
406 nlist = []
392 self._traitlet_notifiers[name] = nlist
407 self._traitlet_notifiers[name] = nlist
393 else:
408 else:
394 nlist = self._traitlet_notifiers[name]
409 nlist = self._traitlet_notifiers[name]
395 if handler not in nlist:
410 if handler not in nlist:
396 nlist.append(handler)
411 nlist.append(handler)
397
412
398 def _remove_notifiers(self, handler, name):
413 def _remove_notifiers(self, handler, name):
399 if self._traitlet_notifiers.has_key(name):
414 if self._traitlet_notifiers.has_key(name):
400 nlist = self._traitlet_notifiers[name]
415 nlist = self._traitlet_notifiers[name]
401 try:
416 try:
402 index = nlist.index(handler)
417 index = nlist.index(handler)
403 except ValueError:
418 except ValueError:
404 pass
419 pass
405 else:
420 else:
406 del nlist[index]
421 del nlist[index]
407
422
408 def on_traitlet_change(self, handler, name=None, remove=False):
423 def on_traitlet_change(self, handler, name=None, remove=False):
409 """Setup a handler to be called when a traitlet changes.
424 """Setup a handler to be called when a traitlet changes.
410
425
411 This is used to setup dynamic notifications of traitlet changes.
426 This is used to setup dynamic notifications of traitlet changes.
412
427
413 Static handlers can be created by creating methods on a HasTraitlets
428 Static handlers can be created by creating methods on a HasTraitlets
414 subclass with the naming convention '_[traitletname]_changed'. Thus,
429 subclass with the naming convention '_[traitletname]_changed'. Thus,
415 to create static handler for the traitlet 'a', create the method
430 to create static handler for the traitlet 'a', create the method
416 _a_changed(self, name, old, new) (fewer arguments can be used, see
431 _a_changed(self, name, old, new) (fewer arguments can be used, see
417 below).
432 below).
418
433
419 Parameters
434 Parameters
420 ----------
435 ----------
421 handler : callable
436 handler : callable
422 A callable that is called when a traitlet changes. Its
437 A callable that is called when a traitlet changes. Its
423 signature can be handler(), handler(name), handler(name, new)
438 signature can be handler(), handler(name), handler(name, new)
424 or handler(name, old, new).
439 or handler(name, old, new).
425 name : list, str, None
440 name : list, str, None
426 If None, the handler will apply to all traitlets. If a list
441 If None, the handler will apply to all traitlets. If a list
427 of str, handler will apply to all names in the list. If a
442 of str, handler will apply to all names in the list. If a
428 str, the handler will apply just to that name.
443 str, the handler will apply just to that name.
429 remove : bool
444 remove : bool
430 If False (the default), then install the handler. If True
445 If False (the default), then install the handler. If True
431 then unintall it.
446 then unintall it.
432 """
447 """
433 if remove:
448 if remove:
434 names = parse_notifier_name(name)
449 names = parse_notifier_name(name)
435 for n in names:
450 for n in names:
436 self._remove_notifiers(handler, n)
451 self._remove_notifiers(handler, n)
437 else:
452 else:
438 names = parse_notifier_name(name)
453 names = parse_notifier_name(name)
439 for n in names:
454 for n in names:
440 self._add_notifiers(handler, n)
455 self._add_notifiers(handler, n)
441
456
442 def traitlet_names(self, **metadata):
457 def traitlet_names(self, **metadata):
443 """Get a list of all the names of this classes traitlets."""
458 """Get a list of all the names of this classes traitlets."""
444 return self.traitlets(**metadata).keys()
459 return self.traitlets(**metadata).keys()
445
460
446 def traitlets(self, *args, **metadata):
461 def traitlets(self, *args, **metadata):
447 """Get a list of all the traitlets of this class.
462 """Get a list of all the traitlets of this class.
448
463
449 The TraitletTypes returned don't know anything about the values
464 The TraitletTypes returned don't know anything about the values
450 that the various HasTraitlet's instances are holding.
465 that the various HasTraitlet's instances are holding.
451 """
466 """
452 traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \
467 traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \
453 isinstance(memb[1], TraitletType)])
468 isinstance(memb[1], TraitletType)])
454 if len(metadata) == 0 and len(args) == 0:
469 if len(metadata) == 0 and len(args) == 0:
455 return traitlets
470 return traitlets
456
471
457 for meta_name in args:
472 for meta_name in args:
458 metadata[meta_name] = lambda _: True
473 metadata[meta_name] = lambda _: True
459
474
460 for meta_name, meta_eval in metadata.items():
475 for meta_name, meta_eval in metadata.items():
461 if type(meta_eval) is not FunctionType:
476 if type(meta_eval) is not FunctionType:
462 metadata[meta_name] = _SimpleTest(meta_eval)
477 metadata[meta_name] = _SimpleTest(meta_eval)
463
478
464 result = {}
479 result = {}
465 for name, traitlet in traitlets.items():
480 for name, traitlet in traitlets.items():
466 for meta_name, meta_eval in metadata.items():
481 for meta_name, meta_eval in metadata.items():
467 if not meta_eval(traitlet.get_metadata(meta_name)):
482 if not meta_eval(traitlet.get_metadata(meta_name)):
468 break
483 break
469 else:
484 else:
470 result[name] = traitlet
485 result[name] = traitlet
471
486
472 return result
487 return result
473
488
474 def traitlet_metadata(self, traitletname, key):
489 def traitlet_metadata(self, traitletname, key):
475 """Get metadata values for traitlet by key."""
490 """Get metadata values for traitlet by key."""
476 try:
491 try:
477 traitlet = getattr(self.__class__, traitletname)
492 traitlet = getattr(self.__class__, traitletname)
478 except AttributeError:
493 except AttributeError:
479 raise TraitletError("Class %s does not have a traitlet named %s" %
494 raise TraitletError("Class %s does not have a traitlet named %s" %
480 (self.__class__.__name__, traitletname))
495 (self.__class__.__name__, traitletname))
481 else:
496 else:
482 return traitlet.get_metadata(key)
497 return traitlet.get_metadata(key)
483
498
484 #-----------------------------------------------------------------------------
499 #-----------------------------------------------------------------------------
485 # Actual TraitletTypes implementations/subclasses
500 # Actual TraitletTypes implementations/subclasses
486 #-----------------------------------------------------------------------------
501 #-----------------------------------------------------------------------------
487
502
488 #-----------------------------------------------------------------------------
503 #-----------------------------------------------------------------------------
489 # TraitletTypes subclasses for handling classes and instances of classes
504 # TraitletTypes subclasses for handling classes and instances of classes
490 #-----------------------------------------------------------------------------
505 #-----------------------------------------------------------------------------
491
506
492
507
493 class ClassBasedTraitletType(TraitletType):
508 class ClassBasedTraitletType(TraitletType):
494 """A traitlet with error reporting for Type, Instance and This."""
509 """A traitlet with error reporting for Type, Instance and This."""
495
510
496 def error(self, obj, value):
511 def error(self, obj, value):
497 kind = type(value)
512 kind = type(value)
498 if kind is InstanceType:
513 if kind is InstanceType:
499 msg = 'class %s' % value.__class__.__name__
514 msg = 'class %s' % value.__class__.__name__
500 else:
515 else:
501 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
516 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
502
517
503 super(ClassBasedTraitletType, self).error(obj, msg)
518 super(ClassBasedTraitletType, self).error(obj, msg)
504
519
505
520
506 class Type(ClassBasedTraitletType):
521 class Type(ClassBasedTraitletType):
507 """A traitlet whose value must be a subclass of a specified class."""
522 """A traitlet whose value must be a subclass of a specified class."""
508
523
509 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
524 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
510 """Construct a Type traitlet
525 """Construct a Type traitlet
511
526
512 A Type traitlet specifies that its values must be subclasses of
527 A Type traitlet specifies that its values must be subclasses of
513 a particular class.
528 a particular class.
514
529
530 If only ``default_value`` is given, it is used for the ``klass`` as
531 well.
532
515 Parameters
533 Parameters
516 ----------
534 ----------
517 default_value : class
535 default_value : class, str or None
518 The default value must be a subclass of klass.
536 The default value must be a subclass of klass. If an str,
537 the str must be a fully specified class name, like 'foo.bar.Bah'.
538 The string is resolved into real class, when the parent
539 :class:`HasTraitlets` class is instantiated.
519 klass : class, str, None
540 klass : class, str, None
520 Values of this traitlet must be a subclass of klass. The klass
541 Values of this traitlet must be a subclass of klass. The klass
521 may be specified in a string like: 'foo.bar.MyClass'.
542 may be specified in a string like: 'foo.bar.MyClass'.
543 The string is resolved into real class, when the parent
544 :class:`HasTraitlets` class is instantiated.
522 allow_none : boolean
545 allow_none : boolean
523 Indicates whether None is allowed as an assignable value. Even if
546 Indicates whether None is allowed as an assignable value. Even if
524 ``False``, the default value may be ``None``.
547 ``False``, the default value may be ``None``.
525 """
548 """
526 if default_value is None:
549 if default_value is None:
527 if klass is None:
550 if klass is None:
528 klass = object
551 klass = object
529 elif klass is None:
552 elif klass is None:
530 klass = default_value
553 klass = default_value
531
554
532 if not inspect.isclass(klass):
555 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
533 raise TraitletError("A Type traitlet must specify a class.")
556 raise TraitletError("A Type traitlet must specify a class.")
534
557
535 self.klass = klass
558 self.klass = klass
536 self._allow_none = allow_none
559 self._allow_none = allow_none
537
560
538 super(Type, self).__init__(default_value, **metadata)
561 super(Type, self).__init__(default_value, **metadata)
539
562
540 def validate(self, obj, value):
563 def validate(self, obj, value):
541 """Validates that the value is a valid object instance."""
564 """Validates that the value is a valid object instance."""
542 try:
565 try:
543 if issubclass(value, self.klass):
566 if issubclass(value, self.klass):
544 return value
567 return value
545 except:
568 except:
546 if (value is None) and (self._allow_none):
569 if (value is None) and (self._allow_none):
547 return value
570 return value
548
571
549 self.error(obj, value)
572 self.error(obj, value)
550
573
551 def info(self):
574 def info(self):
552 """ Returns a description of the trait."""
575 """ Returns a description of the trait."""
576 if isinstance(self.klass, basestring):
577 klass = self.klass
578 else:
553 klass = self.klass.__name__
579 klass = self.klass.__name__
554 result = 'a subclass of ' + klass
580 result = 'a subclass of ' + klass
555 if self._allow_none:
581 if self._allow_none:
556 return result + ' or None'
582 return result + ' or None'
557 return result
583 return result
558
584
585 def instance_init(self, obj):
586 self._resolve_classes()
587 super(Type, self).instance_init(obj)
588
589 def _resolve_classes(self):
590 if isinstance(self.klass, basestring):
591 self.klass = import_item(self.klass)
592 if isinstance(self.default_value, basestring):
593 self.default_value = import_item(self.default_value)
594
595 def get_default_value(self):
596 return self.default_value
597
559
598
560 class DefaultValueGenerator(object):
599 class DefaultValueGenerator(object):
561 """A class for generating new default value instances."""
600 """A class for generating new default value instances."""
562
601
563 def __init__(self, klass, *args, **kw):
602 def __init__(self, *args, **kw):
564 self.klass = klass
565 self.args = args
603 self.args = args
566 self.kw = kw
604 self.kw = kw
567
605
568 def generate(self):
606 def generate(self, klass):
569 return self.klass(*self.args, **self.kw)
607 return klass(*self.args, **self.kw)
570
608
571
609
572 class Instance(ClassBasedTraitletType):
610 class Instance(ClassBasedTraitletType):
573 """A trait whose value must be an instance of a specified class.
611 """A trait whose value must be an instance of a specified class.
574
612
575 The value can also be an instance of a subclass of the specified class.
613 The value can also be an instance of a subclass of the specified class.
576 """
614 """
577
615
578 def __init__(self, klass=None, args=None, kw=None,
616 def __init__(self, klass=None, args=None, kw=None,
579 allow_none=True, **metadata ):
617 allow_none=True, **metadata ):
580 """Construct an Instance traitlet.
618 """Construct an Instance traitlet.
581
619
582 This traitlet allows values that are instances of a particular
620 This traitlet allows values that are instances of a particular
583 class or its sublclasses. Our implementation is quite different
621 class or its sublclasses. Our implementation is quite different
584 from that of enthough.traits as we don't allow instances to be used
622 from that of enthough.traits as we don't allow instances to be used
585 for klass and we handle the ``args`` and ``kw`` arguments differently.
623 for klass and we handle the ``args`` and ``kw`` arguments differently.
586
624
587 Parameters
625 Parameters
588 ----------
626 ----------
589 klass : class
627 klass : class, str
590 The class that forms the basis for the traitlet. Instances
628 The class that forms the basis for the traitlet. Class names
591 and strings are not allowed.
629 can also be specified as strings, like 'foo.bar.Bar'.
592 args : tuple
630 args : tuple
593 Positional arguments for generating the default value.
631 Positional arguments for generating the default value.
594 kw : dict
632 kw : dict
595 Keyword arguments for generating the default value.
633 Keyword arguments for generating the default value.
596 allow_none : bool
634 allow_none : bool
597 Indicates whether None is allowed as a value.
635 Indicates whether None is allowed as a value.
598
636
599 Default Value
637 Default Value
600 -------------
638 -------------
601 If both ``args`` and ``kw`` are None, then the default value is None.
639 If both ``args`` and ``kw`` are None, then the default value is None.
602 If ``args`` is a tuple and ``kw`` is a dict, then the default is
640 If ``args`` is a tuple and ``kw`` is a dict, then the default is
603 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
641 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
604 not (but not both), None is replace by ``()`` or ``{}``.
642 not (but not both), None is replace by ``()`` or ``{}``.
605 """
643 """
606
644
607 self._allow_none = allow_none
645 self._allow_none = allow_none
608
646
609 if (klass is None) or (not inspect.isclass(klass)):
647 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, basestring))):
610 raise TraitletError('The klass argument must be a class'
648 raise TraitletError('The klass argument must be a class'
611 ' you gave: %r' % klass)
649 ' you gave: %r' % klass)
612 self.klass = klass
650 self.klass = klass
613
651
614 # self.klass is a class, so handle default_value
652 # self.klass is a class, so handle default_value
615 if args is None and kw is None:
653 if args is None and kw is None:
616 default_value = None
654 default_value = None
617 else:
655 else:
618 if args is None:
656 if args is None:
619 # kw is not None
657 # kw is not None
620 args = ()
658 args = ()
621 elif kw is None:
659 elif kw is None:
622 # args is not None
660 # args is not None
623 kw = {}
661 kw = {}
624
662
625 if not isinstance(kw, dict):
663 if not isinstance(kw, dict):
626 raise TraitletError("The 'kw' argument must be a dict or None.")
664 raise TraitletError("The 'kw' argument must be a dict or None.")
627 if not isinstance(args, tuple):
665 if not isinstance(args, tuple):
628 raise TraitletError("The 'args' argument must be a tuple or None.")
666 raise TraitletError("The 'args' argument must be a tuple or None.")
629
667
630 default_value = DefaultValueGenerator(self.klass, *args, **kw)
668 default_value = DefaultValueGenerator(*args, **kw)
631
669
632 super(Instance, self).__init__(default_value, **metadata)
670 super(Instance, self).__init__(default_value, **metadata)
633
671
634 def validate(self, obj, value):
672 def validate(self, obj, value):
635 if value is None:
673 if value is None:
636 if self._allow_none:
674 if self._allow_none:
637 return value
675 return value
638 self.error(obj, value)
676 self.error(obj, value)
639
677
640 if isinstance(value, self.klass):
678 if isinstance(value, self.klass):
641 return value
679 return value
642 else:
680 else:
643 self.error(obj, value)
681 self.error(obj, value)
644
682
645 def info(self):
683 def info(self):
684 if isinstance(self.klass, basestring):
685 klass = self.klass
686 else:
646 klass = self.klass.__name__
687 klass = self.klass.__name__
647 result = class_of(klass)
688 result = class_of(klass)
648 if self._allow_none:
689 if self._allow_none:
649 return result + ' or None'
690 return result + ' or None'
650
691
651 return result
692 return result
652
693
694 def instance_init(self, obj):
695 self._resolve_classes()
696 super(Instance, self).instance_init(obj)
697
698 def _resolve_classes(self):
699 if isinstance(self.klass, basestring):
700 self.klass = import_item(self.klass)
701
653 def get_default_value(self):
702 def get_default_value(self):
654 """Instantiate a default value instance.
703 """Instantiate a default value instance.
655
704
656 This is called when the containing HasTraitlets classes'
705 This is called when the containing HasTraitlets classes'
657 :meth:`__new__` method is called to ensure that a unique instance
706 :meth:`__new__` method is called to ensure that a unique instance
658 is created for each HasTraitlets instance.
707 is created for each HasTraitlets instance.
659 """
708 """
660 dv = self.default_value
709 dv = self.default_value
661 if isinstance(dv, DefaultValueGenerator):
710 if isinstance(dv, DefaultValueGenerator):
662 return dv.generate()
711 return dv.generate(self.klass)
663 else:
712 else:
664 return dv
713 return dv
665
714
666
715
667 class This(ClassBasedTraitletType):
716 class This(ClassBasedTraitletType):
668 """A traitlet for instances of the class containing this trait.
717 """A traitlet for instances of the class containing this trait.
669
718
670 Because how how and when class bodies are executed, the ``This``
719 Because how how and when class bodies are executed, the ``This``
671 traitlet can only have a default value of None. This, and because we
720 traitlet can only have a default value of None. This, and because we
672 always validate default values, ``allow_none`` is *always* true.
721 always validate default values, ``allow_none`` is *always* true.
673 """
722 """
674
723
675 info_text = 'an instance of the same type as the receiver or None'
724 info_text = 'an instance of the same type as the receiver or None'
676
725
677 def __init__(self, **metadata):
726 def __init__(self, **metadata):
678 super(This, self).__init__(None, **metadata)
727 super(This, self).__init__(None, **metadata)
679
728
680 def validate(self, obj, value):
729 def validate(self, obj, value):
681 # What if value is a superclass of obj.__class__? This is
730 # What if value is a superclass of obj.__class__? This is
682 # complicated if it was the superclass that defined the This
731 # complicated if it was the superclass that defined the This
683 # traitlet.
732 # traitlet.
684 if isinstance(value, self.this_class) or (value is None):
733 if isinstance(value, self.this_class) or (value is None):
685 return value
734 return value
686 else:
735 else:
687 self.error(obj, value)
736 self.error(obj, value)
688
737
689
738
690 #-----------------------------------------------------------------------------
739 #-----------------------------------------------------------------------------
691 # Basic TraitletTypes implementations/subclasses
740 # Basic TraitletTypes implementations/subclasses
692 #-----------------------------------------------------------------------------
741 #-----------------------------------------------------------------------------
693
742
694
743
695 class Any(TraitletType):
744 class Any(TraitletType):
696 default_value = None
745 default_value = None
697 info_text = 'any value'
746 info_text = 'any value'
698
747
699
748
700 class Int(TraitletType):
749 class Int(TraitletType):
701 """A integer traitlet."""
750 """A integer traitlet."""
702
751
703 evaluate = int
752 evaluate = int
704 default_value = 0
753 default_value = 0
705 info_text = 'an integer'
754 info_text = 'an integer'
706
755
707 def validate(self, obj, value):
756 def validate(self, obj, value):
708 if isinstance(value, int):
757 if isinstance(value, int):
709 return value
758 return value
710 self.error(obj, value)
759 self.error(obj, value)
711
760
712 class CInt(Int):
761 class CInt(Int):
713 """A casting version of the int traitlet."""
762 """A casting version of the int traitlet."""
714
763
715 def validate(self, obj, value):
764 def validate(self, obj, value):
716 try:
765 try:
717 return int(value)
766 return int(value)
718 except:
767 except:
719 self.error(obj, value)
768 self.error(obj, value)
720
769
721
770
722 class Long(TraitletType):
771 class Long(TraitletType):
723 """A long integer traitlet."""
772 """A long integer traitlet."""
724
773
725 evaluate = long
774 evaluate = long
726 default_value = 0L
775 default_value = 0L
727 info_text = 'a long'
776 info_text = 'a long'
728
777
729 def validate(self, obj, value):
778 def validate(self, obj, value):
730 if isinstance(value, long):
779 if isinstance(value, long):
731 return value
780 return value
732 if isinstance(value, int):
781 if isinstance(value, int):
733 return long(value)
782 return long(value)
734 self.error(obj, value)
783 self.error(obj, value)
735
784
736
785
737 class CLong(Long):
786 class CLong(Long):
738 """A casting version of the long integer traitlet."""
787 """A casting version of the long integer traitlet."""
739
788
740 def validate(self, obj, value):
789 def validate(self, obj, value):
741 try:
790 try:
742 return long(value)
791 return long(value)
743 except:
792 except:
744 self.error(obj, value)
793 self.error(obj, value)
745
794
746
795
747 class Float(TraitletType):
796 class Float(TraitletType):
748 """A float traitlet."""
797 """A float traitlet."""
749
798
750 evaluate = float
799 evaluate = float
751 default_value = 0.0
800 default_value = 0.0
752 info_text = 'a float'
801 info_text = 'a float'
753
802
754 def validate(self, obj, value):
803 def validate(self, obj, value):
755 if isinstance(value, float):
804 if isinstance(value, float):
756 return value
805 return value
757 if isinstance(value, int):
806 if isinstance(value, int):
758 return float(value)
807 return float(value)
759 self.error(obj, value)
808 self.error(obj, value)
760
809
761
810
762 class CFloat(Float):
811 class CFloat(Float):
763 """A casting version of the float traitlet."""
812 """A casting version of the float traitlet."""
764
813
765 def validate(self, obj, value):
814 def validate(self, obj, value):
766 try:
815 try:
767 return float(value)
816 return float(value)
768 except:
817 except:
769 self.error(obj, value)
818 self.error(obj, value)
770
819
771 class Complex(TraitletType):
820 class Complex(TraitletType):
772 """A traitlet for complex numbers."""
821 """A traitlet for complex numbers."""
773
822
774 evaluate = complex
823 evaluate = complex
775 default_value = 0.0 + 0.0j
824 default_value = 0.0 + 0.0j
776 info_text = 'a complex number'
825 info_text = 'a complex number'
777
826
778 def validate(self, obj, value):
827 def validate(self, obj, value):
779 if isinstance(value, complex):
828 if isinstance(value, complex):
780 return value
829 return value
781 if isinstance(value, (float, int)):
830 if isinstance(value, (float, int)):
782 return complex(value)
831 return complex(value)
783 self.error(obj, value)
832 self.error(obj, value)
784
833
785
834
786 class CComplex(Complex):
835 class CComplex(Complex):
787 """A casting version of the complex number traitlet."""
836 """A casting version of the complex number traitlet."""
788
837
789 def validate (self, obj, value):
838 def validate (self, obj, value):
790 try:
839 try:
791 return complex(value)
840 return complex(value)
792 except:
841 except:
793 self.error(obj, value)
842 self.error(obj, value)
794
843
795
844
796 class Str(TraitletType):
845 class Str(TraitletType):
797 """A traitlet for strings."""
846 """A traitlet for strings."""
798
847
799 evaluate = lambda x: x
848 evaluate = lambda x: x
800 default_value = ''
849 default_value = ''
801 info_text = 'a string'
850 info_text = 'a string'
802
851
803 def validate(self, obj, value):
852 def validate(self, obj, value):
804 if isinstance(value, str):
853 if isinstance(value, str):
805 return value
854 return value
806 self.error(obj, value)
855 self.error(obj, value)
807
856
808
857
809 class CStr(Str):
858 class CStr(Str):
810 """A casting version of the string traitlet."""
859 """A casting version of the string traitlet."""
811
860
812 def validate(self, obj, value):
861 def validate(self, obj, value):
813 try:
862 try:
814 return str(value)
863 return str(value)
815 except:
864 except:
816 try:
865 try:
817 return unicode(value)
866 return unicode(value)
818 except:
867 except:
819 self.error(obj, value)
868 self.error(obj, value)
820
869
821
870
822 class Unicode(TraitletType):
871 class Unicode(TraitletType):
823 """A traitlet for unicode strings."""
872 """A traitlet for unicode strings."""
824
873
825 evaluate = unicode
874 evaluate = unicode
826 default_value = u''
875 default_value = u''
827 info_text = 'a unicode string'
876 info_text = 'a unicode string'
828
877
829 def validate(self, obj, value):
878 def validate(self, obj, value):
830 if isinstance(value, unicode):
879 if isinstance(value, unicode):
831 return value
880 return value
832 if isinstance(value, str):
881 if isinstance(value, str):
833 return unicode(value)
882 return unicode(value)
834 self.error(obj, value)
883 self.error(obj, value)
835
884
836
885
837 class CUnicode(Unicode):
886 class CUnicode(Unicode):
838 """A casting version of the unicode traitlet."""
887 """A casting version of the unicode traitlet."""
839
888
840 def validate(self, obj, value):
889 def validate(self, obj, value):
841 try:
890 try:
842 return unicode(value)
891 return unicode(value)
843 except:
892 except:
844 self.error(obj, value)
893 self.error(obj, value)
845
894
846
895
847 class Bool(TraitletType):
896 class Bool(TraitletType):
848 """A boolean (True, False) traitlet."""
897 """A boolean (True, False) traitlet."""
849 evaluate = bool
898 evaluate = bool
850 default_value = False
899 default_value = False
851 info_text = 'a boolean'
900 info_text = 'a boolean'
852
901
853 def validate(self, obj, value):
902 def validate(self, obj, value):
854 if isinstance(value, bool):
903 if isinstance(value, bool):
855 return value
904 return value
856 self.error(obj, value)
905 self.error(obj, value)
857
906
858
907
859 class CBool(Bool):
908 class CBool(Bool):
860 """A casting version of the boolean traitlet."""
909 """A casting version of the boolean traitlet."""
861
910
862 def validate(self, obj, value):
911 def validate(self, obj, value):
863 try:
912 try:
864 return bool(value)
913 return bool(value)
865 except:
914 except:
866 self.error(obj, value)
915 self.error(obj, value)
867
916
868
917
869 class Enum(TraitletType):
918 class Enum(TraitletType):
870 """An enum that whose value must be in a given sequence."""
919 """An enum that whose value must be in a given sequence."""
871
920
872 def __init__(self, values, default_value=None, allow_none=True, **metadata):
921 def __init__(self, values, default_value=None, allow_none=True, **metadata):
873 self.values = values
922 self.values = values
874 self._allow_none = allow_none
923 self._allow_none = allow_none
875 super(Enum, self).__init__(default_value, **metadata)
924 super(Enum, self).__init__(default_value, **metadata)
876
925
877 def validate(self, obj, value):
926 def validate(self, obj, value):
878 if value is None:
927 if value is None:
879 if self._allow_none:
928 if self._allow_none:
880 return value
929 return value
881
930
882 if value in self.values:
931 if value in self.values:
883 return value
932 return value
884 self.error(obj, value)
933 self.error(obj, value)
885
934
886 def info(self):
935 def info(self):
887 """ Returns a description of the trait."""
936 """ Returns a description of the trait."""
888 result = 'any of ' + repr(self.values)
937 result = 'any of ' + repr(self.values)
889 if self._allow_none:
938 if self._allow_none:
890 return result + ' or None'
939 return result + ' or None'
891 return result
940 return result
892
941
893 class CaselessStrEnum(Enum):
942 class CaselessStrEnum(Enum):
894 """An enum of strings that are caseless in validate."""
943 """An enum of strings that are caseless in validate."""
895
944
896 def validate(self, obj, value):
945 def validate(self, obj, value):
897 if value is None:
946 if value is None:
898 if self._allow_none:
947 if self._allow_none:
899 return value
948 return value
900
949
901 if not isinstance(value, str):
950 if not isinstance(value, str):
902 self.error(obj, value)
951 self.error(obj, value)
903
952
904 for v in self.values:
953 for v in self.values:
905 if v.lower() == value.lower():
954 if v.lower() == value.lower():
906 return v
955 return v
907 self.error(obj, value)
956 self.error(obj, value)
908
957
909
958
910 class List(Instance):
959 class List(Instance):
911 """An instance of a Python list."""
960 """An instance of a Python list."""
912
961
913 def __init__(self, default_value=None, allow_none=True, **metadata):
962 def __init__(self, default_value=None, allow_none=True, **metadata):
914 """Create a list traitlet type from a list or tuple.
963 """Create a list traitlet type from a list or tuple.
915
964
916 The default value is created by doing ``list(default_value)``,
965 The default value is created by doing ``list(default_value)``,
917 which creates a copy of the ``default_value``.
966 which creates a copy of the ``default_value``.
918 """
967 """
919 if default_value is None:
968 if default_value is None:
920 args = ((),)
969 args = ((),)
921 elif isinstance(default_value, SequenceTypes):
970 elif isinstance(default_value, SequenceTypes):
922 args = (default_value,)
971 args = (default_value,)
923
972
924 super(List,self).__init__(klass=list, args=args,
973 super(List,self).__init__(klass=list, args=args,
925 allow_none=allow_none, **metadata)
974 allow_none=allow_none, **metadata)
General Comments 0
You need to be logged in to leave comments. Login now