##// 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 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 A context manager for managing things injected into :mod:`__builtin__`.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2008-2009 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 import __builtin__
23 23
24 24 from IPython.core.component import Component
25 25 from IPython.core.quitter import Quitter
26 26
27 from IPython.utils.traitlets import Instance
28
27 29 #-----------------------------------------------------------------------------
28 30 # Classes and functions
29 31 #-----------------------------------------------------------------------------
30 32
31 33
32 34 class BuiltinUndefined(object): pass
33 35 BuiltinUndefined = BuiltinUndefined()
34 36
35 37
36 38 class BuiltinTrap(Component):
39 shell = Instance('IPython.core.iplib.InteractiveShell')
37 40
38 41 def __init__(self, parent, name=None, config=None):
39 42 super(BuiltinTrap, self).__init__(parent, name, config)
40 43 # Don't just grab parent!!!
41 from IPython.core.iplib import InteractiveShell
42 self.shell = InteractiveShell.get_instances(root=self.root)[0]
44 self.shell = Component.get_instances(root=self.root,
45 klass='IPython.core.iplib.InteractiveShell')[0]
43 46 self._orig_builtins = {}
44 47
45 48 def __enter__(self):
46 49 self.set()
47 50 # I return self, so callers can use add_builtin in a with clause.
48 51 return self
49 52
50 53 def __exit__(self, type, value, traceback):
51 54 self.unset()
52 55 return True
53 56
54 57 def add_builtin(self, key, value):
55 58 """Add a builtin and save the original."""
56 59 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
57 60 self._orig_builtins[key] = orig
58 61 __builtin__.__dict__[key] = value
59 62
60 63 def remove_builtin(self, key):
61 64 """Remove an added builtin and re-set the original."""
62 65 try:
63 66 orig = self._orig_builtins.pop(key)
64 67 except KeyError:
65 68 pass
66 69 else:
67 70 if orig is BuiltinUndefined:
68 71 del __builtin__.__dict__[key]
69 72 else:
70 73 __builtin__.__dict__[key] = orig
71 74
72 75 def set(self):
73 76 """Store ipython references in the __builtin__ namespace."""
74 77 self.add_builtin('exit', Quitter(self.shell, 'exit'))
75 78 self.add_builtin('quit', Quitter(self.shell, 'quit'))
76 79
77 80 # Recursive reload function
78 81 try:
79 82 from IPython.lib import deepreload
80 83 if self.shell.deep_reload:
81 84 self.add_builtin('reload', deepreload.reload)
82 85 else:
83 86 self.add_builtin('dreload', deepreload.reload)
84 87 del deepreload
85 88 except ImportError:
86 89 pass
87 90
88 91 # Keep in the builtins a flag for when IPython is active. We set it
89 92 # with setdefault so that multiple nested IPythons don't clobber one
90 93 # another. Each will increase its value by one upon being activated,
91 94 # which also gives us a way to determine the nesting level.
92 95 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
93 96
94 97 def unset(self):
95 98 """Remove any builtins which might have been added by add_builtins, or
96 99 restore overwritten ones to their previous values."""
97 100 for key in self._orig_builtins.keys():
98 101 self.remove_builtin(key)
99 102 self._orig_builtins.clear()
100 103 self._builtins_added = False
101 104 try:
102 105 del __builtin__.__dict__['__IPYTHON__active']
103 106 except KeyError:
104 107 pass No newline at end of file
@@ -1,242 +1,248 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 A lightweight component system for IPython.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from copy import deepcopy
24 24 import datetime
25 25 from weakref import WeakValueDictionary
26 26
27 from IPython.utils.importstring import import_item
27 28 from IPython.utils.ipstruct import Struct
28 29 from IPython.utils.traitlets import (
29 30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
30 31 )
31 32
32 33
33 34 #-----------------------------------------------------------------------------
34 35 # Helper classes for Components
35 36 #-----------------------------------------------------------------------------
36 37
37 38
38 39 class ComponentError(Exception):
39 40 pass
40 41
41 42 class MetaComponentTracker(type):
42 43 """A metaclass that tracks instances of Components and its subclasses."""
43 44
44 45 def __init__(cls, name, bases, d):
45 46 super(MetaComponentTracker, cls).__init__(name, bases, d)
46 47 cls.__instance_refs = WeakValueDictionary()
47 48 cls.__numcreated = 0
48 49
49 50 def __call__(cls, *args, **kw):
50 51 """Called when *class* is called (instantiated)!!!
51 52
52 53 When a Component or subclass is instantiated, this is called and
53 54 the instance is saved in a WeakValueDictionary for tracking.
54 55 """
55 56 instance = cls.__new__(cls, *args, **kw)
56 57 # Do this before __init__ is called so get_instances works inside
57 58 # __init__ methods!
58 59 for c in cls.__mro__:
59 60 if issubclass(cls, c) and issubclass(c, Component):
60 61 c.__numcreated += 1
61 62 c.__instance_refs[c.__numcreated] = instance
62 63 if isinstance(instance, cls):
63 64 cls.__init__(instance, *args, **kw)
64 65
65 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 69 """Get all instances of cls and its subclasses.
69 70
70 71 Parameters
71 72 ----------
72 73 name : str
73 74 Limit to components with this name.
74 75 root : Component or subclass
75 76 Limit to components having this root.
76 classname : str
77 The string name of a class to match exactly.
77 klass : class or str
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 85 instances = cls.__instance_refs.values()
80 86 if name is not None:
81 87 instances = [i for i in instances if i.name == name]
82 if classname is not None:
83 instances = [i for i in instances if i.__class__.__name__ == classname]
88 if klass is not None:
89 instances = [i for i in instances if isinstance(i, klass)]
84 90 if root is not None:
85 91 instances = [i for i in instances if i.root == root]
86 92 return instances
87 93
88 94 def get_instances_by_condition(cls, call, name=None, root=None,
89 classname=None):
95 klass=None):
90 96 """Get all instances of cls, i such that call(i)==True.
91 97
92 98 This also takes the ``name`` and ``root`` and ``classname``
93 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 104 class ComponentNameGenerator(object):
99 105 """A Singleton to generate unique component names."""
100 106
101 107 def __init__(self, prefix):
102 108 self.prefix = prefix
103 109 self.i = 0
104 110
105 111 def __call__(self):
106 112 count = self.i
107 113 self.i += 1
108 114 return "%s%s" % (self.prefix, count)
109 115
110 116
111 117 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
112 118
113 119
114 120 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
115 121 pass
116 122
117 123
118 124 #-----------------------------------------------------------------------------
119 125 # Component implementation
120 126 #-----------------------------------------------------------------------------
121 127
122 128
123 129 class Component(HasTraitlets):
124 130
125 131 __metaclass__ = MetaComponent
126 132
127 133 # Traitlets are fun!
128 134 config = Instance(Struct,(),{})
129 135 parent = This()
130 136 root = This()
131 137 created = None
132 138
133 139 def __init__(self, parent, name=None, config=None):
134 140 """Create a component given a parent and possibly and name and config.
135 141
136 142 Parameters
137 143 ----------
138 144 parent : Component subclass
139 145 The parent in the component graph. The parent is used
140 146 to get the root of the component graph.
141 147 name : str
142 148 The unique name of the component. If empty, then a unique
143 149 one will be autogenerated.
144 150 config : Struct
145 151 If this is empty, self.config = parent.config, otherwise
146 152 self.config = config and root.config is ignored. This argument
147 153 should only be used to *override* the automatic inheritance of
148 154 parent.config. If a caller wants to modify parent.config
149 155 (not override), the caller should make a copy and change
150 156 attributes and then pass the copy to this argument.
151 157
152 158 Notes
153 159 -----
154 160 Subclasses of Component must call the :meth:`__init__` method of
155 161 :class:`Component` *before* doing anything else and using
156 162 :func:`super`::
157 163
158 164 class MyComponent(Component):
159 165 def __init__(self, parent, name=None, config=None):
160 166 super(MyComponent, self).__init__(parent, name, config)
161 167 # Then any other code you need to finish initialization.
162 168
163 169 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
164 170 attributes are handled properly.
165 171 """
166 172 super(Component, self).__init__()
167 173 self._children = []
168 174 if name is None:
169 175 self.name = ComponentNameGenerator()
170 176 else:
171 177 self.name = name
172 178 self.root = self # This is the default, it is set when parent is set
173 179 self.parent = parent
174 180 if config is not None:
175 181 self.config = deepcopy(config)
176 182 else:
177 183 if self.parent is not None:
178 184 self.config = deepcopy(self.parent.config)
179 185
180 186 self.created = datetime.datetime.now()
181 187
182 188 #-------------------------------------------------------------------------
183 189 # Static traitlet notifiations
184 190 #-------------------------------------------------------------------------
185 191
186 192 def _parent_changed(self, name, old, new):
187 193 if old is not None:
188 194 old._remove_child(self)
189 195 if new is not None:
190 196 new._add_child(self)
191 197
192 198 if new is None:
193 199 self.root = self
194 200 else:
195 201 self.root = new.root
196 202
197 203 def _root_changed(self, name, old, new):
198 204 if self.parent is None:
199 205 if not (new is self):
200 206 raise ComponentError("Root not self, but parent is None.")
201 207 else:
202 208 if not self.parent.root is new:
203 209 raise ComponentError("Error in setting the root attribute: "
204 210 "root != parent.root")
205 211
206 212 def _config_changed(self, name, old, new):
207 213 """Update all the class traits having a config_key with the config.
208 214
209 215 For any class traitlet with a ``config_key`` metadata attribute, we
210 216 update the traitlet with the value of the corresponding config entry.
211 217
212 218 In the future, we might want to do a pop here so stale config info
213 219 is not passed onto children.
214 220 """
215 221 # Get all traitlets with a config_key metadata entry
216 222 traitlets = self.traitlets('config_key')
217 223 for k, v in traitlets.items():
218 224 try:
219 225 config_value = new[v.get_metadata('config_key')]
220 226 except KeyError:
221 227 pass
222 228 else:
223 229 setattr(self, k, config_value)
224 230
225 231 @property
226 232 def children(self):
227 233 """A list of all my child components."""
228 234 return self._children
229 235
230 236 def _remove_child(self, child):
231 237 """A private method for removing children components."""
232 238 if child in self._children:
233 239 index = self._children.index(child)
234 240 del self._children[index]
235 241
236 242 def _add_child(self, child):
237 243 """A private method for adding children components."""
238 244 if child not in self._children:
239 245 self._children.append(child)
240 246
241 247 def __repr__(self):
242 248 return "<Component('%s')>" % self.name
@@ -1,2962 +1,2961 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Main IPython Component
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 9 # Copyright (C) 2008-2009 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from __future__ import with_statement
20 20
21 21 import __main__
22 22 import __builtin__
23 23 import StringIO
24 24 import bdb
25 25 import codeop
26 26 import exceptions
27 27 import glob
28 28 import keyword
29 29 import new
30 30 import os
31 31 import re
32 32 import shutil
33 33 import string
34 34 import sys
35 35 import tempfile
36 36
37 37 from IPython.core import ultratb
38 38 from IPython.core import debugger, oinspect
39 39 from IPython.core import shadowns
40 40 from IPython.core import history as ipcorehist
41 41 from IPython.core import prefilter
42 42 from IPython.core.autocall import IPyAutocall
43 43 from IPython.core.builtin_trap import BuiltinTrap
44 44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 45 from IPython.core.logger import Logger
46 46 from IPython.core.magic import Magic
47 47 from IPython.core.prompts import CachedOutput
48 48 from IPython.core.page import page
49 49 from IPython.core.component import Component
50 50 from IPython.core.oldusersetup import user_setup
51 51 from IPython.core.usage import interactive_usage, default_banner
52 52 from IPython.core.error import TryNext, UsageError
53 53
54 54 from IPython.extensions import pickleshare
55 55 from IPython.external.Itpl import ItplNS
56 56 from IPython.lib.backgroundjobs import BackgroundJobManager
57 57 from IPython.utils.ipstruct import Struct
58 58 from IPython.utils import PyColorize
59 59 from IPython.utils.genutils import *
60 60 from IPython.utils.strdispatch import StrDispatch
61 61 from IPython.utils.platutils import toggle_set_term_title, set_term_title
62 62
63 63 from IPython.utils.traitlets import (
64 64 Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode
65 65 )
66 66
67 67 #-----------------------------------------------------------------------------
68 68 # Globals
69 69 #-----------------------------------------------------------------------------
70 70
71 71
72 72 # store the builtin raw_input globally, and use this always, in case user code
73 73 # overwrites it (like wx.py.PyShell does)
74 74 raw_input_original = raw_input
75 75
76 76 # compiled regexps for autoindent management
77 77 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
78 78
79 79
80 80 #-----------------------------------------------------------------------------
81 81 # Utilities
82 82 #-----------------------------------------------------------------------------
83 83
84 84
85 85 ini_spaces_re = re.compile(r'^(\s+)')
86 86
87 87
88 88 def num_ini_spaces(strng):
89 89 """Return the number of initial spaces in a string"""
90 90
91 91 ini_spaces = ini_spaces_re.match(strng)
92 92 if ini_spaces:
93 93 return ini_spaces.end()
94 94 else:
95 95 return 0
96 96
97 97
98 98 def softspace(file, newvalue):
99 99 """Copied from code.py, to remove the dependency"""
100 100
101 101 oldvalue = 0
102 102 try:
103 103 oldvalue = file.softspace
104 104 except AttributeError:
105 105 pass
106 106 try:
107 107 file.softspace = newvalue
108 108 except (AttributeError, TypeError):
109 109 # "attribute-less object" or "read-only attributes"
110 110 pass
111 111 return oldvalue
112 112
113 113
114 114 class SpaceInInput(exceptions.Exception): pass
115 115
116 116 class Bunch: pass
117 117
118 118 class InputList(list):
119 119 """Class to store user input.
120 120
121 121 It's basically a list, but slices return a string instead of a list, thus
122 122 allowing things like (assuming 'In' is an instance):
123 123
124 124 exec In[4:7]
125 125
126 126 or
127 127
128 128 exec In[5:9] + In[14] + In[21:25]"""
129 129
130 130 def __getslice__(self,i,j):
131 131 return ''.join(list.__getslice__(self,i,j))
132 132
133 133
134 134 class SyntaxTB(ultratb.ListTB):
135 135 """Extension which holds some state: the last exception value"""
136 136
137 137 def __init__(self,color_scheme = 'NoColor'):
138 138 ultratb.ListTB.__init__(self,color_scheme)
139 139 self.last_syntax_error = None
140 140
141 141 def __call__(self, etype, value, elist):
142 142 self.last_syntax_error = value
143 143 ultratb.ListTB.__call__(self,etype,value,elist)
144 144
145 145 def clear_err_state(self):
146 146 """Return the current error state and clear it"""
147 147 e = self.last_syntax_error
148 148 self.last_syntax_error = None
149 149 return e
150 150
151 151
152 152 def get_default_editor():
153 153 try:
154 154 ed = os.environ['EDITOR']
155 155 except KeyError:
156 156 if os.name == 'posix':
157 157 ed = 'vi' # the only one guaranteed to be there!
158 158 else:
159 159 ed = 'notepad' # same in Windows!
160 160 return ed
161 161
162 162
163 163 class SeparateStr(Str):
164 164 """A Str subclass to validate separate_in, separate_out, etc.
165 165
166 166 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
167 167 """
168 168
169 169 def validate(self, obj, value):
170 170 if value == '0': value = ''
171 171 value = value.replace('\\n','\n')
172 172 return super(SeparateStr, self).validate(obj, value)
173 173
174 174
175 175 #-----------------------------------------------------------------------------
176 176 # Main IPython class
177 177 #-----------------------------------------------------------------------------
178 178
179 179
180 180 class InteractiveShell(Component, Magic):
181 181 """An enhanced, interactive shell for Python."""
182 182
183 183 autocall = Enum((0,1,2), config_key='AUTOCALL')
184 184 autoedit_syntax = CBool(False, config_key='AUTOEDIT_SYNTAX')
185 185 autoindent = CBool(True, config_key='AUTOINDENT')
186 186 automagic = CBool(True, config_key='AUTOMAGIC')
187 187 display_banner = CBool(True, config_key='DISPLAY_BANNER')
188 188 banner = Str('')
189 189 banner1 = Str(default_banner, config_key='BANNER1')
190 190 banner2 = Str('', config_key='BANNER2')
191 191 c = Str('', config_key='C')
192 192 cache_size = Int(1000, config_key='CACHE_SIZE')
193 193 classic = CBool(False, config_key='CLASSIC')
194 194 color_info = CBool(True, config_key='COLOR_INFO')
195 195 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
196 196 default_value='LightBG', config_key='COLORS')
197 197 confirm_exit = CBool(True, config_key='CONFIRM_EXIT')
198 198 debug = CBool(False, config_key='DEBUG')
199 199 deep_reload = CBool(False, config_key='DEEP_RELOAD')
200 200 embedded = CBool(False)
201 201 embedded_active = CBool(False)
202 202 editor = Str(get_default_editor(), config_key='EDITOR')
203 203 filename = Str("<ipython console>")
204 204 interactive = CBool(False, config_key='INTERACTIVE')
205 205 ipythondir= Unicode('', config_key='IPYTHONDIR') # Set to os.getcwd() in __init__
206 206 logstart = CBool(False, config_key='LOGSTART')
207 207 logfile = Str('', config_key='LOGFILE')
208 208 logplay = Str('', config_key='LOGPLAY')
209 209 multi_line_specials = CBool(True, config_key='MULTI_LINE_SPECIALS')
210 210 object_info_string_level = Enum((0,1,2), default_value=0,
211 211 config_keys='OBJECT_INFO_STRING_LEVEL')
212 212 pager = Str('less', config_key='PAGER')
213 213 pdb = CBool(False, config_key='PDB')
214 214 pprint = CBool(True, config_key='PPRINT')
215 215 profile = Str('', config_key='PROFILE')
216 216 prompt_in1 = Str('In [\\#]: ', config_key='PROMPT_IN1')
217 217 prompt_in2 = Str(' .\\D.: ', config_key='PROMPT_IN2')
218 218 prompt_out = Str('Out[\\#]: ', config_key='PROMPT_OUT1')
219 219 prompts_pad_left = CBool(True, config_key='PROMPTS_PAD_LEFT')
220 220 quiet = CBool(False, config_key='QUIET')
221 221
222 222 readline_use = CBool(True, config_key='READLINE_USE')
223 223 readline_merge_completions = CBool(True,
224 224 config_key='READLINE_MERGE_COMPLETIONS')
225 225 readline_omit__names = Enum((0,1,2), default_value=0,
226 226 config_key='READLINE_OMIT_NAMES')
227 227 readline_remove_delims = Str('-/~', config_key='READLINE_REMOVE_DELIMS')
228 228 readline_parse_and_bind = List([
229 229 'tab: complete',
230 230 '"\C-l": possible-completions',
231 231 'set show-all-if-ambiguous on',
232 232 '"\C-o": tab-insert',
233 233 '"\M-i": " "',
234 234 '"\M-o": "\d\d\d\d"',
235 235 '"\M-I": "\d\d\d\d"',
236 236 '"\C-r": reverse-search-history',
237 237 '"\C-s": forward-search-history',
238 238 '"\C-p": history-search-backward',
239 239 '"\C-n": history-search-forward',
240 240 '"\e[A": history-search-backward',
241 241 '"\e[B": history-search-forward',
242 242 '"\C-k": kill-line',
243 243 '"\C-u": unix-line-discard',
244 244 ], allow_none=False, config_key='READLINE_PARSE_AND_BIND'
245 245 )
246 246
247 247 screen_length = Int(0, config_key='SCREEN_LENGTH')
248 248
249 249 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
250 250 separate_in = SeparateStr('\n', config_key='SEPARATE_IN')
251 251 separate_out = SeparateStr('', config_key='SEPARATE_OUT')
252 252 separate_out2 = SeparateStr('', config_key='SEPARATE_OUT2')
253 253
254 254 system_header = Str('IPython system call: ', config_key='SYSTEM_HEADER')
255 255 system_verbose = CBool(False, config_key='SYSTEM_VERBOSE')
256 256 term_title = CBool(False, config_key='TERM_TITLE')
257 257 wildcards_case_sensitive = CBool(True, config_key='WILDCARDS_CASE_SENSITIVE')
258 258 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
259 259 default_value='Context', config_key='XMODE')
260 260
261 261 alias = List(allow_none=False, config_key='ALIAS')
262 262 autoexec = List(allow_none=False)
263 263
264 264 # class attribute to indicate whether the class supports threads or not.
265 265 # Subclasses with thread support should override this as needed.
266 266 isthreaded = False
267 267
268 268 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
269 269 user_ns=None, user_global_ns=None,
270 270 banner1=None, banner2=None,
271 271 custom_exceptions=((),None)):
272 272
273 273 # This is where traitlets with a config_key argument are updated
274 274 # from the values on config.
275 275 super(InteractiveShell, self).__init__(parent, config=config, name='__IP')
276 276
277 277 # These are relatively independent and stateless
278 278 self.init_ipythondir(ipythondir)
279 279 self.init_instance_attrs()
280 280 self.init_term_title()
281 281 self.init_usage(usage)
282 282 self.init_banner(banner1, banner2)
283 283
284 284 # Create namespaces (user_ns, user_global_ns, alias_table, etc.)
285 285 self.init_create_namespaces(user_ns, user_global_ns)
286 286 # This has to be done after init_create_namespaces because it uses
287 287 # something in self.user_ns, but before init_sys_modules, which
288 288 # is the first thing to modify sys.
289 289 self.save_sys_module_state()
290 290 self.init_sys_modules()
291 291
292 292 self.init_history()
293 293 self.init_encoding()
294 294 self.init_handlers()
295 295
296 296 Magic.__init__(self, self)
297 297
298 298 self.init_syntax_highlighting()
299 299 self.init_hooks()
300 300 self.init_pushd_popd_magic()
301 301 self.init_traceback_handlers(custom_exceptions)
302 302 self.init_user_ns()
303 303 self.init_logger()
304 304 self.init_aliases()
305 305 self.init_builtins()
306 306
307 307 # pre_config_initialization
308 308 self.init_shadow_hist()
309 309
310 310 # The next section should contain averything that was in ipmaker.
311 311 self.init_logstart()
312 312
313 313 # The following was in post_config_initialization
314 314 self.init_inspector()
315 315 self.init_readline()
316 316 self.init_prompts()
317 317 self.init_displayhook()
318 318 self.init_reload_doctest()
319 319 self.init_magics()
320 320 self.init_pdb()
321 321 self.hooks.late_startup_hook()
322 322
323 323 def cleanup(self):
324 324 self.restore_sys_module_state()
325 325
326 326 #-------------------------------------------------------------------------
327 327 # Traitlet changed handlers
328 328 #-------------------------------------------------------------------------
329 329
330 330 def _banner1_changed(self):
331 331 self.compute_banner()
332 332
333 333 def _banner2_changed(self):
334 334 self.compute_banner()
335 335
336 336 @property
337 337 def usable_screen_length(self):
338 338 if self.screen_length == 0:
339 339 return 0
340 340 else:
341 341 num_lines_bot = self.separate_in.count('\n')+1
342 342 return self.screen_length - num_lines_bot
343 343
344 344 def _term_title_changed(self, name, new_value):
345 345 self.init_term_title()
346 346
347 347 #-------------------------------------------------------------------------
348 348 # init_* methods called by __init__
349 349 #-------------------------------------------------------------------------
350 350
351 351 def init_ipythondir(self, ipythondir):
352 352 if ipythondir is not None:
353 353 self.ipythondir = ipythondir
354 354 self.config.IPYTHONDIR = self.ipythondir
355 355 return
356 356
357 357 if hasattr(self.config, 'IPYTHONDIR'):
358 358 self.ipythondir = self.config.IPYTHONDIR
359 359 if not hasattr(self.config, 'IPYTHONDIR'):
360 360 # cdw is always defined
361 361 self.ipythondir = os.getcwd()
362 362
363 363 # The caller must make sure that ipythondir exists. We should
364 364 # probably handle this using a Dir traitlet.
365 365 if not os.path.isdir(self.ipythondir):
366 366 raise IOError('IPython dir does not exist: %s' % self.ipythondir)
367 367
368 368 # All children can just read this
369 369 self.config.IPYTHONDIR = self.ipythondir
370 370
371 371 def init_instance_attrs(self):
372 372 self.jobs = BackgroundJobManager()
373 373 self.more = False
374 374
375 375 # command compiler
376 376 self.compile = codeop.CommandCompiler()
377 377
378 378 # User input buffer
379 379 self.buffer = []
380 380
381 381 # Make an empty namespace, which extension writers can rely on both
382 382 # existing and NEVER being used by ipython itself. This gives them a
383 383 # convenient location for storing additional information and state
384 384 # their extensions may require, without fear of collisions with other
385 385 # ipython names that may develop later.
386 386 self.meta = Struct()
387 387
388 388 # Object variable to store code object waiting execution. This is
389 389 # used mainly by the multithreaded shells, but it can come in handy in
390 390 # other situations. No need to use a Queue here, since it's a single
391 391 # item which gets cleared once run.
392 392 self.code_to_run = None
393 393
394 394 # Flag to mark unconditional exit
395 395 self.exit_now = False
396 396
397 397 # Temporary files used for various purposes. Deleted at exit.
398 398 self.tempfiles = []
399 399
400 400 # Keep track of readline usage (later set by init_readline)
401 401 self.has_readline = False
402 402
403 403 # keep track of where we started running (mainly for crash post-mortem)
404 404 # This is not being used anywhere currently.
405 405 self.starting_dir = os.getcwd()
406 406
407 407 # Indentation management
408 408 self.indent_current_nsp = 0
409 409
410 410 def init_term_title(self):
411 411 # Enable or disable the terminal title.
412 412 if self.term_title:
413 413 toggle_set_term_title(True)
414 414 set_term_title('IPython: ' + abbrev_cwd())
415 415 else:
416 416 toggle_set_term_title(False)
417 417
418 418 def init_usage(self, usage=None):
419 419 if usage is None:
420 420 self.usage = interactive_usage
421 421 else:
422 422 self.usage = usage
423 423
424 424 def init_banner(self, banner1, banner2):
425 425 if self.c: # regular python doesn't print the banner with -c
426 426 self.display_banner = False
427 427 if banner1 is not None:
428 428 self.banner1 = banner1
429 429 if banner2 is not None:
430 430 self.banner2 = banner2
431 431 self.compute_banner()
432 432
433 433 def compute_banner(self):
434 434 self.banner = self.banner1 + '\n'
435 435 if self.profile:
436 436 self.banner += '\nIPython profile: %s\n' % self.profile
437 437 if self.banner2:
438 438 self.banner += '\n' + self.banner2 + '\n'
439 439
440 440 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
441 441 # Create the namespace where the user will operate. user_ns is
442 442 # normally the only one used, and it is passed to the exec calls as
443 443 # the locals argument. But we do carry a user_global_ns namespace
444 444 # given as the exec 'globals' argument, This is useful in embedding
445 445 # situations where the ipython shell opens in a context where the
446 446 # distinction between locals and globals is meaningful. For
447 447 # non-embedded contexts, it is just the same object as the user_ns dict.
448 448
449 449 # FIXME. For some strange reason, __builtins__ is showing up at user
450 450 # level as a dict instead of a module. This is a manual fix, but I
451 451 # should really track down where the problem is coming from. Alex
452 452 # Schmolck reported this problem first.
453 453
454 454 # A useful post by Alex Martelli on this topic:
455 455 # Re: inconsistent value from __builtins__
456 456 # Von: Alex Martelli <aleaxit@yahoo.com>
457 457 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
458 458 # Gruppen: comp.lang.python
459 459
460 460 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
461 461 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
462 462 # > <type 'dict'>
463 463 # > >>> print type(__builtins__)
464 464 # > <type 'module'>
465 465 # > Is this difference in return value intentional?
466 466
467 467 # Well, it's documented that '__builtins__' can be either a dictionary
468 468 # or a module, and it's been that way for a long time. Whether it's
469 469 # intentional (or sensible), I don't know. In any case, the idea is
470 470 # that if you need to access the built-in namespace directly, you
471 471 # should start with "import __builtin__" (note, no 's') which will
472 472 # definitely give you a module. Yeah, it's somewhat confusing:-(.
473 473
474 474 # These routines return properly built dicts as needed by the rest of
475 475 # the code, and can also be used by extension writers to generate
476 476 # properly initialized namespaces.
477 477 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
478 478 user_global_ns)
479 479
480 480 # Assign namespaces
481 481 # This is the namespace where all normal user variables live
482 482 self.user_ns = user_ns
483 483 self.user_global_ns = user_global_ns
484 484
485 485 # An auxiliary namespace that checks what parts of the user_ns were
486 486 # loaded at startup, so we can list later only variables defined in
487 487 # actual interactive use. Since it is always a subset of user_ns, it
488 488 # doesn't need to be seaparately tracked in the ns_table
489 489 self.user_config_ns = {}
490 490
491 491 # A namespace to keep track of internal data structures to prevent
492 492 # them from cluttering user-visible stuff. Will be updated later
493 493 self.internal_ns = {}
494 494
495 495 # Namespace of system aliases. Each entry in the alias
496 496 # table must be a 2-tuple of the form (N,name), where N is the number
497 497 # of positional arguments of the alias.
498 498 self.alias_table = {}
499 499
500 500 # Now that FakeModule produces a real module, we've run into a nasty
501 501 # problem: after script execution (via %run), the module where the user
502 502 # code ran is deleted. Now that this object is a true module (needed
503 503 # so docetst and other tools work correctly), the Python module
504 504 # teardown mechanism runs over it, and sets to None every variable
505 505 # present in that module. Top-level references to objects from the
506 506 # script survive, because the user_ns is updated with them. However,
507 507 # calling functions defined in the script that use other things from
508 508 # the script will fail, because the function's closure had references
509 509 # to the original objects, which are now all None. So we must protect
510 510 # these modules from deletion by keeping a cache.
511 511 #
512 512 # To avoid keeping stale modules around (we only need the one from the
513 513 # last run), we use a dict keyed with the full path to the script, so
514 514 # only the last version of the module is held in the cache. Note,
515 515 # however, that we must cache the module *namespace contents* (their
516 516 # __dict__). Because if we try to cache the actual modules, old ones
517 517 # (uncached) could be destroyed while still holding references (such as
518 518 # those held by GUI objects that tend to be long-lived)>
519 519 #
520 520 # The %reset command will flush this cache. See the cache_main_mod()
521 521 # and clear_main_mod_cache() methods for details on use.
522 522
523 523 # This is the cache used for 'main' namespaces
524 524 self._main_ns_cache = {}
525 525 # And this is the single instance of FakeModule whose __dict__ we keep
526 526 # copying and clearing for reuse on each %run
527 527 self._user_main_module = FakeModule()
528 528
529 529 # A table holding all the namespaces IPython deals with, so that
530 530 # introspection facilities can search easily.
531 531 self.ns_table = {'user':user_ns,
532 532 'user_global':user_global_ns,
533 533 'alias':self.alias_table,
534 534 'internal':self.internal_ns,
535 535 'builtin':__builtin__.__dict__
536 536 }
537 537
538 538 # Similarly, track all namespaces where references can be held and that
539 539 # we can safely clear (so it can NOT include builtin). This one can be
540 540 # a simple list.
541 541 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
542 542 self.alias_table, self.internal_ns,
543 543 self._main_ns_cache ]
544 544
545 545 def init_sys_modules(self):
546 546 # We need to insert into sys.modules something that looks like a
547 547 # module but which accesses the IPython namespace, for shelve and
548 548 # pickle to work interactively. Normally they rely on getting
549 549 # everything out of __main__, but for embedding purposes each IPython
550 550 # instance has its own private namespace, so we can't go shoving
551 551 # everything into __main__.
552 552
553 553 # note, however, that we should only do this for non-embedded
554 554 # ipythons, which really mimic the __main__.__dict__ with their own
555 555 # namespace. Embedded instances, on the other hand, should not do
556 556 # this because they need to manage the user local/global namespaces
557 557 # only, but they live within a 'normal' __main__ (meaning, they
558 558 # shouldn't overtake the execution environment of the script they're
559 559 # embedded in).
560 560
561 561 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
562 562
563 563 try:
564 564 main_name = self.user_ns['__name__']
565 565 except KeyError:
566 566 raise KeyError('user_ns dictionary MUST have a "__name__" key')
567 567 else:
568 568 sys.modules[main_name] = FakeModule(self.user_ns)
569 569
570 570 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
571 571 """Return a valid local and global user interactive namespaces.
572 572
573 573 This builds a dict with the minimal information needed to operate as a
574 574 valid IPython user namespace, which you can pass to the various
575 575 embedding classes in ipython. The default implementation returns the
576 576 same dict for both the locals and the globals to allow functions to
577 577 refer to variables in the namespace. Customized implementations can
578 578 return different dicts. The locals dictionary can actually be anything
579 579 following the basic mapping protocol of a dict, but the globals dict
580 580 must be a true dict, not even a subclass. It is recommended that any
581 581 custom object for the locals namespace synchronize with the globals
582 582 dict somehow.
583 583
584 584 Raises TypeError if the provided globals namespace is not a true dict.
585 585
586 586 :Parameters:
587 587 user_ns : dict-like, optional
588 588 The current user namespace. The items in this namespace should
589 589 be included in the output. If None, an appropriate blank
590 590 namespace should be created.
591 591 user_global_ns : dict, optional
592 592 The current user global namespace. The items in this namespace
593 593 should be included in the output. If None, an appropriate
594 594 blank namespace should be created.
595 595
596 596 :Returns:
597 597 A tuple pair of dictionary-like object to be used as the local namespace
598 598 of the interpreter and a dict to be used as the global namespace.
599 599 """
600 600
601 601 if user_ns is None:
602 602 # Set __name__ to __main__ to better match the behavior of the
603 603 # normal interpreter.
604 604 user_ns = {'__name__' :'__main__',
605 605 '__builtins__' : __builtin__,
606 606 }
607 607 else:
608 608 user_ns.setdefault('__name__','__main__')
609 609 user_ns.setdefault('__builtins__',__builtin__)
610 610
611 611 if user_global_ns is None:
612 612 user_global_ns = user_ns
613 613 if type(user_global_ns) is not dict:
614 614 raise TypeError("user_global_ns must be a true dict; got %r"
615 615 % type(user_global_ns))
616 616
617 617 return user_ns, user_global_ns
618 618
619 619 def init_history(self):
620 620 # List of input with multi-line handling.
621 621 self.input_hist = InputList()
622 622 # This one will hold the 'raw' input history, without any
623 623 # pre-processing. This will allow users to retrieve the input just as
624 624 # it was exactly typed in by the user, with %hist -r.
625 625 self.input_hist_raw = InputList()
626 626
627 627 # list of visited directories
628 628 try:
629 629 self.dir_hist = [os.getcwd()]
630 630 except OSError:
631 631 self.dir_hist = []
632 632
633 633 # dict of output history
634 634 self.output_hist = {}
635 635
636 636 # Now the history file
637 637 try:
638 638 histfname = 'history-%s' % self.profile
639 639 except AttributeError:
640 640 histfname = 'history'
641 641 self.histfile = os.path.join(self.config.IPYTHONDIR, histfname)
642 642
643 643 # Fill the history zero entry, user counter starts at 1
644 644 self.input_hist.append('\n')
645 645 self.input_hist_raw.append('\n')
646 646
647 647 def init_encoding(self):
648 648 # Get system encoding at startup time. Certain terminals (like Emacs
649 649 # under Win32 have it set to None, and we need to have a known valid
650 650 # encoding to use in the raw_input() method
651 651 try:
652 652 self.stdin_encoding = sys.stdin.encoding or 'ascii'
653 653 except AttributeError:
654 654 self.stdin_encoding = 'ascii'
655 655
656 656 def init_handlers(self):
657 657 # escapes for automatic behavior on the command line
658 658 self.ESC_SHELL = '!'
659 659 self.ESC_SH_CAP = '!!'
660 660 self.ESC_HELP = '?'
661 661 self.ESC_MAGIC = '%'
662 662 self.ESC_QUOTE = ','
663 663 self.ESC_QUOTE2 = ';'
664 664 self.ESC_PAREN = '/'
665 665
666 666 # And their associated handlers
667 667 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
668 668 self.ESC_QUOTE : self.handle_auto,
669 669 self.ESC_QUOTE2 : self.handle_auto,
670 670 self.ESC_MAGIC : self.handle_magic,
671 671 self.ESC_HELP : self.handle_help,
672 672 self.ESC_SHELL : self.handle_shell_escape,
673 673 self.ESC_SH_CAP : self.handle_shell_escape,
674 674 }
675 675
676 676 def init_syntax_highlighting(self):
677 677 # Python source parser/formatter for syntax highlighting
678 678 pyformat = PyColorize.Parser().format
679 679 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
680 680
681 681 def init_hooks(self):
682 682 # hooks holds pointers used for user-side customizations
683 683 self.hooks = Struct()
684 684
685 685 self.strdispatchers = {}
686 686
687 687 # Set all default hooks, defined in the IPython.hooks module.
688 688 import IPython.core.hooks
689 689 hooks = IPython.core.hooks
690 690 for hook_name in hooks.__all__:
691 691 # default hooks have priority 100, i.e. low; user hooks should have
692 692 # 0-100 priority
693 693 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
694 694
695 695 def init_pushd_popd_magic(self):
696 696 # for pushd/popd management
697 697 try:
698 698 self.home_dir = get_home_dir()
699 699 except HomeDirError, msg:
700 700 fatal(msg)
701 701
702 702 self.dir_stack = []
703 703
704 704 def init_traceback_handlers(self, custom_exceptions):
705 705 # Syntax error handler.
706 706 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
707 707
708 708 # The interactive one is initialized with an offset, meaning we always
709 709 # want to remove the topmost item in the traceback, which is our own
710 710 # internal code. Valid modes: ['Plain','Context','Verbose']
711 711 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
712 712 color_scheme='NoColor',
713 713 tb_offset = 1)
714 714
715 715 # IPython itself shouldn't crash. This will produce a detailed
716 716 # post-mortem if it does. But we only install the crash handler for
717 717 # non-threaded shells, the threaded ones use a normal verbose reporter
718 718 # and lose the crash handler. This is because exceptions in the main
719 719 # thread (such as in GUI code) propagate directly to sys.excepthook,
720 720 # and there's no point in printing crash dumps for every user exception.
721 721 if self.isthreaded:
722 722 ipCrashHandler = ultratb.FormattedTB()
723 723 else:
724 724 from IPython.core import crashhandler
725 725 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
726 726 self.set_crash_handler(ipCrashHandler)
727 727
728 728 # and add any custom exception handlers the user may have specified
729 729 self.set_custom_exc(*custom_exceptions)
730 730
731 731 def init_logger(self):
732 732 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
733 733 # local shortcut, this is used a LOT
734 734 self.log = self.logger.log
735 735 # template for logfile headers. It gets resolved at runtime by the
736 736 # logstart method.
737 737 self.loghead_tpl = \
738 738 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
739 739 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
740 740 #log# opts = %s
741 741 #log# args = %s
742 742 #log# It is safe to make manual edits below here.
743 743 #log#-----------------------------------------------------------------------
744 744 """
745 745
746 746 def init_logstart(self):
747 747 if self.logplay:
748 748 self.magic_logstart(self.logplay + ' append')
749 749 elif self.logfile:
750 750 self.magic_logstart(self.logfile)
751 751 elif self.logstart:
752 752 self.magic_logstart()
753 753
754 754 def init_aliases(self):
755 755 # dict of things NOT to alias (keywords, builtins and some magics)
756 756 no_alias = {}
757 757 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
758 758 for key in keyword.kwlist + no_alias_magics:
759 759 no_alias[key] = 1
760 760 no_alias.update(__builtin__.__dict__)
761 761 self.no_alias = no_alias
762 762
763 763 # Make some aliases automatically
764 764 # Prepare list of shell aliases to auto-define
765 765 if os.name == 'posix':
766 766 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
767 767 'mv mv -i','rm rm -i','cp cp -i',
768 768 'cat cat','less less','clear clear',
769 769 # a better ls
770 770 'ls ls -F',
771 771 # long ls
772 772 'll ls -lF')
773 773 # Extra ls aliases with color, which need special treatment on BSD
774 774 # variants
775 775 ls_extra = ( # color ls
776 776 'lc ls -F -o --color',
777 777 # ls normal files only
778 778 'lf ls -F -o --color %l | grep ^-',
779 779 # ls symbolic links
780 780 'lk ls -F -o --color %l | grep ^l',
781 781 # directories or links to directories,
782 782 'ldir ls -F -o --color %l | grep /$',
783 783 # things which are executable
784 784 'lx ls -F -o --color %l | grep ^-..x',
785 785 )
786 786 # The BSDs don't ship GNU ls, so they don't understand the
787 787 # --color switch out of the box
788 788 if 'bsd' in sys.platform:
789 789 ls_extra = ( # ls normal files only
790 790 'lf ls -lF | grep ^-',
791 791 # ls symbolic links
792 792 'lk ls -lF | grep ^l',
793 793 # directories or links to directories,
794 794 'ldir ls -lF | grep /$',
795 795 # things which are executable
796 796 'lx ls -lF | grep ^-..x',
797 797 )
798 798 auto_alias = auto_alias + ls_extra
799 799 elif os.name in ['nt','dos']:
800 800 auto_alias = ('ls dir /on',
801 801 'ddir dir /ad /on', 'ldir dir /ad /on',
802 802 'mkdir mkdir','rmdir rmdir','echo echo',
803 803 'ren ren','cls cls','copy copy')
804 804 else:
805 805 auto_alias = ()
806 806 self.auto_alias = [s.split(None,1) for s in auto_alias]
807 807
808 808 # Load default aliases
809 809 for alias, cmd in self.auto_alias:
810 810 self.define_alias(alias,cmd)
811 811
812 812 # Load user aliases
813 813 for alias in self.alias:
814 814 self.magic_alias(alias)
815 815
816 816 def init_builtins(self):
817 817 self.builtin_trap = BuiltinTrap(self)
818 818
819 819 def init_shadow_hist(self):
820 820 try:
821 821 self.db = pickleshare.PickleShareDB(self.config.IPYTHONDIR + "/db")
822 822 except exceptions.UnicodeDecodeError:
823 823 print "Your ipythondir can't be decoded to unicode!"
824 824 print "Please set HOME environment variable to something that"
825 825 print r"only has ASCII characters, e.g. c:\home"
826 826 print "Now it is", self.config.IPYTHONDIR
827 827 sys.exit()
828 828 self.shadowhist = ipcorehist.ShadowHist(self.db)
829 829
830 830 def init_inspector(self):
831 831 # Object inspector
832 832 self.inspector = oinspect.Inspector(oinspect.InspectColors,
833 833 PyColorize.ANSICodeColors,
834 834 'NoColor',
835 835 self.object_info_string_level)
836 836
837 837 def init_readline(self):
838 838 """Command history completion/saving/reloading."""
839 839
840 840 self.rl_next_input = None
841 841 self.rl_do_indent = False
842 842
843 843 if not self.readline_use:
844 844 return
845 845
846 846 import IPython.utils.rlineimpl as readline
847 847
848 848 if not readline.have_readline:
849 849 self.has_readline = 0
850 850 self.readline = None
851 851 # no point in bugging windows users with this every time:
852 852 warn('Readline services not available on this platform.')
853 853 else:
854 854 sys.modules['readline'] = readline
855 855 import atexit
856 856 from IPython.core.completer import IPCompleter
857 857 self.Completer = IPCompleter(self,
858 858 self.user_ns,
859 859 self.user_global_ns,
860 860 self.readline_omit__names,
861 861 self.alias_table)
862 862 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
863 863 self.strdispatchers['complete_command'] = sdisp
864 864 self.Completer.custom_completers = sdisp
865 865 # Platform-specific configuration
866 866 if os.name == 'nt':
867 867 self.readline_startup_hook = readline.set_pre_input_hook
868 868 else:
869 869 self.readline_startup_hook = readline.set_startup_hook
870 870
871 871 # Load user's initrc file (readline config)
872 872 # Or if libedit is used, load editrc.
873 873 inputrc_name = os.environ.get('INPUTRC')
874 874 if inputrc_name is None:
875 875 home_dir = get_home_dir()
876 876 if home_dir is not None:
877 877 inputrc_name = '.inputrc'
878 878 if readline.uses_libedit:
879 879 inputrc_name = '.editrc'
880 880 inputrc_name = os.path.join(home_dir, inputrc_name)
881 881 if os.path.isfile(inputrc_name):
882 882 try:
883 883 readline.read_init_file(inputrc_name)
884 884 except:
885 885 warn('Problems reading readline initialization file <%s>'
886 886 % inputrc_name)
887 887
888 888 self.has_readline = 1
889 889 self.readline = readline
890 890 # save this in sys so embedded copies can restore it properly
891 891 sys.ipcompleter = self.Completer.complete
892 892 self.set_completer()
893 893
894 894 # Configure readline according to user's prefs
895 895 # This is only done if GNU readline is being used. If libedit
896 896 # is being used (as on Leopard) the readline config is
897 897 # not run as the syntax for libedit is different.
898 898 if not readline.uses_libedit:
899 899 for rlcommand in self.readline_parse_and_bind:
900 900 #print "loading rl:",rlcommand # dbg
901 901 readline.parse_and_bind(rlcommand)
902 902
903 903 # Remove some chars from the delimiters list. If we encounter
904 904 # unicode chars, discard them.
905 905 delims = readline.get_completer_delims().encode("ascii", "ignore")
906 906 delims = delims.translate(string._idmap,
907 907 self.readline_remove_delims)
908 908 readline.set_completer_delims(delims)
909 909 # otherwise we end up with a monster history after a while:
910 910 readline.set_history_length(1000)
911 911 try:
912 912 #print '*** Reading readline history' # dbg
913 913 readline.read_history_file(self.histfile)
914 914 except IOError:
915 915 pass # It doesn't exist yet.
916 916
917 917 atexit.register(self.atexit_operations)
918 918 del atexit
919 919
920 920 # Configure auto-indent for all platforms
921 921 self.set_autoindent(self.autoindent)
922 922
923 923 def init_prompts(self):
924 924 # Initialize cache, set in/out prompts and printing system
925 925 self.outputcache = CachedOutput(self,
926 926 self.cache_size,
927 927 self.pprint,
928 928 input_sep = self.separate_in,
929 929 output_sep = self.separate_out,
930 930 output_sep2 = self.separate_out2,
931 931 ps1 = self.prompt_in1,
932 932 ps2 = self.prompt_in2,
933 933 ps_out = self.prompt_out,
934 934 pad_left = self.prompts_pad_left)
935 935
936 936 # user may have over-ridden the default print hook:
937 937 try:
938 938 self.outputcache.__class__.display = self.hooks.display
939 939 except AttributeError:
940 940 pass
941 941
942 942 def init_displayhook(self):
943 943 # I don't like assigning globally to sys, because it means when
944 944 # embedding instances, each embedded instance overrides the previous
945 945 # choice. But sys.displayhook seems to be called internally by exec,
946 946 # so I don't see a way around it. We first save the original and then
947 947 # overwrite it.
948 948 self.sys_displayhook = sys.displayhook
949 949 sys.displayhook = self.outputcache
950 950
951 951 def init_reload_doctest(self):
952 952 # Do a proper resetting of doctest, including the necessary displayhook
953 953 # monkeypatching
954 954 try:
955 955 doctest_reload()
956 956 except ImportError:
957 957 warn("doctest module does not exist.")
958 958
959 959 def init_magics(self):
960 960 # Set user colors (don't do it in the constructor above so that it
961 961 # doesn't crash if colors option is invalid)
962 962 self.magic_colors(self.colors)
963 963
964 964 def init_pdb(self):
965 965 # Set calling of pdb on exceptions
966 966 # self.call_pdb is a property
967 967 self.call_pdb = self.pdb
968 968
969 969 # def init_exec_commands(self):
970 970 # for cmd in self.config.EXECUTE:
971 971 # print "execute:", cmd
972 972 # self.api.runlines(cmd)
973 973 #
974 974 # batchrun = False
975 975 # if self.config.has_key('EXECFILE'):
976 976 # for batchfile in [path(arg) for arg in self.config.EXECFILE
977 977 # if arg.lower().endswith('.ipy')]:
978 978 # if not batchfile.isfile():
979 979 # print "No such batch file:", batchfile
980 980 # continue
981 981 # self.api.runlines(batchfile.text())
982 982 # batchrun = True
983 983 # # without -i option, exit after running the batch file
984 984 # if batchrun and not self.interactive:
985 985 # self.ask_exit()
986 986
987 987 # def load(self, mod):
988 988 # """ Load an extension.
989 989 #
990 990 # Some modules should (or must) be 'load()':ed, rather than just imported.
991 991 #
992 992 # Loading will do:
993 993 #
994 994 # - run init_ipython(ip)
995 995 # - run ipython_firstrun(ip)
996 996 # """
997 997 #
998 998 # if mod in self.extensions:
999 999 # # just to make sure we don't init it twice
1000 1000 # # note that if you 'load' a module that has already been
1001 1001 # # imported, init_ipython gets run anyway
1002 1002 #
1003 1003 # return self.extensions[mod]
1004 1004 # __import__(mod)
1005 1005 # m = sys.modules[mod]
1006 1006 # if hasattr(m,'init_ipython'):
1007 1007 # m.init_ipython(self)
1008 1008 #
1009 1009 # if hasattr(m,'ipython_firstrun'):
1010 1010 # already_loaded = self.db.get('firstrun_done', set())
1011 1011 # if mod not in already_loaded:
1012 1012 # m.ipython_firstrun(self)
1013 1013 # already_loaded.add(mod)
1014 1014 # self.db['firstrun_done'] = already_loaded
1015 1015 #
1016 1016 # self.extensions[mod] = m
1017 1017 # return m
1018 1018
1019 1019 def init_user_ns(self):
1020 1020 """Initialize all user-visible namespaces to their minimum defaults.
1021 1021
1022 1022 Certain history lists are also initialized here, as they effectively
1023 1023 act as user namespaces.
1024 1024
1025 1025 Notes
1026 1026 -----
1027 1027 All data structures here are only filled in, they are NOT reset by this
1028 1028 method. If they were not empty before, data will simply be added to
1029 1029 therm.
1030 1030 """
1031 1031 # The user namespace MUST have a pointer to the shell itself.
1032 1032 self.user_ns[self.name] = self
1033 1033
1034 1034 # Store myself as the public api!!!
1035 1035 self.user_ns['_ip'] = self
1036 1036
1037 1037 # make global variables for user access to the histories
1038 1038 self.user_ns['_ih'] = self.input_hist
1039 1039 self.user_ns['_oh'] = self.output_hist
1040 1040 self.user_ns['_dh'] = self.dir_hist
1041 1041
1042 1042 # user aliases to input and output histories
1043 1043 self.user_ns['In'] = self.input_hist
1044 1044 self.user_ns['Out'] = self.output_hist
1045 1045
1046 1046 self.user_ns['_sh'] = shadowns
1047 1047
1048 1048 # Put 'help' in the user namespace
1049 1049 try:
1050 1050 from site import _Helper
1051 1051 self.user_ns['help'] = _Helper()
1052 1052 except ImportError:
1053 1053 warn('help() not available - check site.py')
1054 1054
1055 1055 def save_sys_module_state(self):
1056 1056 """Save the state of hooks in the sys module.
1057 1057
1058 1058 This has to be called after self.user_ns is created.
1059 1059 """
1060 1060 self._orig_sys_module_state = {}
1061 1061 self._orig_sys_module_state['stdin'] = sys.stdin
1062 1062 self._orig_sys_module_state['stdout'] = sys.stdout
1063 1063 self._orig_sys_module_state['stderr'] = sys.stderr
1064 1064 self._orig_sys_module_state['displayhook'] = sys.displayhook
1065 1065 self._orig_sys_module_state['excepthook'] = sys.excepthook
1066 1066 try:
1067 1067 self._orig_sys_modules_main_name = self.user_ns['__name__']
1068 1068 except KeyError:
1069 1069 pass
1070 1070
1071 1071 def restore_sys_module_state(self):
1072 1072 """Restore the state of the sys module."""
1073 1073 try:
1074 1074 for k, v in self._orig_sys_module_state.items():
1075 1075 setattr(sys, k, v)
1076 1076 except AttributeError:
1077 1077 pass
1078 1078 try:
1079 1079 delattr(sys, 'ipcompleter')
1080 1080 except AttributeError:
1081 1081 pass
1082 1082 # Reset what what done in self.init_sys_modules
1083 1083 try:
1084 1084 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
1085 1085 except (AttributeError, KeyError):
1086 1086 pass
1087 1087
1088 1088 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
1089 1089 """set_hook(name,hook) -> sets an internal IPython hook.
1090 1090
1091 1091 IPython exposes some of its internal API as user-modifiable hooks. By
1092 1092 adding your function to one of these hooks, you can modify IPython's
1093 1093 behavior to call at runtime your own routines."""
1094 1094
1095 1095 # At some point in the future, this should validate the hook before it
1096 1096 # accepts it. Probably at least check that the hook takes the number
1097 1097 # of args it's supposed to.
1098 1098
1099 1099 f = new.instancemethod(hook,self,self.__class__)
1100 1100
1101 1101 # check if the hook is for strdispatcher first
1102 1102 if str_key is not None:
1103 1103 sdp = self.strdispatchers.get(name, StrDispatch())
1104 1104 sdp.add_s(str_key, f, priority )
1105 1105 self.strdispatchers[name] = sdp
1106 1106 return
1107 1107 if re_key is not None:
1108 1108 sdp = self.strdispatchers.get(name, StrDispatch())
1109 1109 sdp.add_re(re.compile(re_key), f, priority )
1110 1110 self.strdispatchers[name] = sdp
1111 1111 return
1112 1112
1113 1113 dp = getattr(self.hooks, name, None)
1114 1114 if name not in IPython.core.hooks.__all__:
1115 1115 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
1116 1116 if not dp:
1117 1117 dp = IPython.core.hooks.CommandChainDispatcher()
1118 1118
1119 1119 try:
1120 1120 dp.add(f,priority)
1121 1121 except AttributeError:
1122 1122 # it was not commandchain, plain old func - replace
1123 1123 dp = f
1124 1124
1125 1125 setattr(self.hooks,name, dp)
1126 1126
1127 1127 def set_crash_handler(self, crashHandler):
1128 1128 """Set the IPython crash handler.
1129 1129
1130 1130 This must be a callable with a signature suitable for use as
1131 1131 sys.excepthook."""
1132 1132
1133 1133 # Install the given crash handler as the Python exception hook
1134 1134 sys.excepthook = crashHandler
1135 1135
1136 1136 # The instance will store a pointer to this, so that runtime code
1137 1137 # (such as magics) can access it. This is because during the
1138 1138 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1139 1139 # frameworks).
1140 1140 self.sys_excepthook = sys.excepthook
1141 1141
1142 1142 def set_custom_exc(self,exc_tuple,handler):
1143 1143 """set_custom_exc(exc_tuple,handler)
1144 1144
1145 1145 Set a custom exception handler, which will be called if any of the
1146 1146 exceptions in exc_tuple occur in the mainloop (specifically, in the
1147 1147 runcode() method.
1148 1148
1149 1149 Inputs:
1150 1150
1151 1151 - exc_tuple: a *tuple* of valid exceptions to call the defined
1152 1152 handler for. It is very important that you use a tuple, and NOT A
1153 1153 LIST here, because of the way Python's except statement works. If
1154 1154 you only want to trap a single exception, use a singleton tuple:
1155 1155
1156 1156 exc_tuple == (MyCustomException,)
1157 1157
1158 1158 - handler: this must be defined as a function with the following
1159 1159 basic interface: def my_handler(self,etype,value,tb).
1160 1160
1161 1161 This will be made into an instance method (via new.instancemethod)
1162 1162 of IPython itself, and it will be called if any of the exceptions
1163 1163 listed in the exc_tuple are caught. If the handler is None, an
1164 1164 internal basic one is used, which just prints basic info.
1165 1165
1166 1166 WARNING: by putting in your own exception handler into IPython's main
1167 1167 execution loop, you run a very good chance of nasty crashes. This
1168 1168 facility should only be used if you really know what you are doing."""
1169 1169
1170 1170 assert type(exc_tuple)==type(()) , \
1171 1171 "The custom exceptions must be given AS A TUPLE."
1172 1172
1173 1173 def dummy_handler(self,etype,value,tb):
1174 1174 print '*** Simple custom exception handler ***'
1175 1175 print 'Exception type :',etype
1176 1176 print 'Exception value:',value
1177 1177 print 'Traceback :',tb
1178 1178 print 'Source code :','\n'.join(self.buffer)
1179 1179
1180 1180 if handler is None: handler = dummy_handler
1181 1181
1182 1182 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1183 1183 self.custom_exceptions = exc_tuple
1184 1184
1185 1185 def set_custom_completer(self,completer,pos=0):
1186 1186 """set_custom_completer(completer,pos=0)
1187 1187
1188 1188 Adds a new custom completer function.
1189 1189
1190 1190 The position argument (defaults to 0) is the index in the completers
1191 1191 list where you want the completer to be inserted."""
1192 1192
1193 1193 newcomp = new.instancemethod(completer,self.Completer,
1194 1194 self.Completer.__class__)
1195 1195 self.Completer.matchers.insert(pos,newcomp)
1196 1196
1197 1197 def set_completer(self):
1198 1198 """reset readline's completer to be our own."""
1199 1199 self.readline.set_completer(self.Completer.complete)
1200 1200
1201 1201 def _get_call_pdb(self):
1202 1202 return self._call_pdb
1203 1203
1204 1204 def _set_call_pdb(self,val):
1205 1205
1206 1206 if val not in (0,1,False,True):
1207 1207 raise ValueError,'new call_pdb value must be boolean'
1208 1208
1209 1209 # store value in instance
1210 1210 self._call_pdb = val
1211 1211
1212 1212 # notify the actual exception handlers
1213 1213 self.InteractiveTB.call_pdb = val
1214 1214 if self.isthreaded:
1215 1215 try:
1216 1216 self.sys_excepthook.call_pdb = val
1217 1217 except:
1218 1218 warn('Failed to activate pdb for threaded exception handler')
1219 1219
1220 1220 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1221 1221 'Control auto-activation of pdb at exceptions')
1222 1222
1223 1223 def magic(self,arg_s):
1224 1224 """Call a magic function by name.
1225 1225
1226 1226 Input: a string containing the name of the magic function to call and any
1227 1227 additional arguments to be passed to the magic.
1228 1228
1229 1229 magic('name -opt foo bar') is equivalent to typing at the ipython
1230 1230 prompt:
1231 1231
1232 1232 In[1]: %name -opt foo bar
1233 1233
1234 1234 To call a magic without arguments, simply use magic('name').
1235 1235
1236 1236 This provides a proper Python function to call IPython's magics in any
1237 1237 valid Python code you can type at the interpreter, including loops and
1238 1238 compound statements.
1239 1239 """
1240 1240
1241 1241 args = arg_s.split(' ',1)
1242 1242 magic_name = args[0]
1243 1243 magic_name = magic_name.lstrip(self.ESC_MAGIC)
1244 1244
1245 1245 try:
1246 1246 magic_args = args[1]
1247 1247 except IndexError:
1248 1248 magic_args = ''
1249 1249 fn = getattr(self,'magic_'+magic_name,None)
1250 1250 if fn is None:
1251 1251 error("Magic function `%s` not found." % magic_name)
1252 1252 else:
1253 1253 magic_args = self.var_expand(magic_args,1)
1254 1254 with self.builtin_trap:
1255 result = fn(magic_args)
1256 return result
1255 return fn(magic_args)
1256 # return result
1257 1257
1258 1258 def define_magic(self, magicname, func):
1259 1259 """Expose own function as magic function for ipython
1260 1260
1261 1261 def foo_impl(self,parameter_s=''):
1262 1262 'My very own magic!. (Use docstrings, IPython reads them).'
1263 1263 print 'Magic function. Passed parameter is between < >:'
1264 1264 print '<%s>' % parameter_s
1265 1265 print 'The self object is:',self
1266 1266
1267 1267 self.define_magic('foo',foo_impl)
1268 1268 """
1269 1269
1270 1270 import new
1271 1271 im = new.instancemethod(func,self, self.__class__)
1272 1272 old = getattr(self, "magic_" + magicname, None)
1273 1273 setattr(self, "magic_" + magicname, im)
1274 1274 return old
1275 1275
1276 1276 def define_macro(self, name, themacro):
1277 1277 """Define a new macro
1278 1278
1279 1279 Parameters
1280 1280 ----------
1281 1281 name : str
1282 1282 The name of the macro.
1283 1283 themacro : str or Macro
1284 1284 The action to do upon invoking the macro. If a string, a new
1285 1285 Macro object is created by passing the string to it.
1286 1286 """
1287 1287
1288 1288 from IPython.core import macro
1289 1289
1290 1290 if isinstance(themacro, basestring):
1291 1291 themacro = macro.Macro(themacro)
1292 1292 if not isinstance(themacro, macro.Macro):
1293 1293 raise ValueError('A macro must be a string or a Macro instance.')
1294 1294 self.user_ns[name] = themacro
1295 1295
1296 1296 def define_alias(self, name, cmd):
1297 1297 """ Define a new alias."""
1298 1298
1299 1299 if callable(cmd):
1300 1300 self.alias_table[name] = cmd
1301 1301 from IPython.core import shadowns
1302 1302 setattr(shadowns, name, cmd)
1303 1303 return
1304 1304
1305 1305 if isinstance(cmd, basestring):
1306 1306 nargs = cmd.count('%s')
1307 1307 if nargs>0 and cmd.find('%l')>=0:
1308 1308 raise Exception('The %s and %l specifiers are mutually '
1309 1309 'exclusive in alias definitions.')
1310 1310
1311 1311 self.alias_table[name] = (nargs,cmd)
1312 1312 return
1313 1313
1314 1314 self.alias_table[name] = cmd
1315 1315
1316 1316 def ipalias(self,arg_s):
1317 1317 """Call an alias by name.
1318 1318
1319 1319 Input: a string containing the name of the alias to call and any
1320 1320 additional arguments to be passed to the magic.
1321 1321
1322 1322 ipalias('name -opt foo bar') is equivalent to typing at the ipython
1323 1323 prompt:
1324 1324
1325 1325 In[1]: name -opt foo bar
1326 1326
1327 1327 To call an alias without arguments, simply use ipalias('name').
1328 1328
1329 1329 This provides a proper Python function to call IPython's aliases in any
1330 1330 valid Python code you can type at the interpreter, including loops and
1331 1331 compound statements. It is added by IPython to the Python builtin
1332 1332 namespace upon initialization."""
1333 1333
1334 1334 args = arg_s.split(' ',1)
1335 1335 alias_name = args[0]
1336 1336 try:
1337 1337 alias_args = args[1]
1338 1338 except IndexError:
1339 1339 alias_args = ''
1340 1340 if alias_name in self.alias_table:
1341 1341 self.call_alias(alias_name,alias_args)
1342 1342 else:
1343 1343 error("Alias `%s` not found." % alias_name)
1344 1344
1345 1345 def system(self, cmd):
1346 1346 """Make a system call, using IPython."""
1347 1347 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1348 1348
1349 1349 def ex(self, cmd):
1350 1350 """Execute a normal python statement in user namespace."""
1351 1351 with self.builtin_trap:
1352 1352 exec cmd in self.user_global_ns, self.user_ns
1353 1353
1354 1354 def ev(self, expr):
1355 1355 """Evaluate python expression expr in user namespace.
1356 1356
1357 1357 Returns the result of evaluation
1358 1358 """
1359 1359 with self.builtin_trap:
1360 result = eval(expr, self.user_global_ns, self.user_ns)
1361 return result
1360 return eval(expr, self.user_global_ns, self.user_ns)
1362 1361
1363 1362 def getoutput(self, cmd):
1364 1363 return getoutput(self.var_expand(cmd,depth=2),
1365 1364 header=self.system_header,
1366 1365 verbose=self.system_verbose)
1367 1366
1368 1367 def getoutputerror(self, cmd):
1369 1368 return getoutputerror(self.var_expand(cmd,depth=2),
1370 1369 header=self.system_header,
1371 1370 verbose=self.system_verbose)
1372 1371
1373 1372 def complete(self, text):
1374 1373 """Return a sorted list of all possible completions on text.
1375 1374
1376 1375 Inputs:
1377 1376
1378 1377 - text: a string of text to be completed on.
1379 1378
1380 1379 This is a wrapper around the completion mechanism, similar to what
1381 1380 readline does at the command line when the TAB key is hit. By
1382 1381 exposing it as a method, it can be used by other non-readline
1383 1382 environments (such as GUIs) for text completion.
1384 1383
1385 1384 Simple usage example:
1386 1385
1387 1386 In [7]: x = 'hello'
1388 1387
1389 1388 In [8]: x
1390 1389 Out[8]: 'hello'
1391 1390
1392 1391 In [9]: print x
1393 1392 hello
1394 1393
1395 1394 In [10]: _ip.complete('x.l')
1396 1395 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1397 1396 """
1398 1397
1399 1398 # Inject names into __builtin__ so we can complete on the added names.
1400 1399 with self.builtin_trap:
1401 1400 complete = self.Completer.complete
1402 1401 state = 0
1403 1402 # use a dict so we get unique keys, since ipyhton's multiple
1404 1403 # completers can return duplicates. When we make 2.4 a requirement,
1405 1404 # start using sets instead, which are faster.
1406 1405 comps = {}
1407 1406 while True:
1408 1407 newcomp = complete(text,state,line_buffer=text)
1409 1408 if newcomp is None:
1410 1409 break
1411 1410 comps[newcomp] = 1
1412 1411 state += 1
1413 1412 outcomps = comps.keys()
1414 1413 outcomps.sort()
1415 1414 #print "T:",text,"OC:",outcomps # dbg
1416 1415 #print "vars:",self.user_ns.keys()
1417 return outcomps
1416 return outcomps
1418 1417
1419 1418 def set_completer_frame(self, frame=None):
1420 1419 if frame:
1421 1420 self.Completer.namespace = frame.f_locals
1422 1421 self.Completer.global_namespace = frame.f_globals
1423 1422 else:
1424 1423 self.Completer.namespace = self.user_ns
1425 1424 self.Completer.global_namespace = self.user_global_ns
1426 1425
1427 1426 def init_auto_alias(self):
1428 1427 """Define some aliases automatically.
1429 1428
1430 1429 These are ALL parameter-less aliases"""
1431 1430
1432 1431 for alias,cmd in self.auto_alias:
1433 1432 self.define_alias(alias,cmd)
1434 1433
1435 1434 def alias_table_validate(self,verbose=0):
1436 1435 """Update information about the alias table.
1437 1436
1438 1437 In particular, make sure no Python keywords/builtins are in it."""
1439 1438
1440 1439 no_alias = self.no_alias
1441 1440 for k in self.alias_table.keys():
1442 1441 if k in no_alias:
1443 1442 del self.alias_table[k]
1444 1443 if verbose:
1445 1444 print ("Deleting alias <%s>, it's a Python "
1446 1445 "keyword or builtin." % k)
1447 1446
1448 1447 def set_next_input(self, s):
1449 1448 """ Sets the 'default' input string for the next command line.
1450 1449
1451 1450 Requires readline.
1452 1451
1453 1452 Example:
1454 1453
1455 1454 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1456 1455 [D:\ipython]|2> Hello Word_ # cursor is here
1457 1456 """
1458 1457
1459 1458 self.rl_next_input = s
1460 1459
1461 1460 def set_autoindent(self,value=None):
1462 1461 """Set the autoindent flag, checking for readline support.
1463 1462
1464 1463 If called with no arguments, it acts as a toggle."""
1465 1464
1466 1465 if not self.has_readline:
1467 1466 if os.name == 'posix':
1468 1467 warn("The auto-indent feature requires the readline library")
1469 1468 self.autoindent = 0
1470 1469 return
1471 1470 if value is None:
1472 1471 self.autoindent = not self.autoindent
1473 1472 else:
1474 1473 self.autoindent = value
1475 1474
1476 1475 def atexit_operations(self):
1477 1476 """This will be executed at the time of exit.
1478 1477
1479 1478 Saving of persistent data should be performed here. """
1480 1479
1481 1480 #print '*** IPython exit cleanup ***' # dbg
1482 1481 # input history
1483 1482 self.savehist()
1484 1483
1485 1484 # Cleanup all tempfiles left around
1486 1485 for tfile in self.tempfiles:
1487 1486 try:
1488 1487 os.unlink(tfile)
1489 1488 except OSError:
1490 1489 pass
1491 1490
1492 1491 # Clear all user namespaces to release all references cleanly.
1493 1492 self.reset()
1494 1493
1495 1494 # Run user hooks
1496 1495 self.hooks.shutdown_hook()
1497 1496
1498 1497 def reset(self):
1499 1498 """Clear all internal namespaces.
1500 1499
1501 1500 Note that this is much more aggressive than %reset, since it clears
1502 1501 fully all namespaces, as well as all input/output lists.
1503 1502 """
1504 1503 for ns in self.ns_refs_table:
1505 1504 ns.clear()
1506 1505
1507 1506 # Clear input and output histories
1508 1507 self.input_hist[:] = []
1509 1508 self.input_hist_raw[:] = []
1510 1509 self.output_hist.clear()
1511 1510 # Restore the user namespaces to minimal usability
1512 1511 self.init_user_ns()
1513 1512
1514 1513 def savehist(self):
1515 1514 """Save input history to a file (via readline library)."""
1516 1515
1517 1516 if not self.has_readline:
1518 1517 return
1519 1518
1520 1519 try:
1521 1520 self.readline.write_history_file(self.histfile)
1522 1521 except:
1523 1522 print 'Unable to save IPython command history to file: ' + \
1524 1523 `self.histfile`
1525 1524
1526 1525 def reloadhist(self):
1527 1526 """Reload the input history from disk file."""
1528 1527
1529 1528 if self.has_readline:
1530 1529 try:
1531 1530 self.readline.clear_history()
1532 1531 self.readline.read_history_file(self.shell.histfile)
1533 1532 except AttributeError:
1534 1533 pass
1535 1534
1536 1535
1537 1536 def history_saving_wrapper(self, func):
1538 1537 """ Wrap func for readline history saving
1539 1538
1540 1539 Convert func into callable that saves & restores
1541 1540 history around the call """
1542 1541
1543 1542 if not self.has_readline:
1544 1543 return func
1545 1544
1546 1545 def wrapper():
1547 1546 self.savehist()
1548 1547 try:
1549 1548 func()
1550 1549 finally:
1551 1550 readline.read_history_file(self.histfile)
1552 1551 return wrapper
1553 1552
1554 1553 def pre_readline(self):
1555 1554 """readline hook to be used at the start of each line.
1556 1555
1557 1556 Currently it handles auto-indent only."""
1558 1557
1559 1558 #debugx('self.indent_current_nsp','pre_readline:')
1560 1559
1561 1560 if self.rl_do_indent:
1562 1561 self.readline.insert_text(self.indent_current_str())
1563 1562 if self.rl_next_input is not None:
1564 1563 self.readline.insert_text(self.rl_next_input)
1565 1564 self.rl_next_input = None
1566 1565
1567 1566 def ask_yes_no(self,prompt,default=True):
1568 1567 if self.quiet:
1569 1568 return True
1570 1569 return ask_yes_no(prompt,default)
1571 1570
1572 1571 def new_main_mod(self,ns=None):
1573 1572 """Return a new 'main' module object for user code execution.
1574 1573 """
1575 1574 main_mod = self._user_main_module
1576 1575 init_fakemod_dict(main_mod,ns)
1577 1576 return main_mod
1578 1577
1579 1578 def cache_main_mod(self,ns,fname):
1580 1579 """Cache a main module's namespace.
1581 1580
1582 1581 When scripts are executed via %run, we must keep a reference to the
1583 1582 namespace of their __main__ module (a FakeModule instance) around so
1584 1583 that Python doesn't clear it, rendering objects defined therein
1585 1584 useless.
1586 1585
1587 1586 This method keeps said reference in a private dict, keyed by the
1588 1587 absolute path of the module object (which corresponds to the script
1589 1588 path). This way, for multiple executions of the same script we only
1590 1589 keep one copy of the namespace (the last one), thus preventing memory
1591 1590 leaks from old references while allowing the objects from the last
1592 1591 execution to be accessible.
1593 1592
1594 1593 Note: we can not allow the actual FakeModule instances to be deleted,
1595 1594 because of how Python tears down modules (it hard-sets all their
1596 1595 references to None without regard for reference counts). This method
1597 1596 must therefore make a *copy* of the given namespace, to allow the
1598 1597 original module's __dict__ to be cleared and reused.
1599 1598
1600 1599
1601 1600 Parameters
1602 1601 ----------
1603 1602 ns : a namespace (a dict, typically)
1604 1603
1605 1604 fname : str
1606 1605 Filename associated with the namespace.
1607 1606
1608 1607 Examples
1609 1608 --------
1610 1609
1611 1610 In [10]: import IPython
1612 1611
1613 1612 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1614 1613
1615 1614 In [12]: IPython.__file__ in _ip._main_ns_cache
1616 1615 Out[12]: True
1617 1616 """
1618 1617 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
1619 1618
1620 1619 def clear_main_mod_cache(self):
1621 1620 """Clear the cache of main modules.
1622 1621
1623 1622 Mainly for use by utilities like %reset.
1624 1623
1625 1624 Examples
1626 1625 --------
1627 1626
1628 1627 In [15]: import IPython
1629 1628
1630 1629 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
1631 1630
1632 1631 In [17]: len(_ip._main_ns_cache) > 0
1633 1632 Out[17]: True
1634 1633
1635 1634 In [18]: _ip.clear_main_mod_cache()
1636 1635
1637 1636 In [19]: len(_ip._main_ns_cache) == 0
1638 1637 Out[19]: True
1639 1638 """
1640 1639 self._main_ns_cache.clear()
1641 1640
1642 1641 def _should_recompile(self,e):
1643 1642 """Utility routine for edit_syntax_error"""
1644 1643
1645 1644 if e.filename in ('<ipython console>','<input>','<string>',
1646 1645 '<console>','<BackgroundJob compilation>',
1647 1646 None):
1648 1647
1649 1648 return False
1650 1649 try:
1651 1650 if (self.autoedit_syntax and
1652 1651 not self.ask_yes_no('Return to editor to correct syntax error? '
1653 1652 '[Y/n] ','y')):
1654 1653 return False
1655 1654 except EOFError:
1656 1655 return False
1657 1656
1658 1657 def int0(x):
1659 1658 try:
1660 1659 return int(x)
1661 1660 except TypeError:
1662 1661 return 0
1663 1662 # always pass integer line and offset values to editor hook
1664 1663 try:
1665 1664 self.hooks.fix_error_editor(e.filename,
1666 1665 int0(e.lineno),int0(e.offset),e.msg)
1667 1666 except TryNext:
1668 1667 warn('Could not open editor')
1669 1668 return False
1670 1669 return True
1671 1670
1672 1671 def edit_syntax_error(self):
1673 1672 """The bottom half of the syntax error handler called in the main loop.
1674 1673
1675 1674 Loop until syntax error is fixed or user cancels.
1676 1675 """
1677 1676
1678 1677 while self.SyntaxTB.last_syntax_error:
1679 1678 # copy and clear last_syntax_error
1680 1679 err = self.SyntaxTB.clear_err_state()
1681 1680 if not self._should_recompile(err):
1682 1681 return
1683 1682 try:
1684 1683 # may set last_syntax_error again if a SyntaxError is raised
1685 1684 self.safe_execfile(err.filename,self.user_ns)
1686 1685 except:
1687 1686 self.showtraceback()
1688 1687 else:
1689 1688 try:
1690 1689 f = file(err.filename)
1691 1690 try:
1692 1691 sys.displayhook(f.read())
1693 1692 finally:
1694 1693 f.close()
1695 1694 except:
1696 1695 self.showtraceback()
1697 1696
1698 1697 def showsyntaxerror(self, filename=None):
1699 1698 """Display the syntax error that just occurred.
1700 1699
1701 1700 This doesn't display a stack trace because there isn't one.
1702 1701
1703 1702 If a filename is given, it is stuffed in the exception instead
1704 1703 of what was there before (because Python's parser always uses
1705 1704 "<string>" when reading from a string).
1706 1705 """
1707 1706 etype, value, last_traceback = sys.exc_info()
1708 1707
1709 1708 # See note about these variables in showtraceback() below
1710 1709 sys.last_type = etype
1711 1710 sys.last_value = value
1712 1711 sys.last_traceback = last_traceback
1713 1712
1714 1713 if filename and etype is SyntaxError:
1715 1714 # Work hard to stuff the correct filename in the exception
1716 1715 try:
1717 1716 msg, (dummy_filename, lineno, offset, line) = value
1718 1717 except:
1719 1718 # Not the format we expect; leave it alone
1720 1719 pass
1721 1720 else:
1722 1721 # Stuff in the right filename
1723 1722 try:
1724 1723 # Assume SyntaxError is a class exception
1725 1724 value = SyntaxError(msg, (filename, lineno, offset, line))
1726 1725 except:
1727 1726 # If that failed, assume SyntaxError is a string
1728 1727 value = msg, (filename, lineno, offset, line)
1729 1728 self.SyntaxTB(etype,value,[])
1730 1729
1731 1730 def debugger(self,force=False):
1732 1731 """Call the pydb/pdb debugger.
1733 1732
1734 1733 Keywords:
1735 1734
1736 1735 - force(False): by default, this routine checks the instance call_pdb
1737 1736 flag and does not actually invoke the debugger if the flag is false.
1738 1737 The 'force' option forces the debugger to activate even if the flag
1739 1738 is false.
1740 1739 """
1741 1740
1742 1741 if not (force or self.call_pdb):
1743 1742 return
1744 1743
1745 1744 if not hasattr(sys,'last_traceback'):
1746 1745 error('No traceback has been produced, nothing to debug.')
1747 1746 return
1748 1747
1749 1748 # use pydb if available
1750 1749 if debugger.has_pydb:
1751 1750 from pydb import pm
1752 1751 else:
1753 1752 # fallback to our internal debugger
1754 1753 pm = lambda : self.InteractiveTB.debugger(force=True)
1755 1754 self.history_saving_wrapper(pm)()
1756 1755
1757 1756 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1758 1757 """Display the exception that just occurred.
1759 1758
1760 1759 If nothing is known about the exception, this is the method which
1761 1760 should be used throughout the code for presenting user tracebacks,
1762 1761 rather than directly invoking the InteractiveTB object.
1763 1762
1764 1763 A specific showsyntaxerror() also exists, but this method can take
1765 1764 care of calling it if needed, so unless you are explicitly catching a
1766 1765 SyntaxError exception, don't try to analyze the stack manually and
1767 1766 simply call this method."""
1768 1767
1769 1768
1770 1769 # Though this won't be called by syntax errors in the input line,
1771 1770 # there may be SyntaxError cases whith imported code.
1772 1771
1773 1772 try:
1774 1773 if exc_tuple is None:
1775 1774 etype, value, tb = sys.exc_info()
1776 1775 else:
1777 1776 etype, value, tb = exc_tuple
1778 1777
1779 1778 if etype is SyntaxError:
1780 1779 self.showsyntaxerror(filename)
1781 1780 elif etype is UsageError:
1782 1781 print "UsageError:", value
1783 1782 else:
1784 1783 # WARNING: these variables are somewhat deprecated and not
1785 1784 # necessarily safe to use in a threaded environment, but tools
1786 1785 # like pdb depend on their existence, so let's set them. If we
1787 1786 # find problems in the field, we'll need to revisit their use.
1788 1787 sys.last_type = etype
1789 1788 sys.last_value = value
1790 1789 sys.last_traceback = tb
1791 1790
1792 1791 if etype in self.custom_exceptions:
1793 1792 self.CustomTB(etype,value,tb)
1794 1793 else:
1795 1794 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1796 1795 if self.InteractiveTB.call_pdb and self.has_readline:
1797 1796 # pdb mucks up readline, fix it back
1798 1797 self.set_completer()
1799 1798 except KeyboardInterrupt:
1800 1799 self.write("\nKeyboardInterrupt\n")
1801 1800
1802 1801 def mainloop(self, banner=None):
1803 1802 """Start the mainloop.
1804 1803
1805 1804 If an optional banner argument is given, it will override the
1806 1805 internally created default banner.
1807 1806 """
1808 1807
1809 1808 with self.builtin_trap:
1810 1809 if self.c: # Emulate Python's -c option
1811 1810 self.exec_init_cmd()
1812 1811
1813 1812 if self.display_banner:
1814 1813 if banner is None:
1815 1814 banner = self.banner
1816 1815
1817 1816 # if you run stuff with -c <cmd>, raw hist is not updated
1818 1817 # ensure that it's in sync
1819 1818 if len(self.input_hist) != len (self.input_hist_raw):
1820 1819 self.input_hist_raw = InputList(self.input_hist)
1821 1820
1822 1821 while 1:
1823 1822 try:
1824 1823 self.interact()
1825 1824 #self.interact_with_readline()
1826 1825 # XXX for testing of a readline-decoupled repl loop, call
1827 1826 # interact_with_readline above
1828 1827 break
1829 1828 except KeyboardInterrupt:
1830 1829 # this should not be necessary, but KeyboardInterrupt
1831 1830 # handling seems rather unpredictable...
1832 1831 self.write("\nKeyboardInterrupt in interact()\n")
1833 1832
1834 1833 def exec_init_cmd(self):
1835 1834 """Execute a command given at the command line.
1836 1835
1837 1836 This emulates Python's -c option."""
1838 1837
1839 1838 #sys.argv = ['-c']
1840 1839 self.push_line(self.prefilter(self.c, False))
1841 1840 if not self.interactive:
1842 1841 self.ask_exit()
1843 1842
1844 1843 def interact_prompt(self):
1845 1844 """ Print the prompt (in read-eval-print loop)
1846 1845
1847 1846 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1848 1847 used in standard IPython flow.
1849 1848 """
1850 1849 if self.more:
1851 1850 try:
1852 1851 prompt = self.hooks.generate_prompt(True)
1853 1852 except:
1854 1853 self.showtraceback()
1855 1854 if self.autoindent:
1856 1855 self.rl_do_indent = True
1857 1856
1858 1857 else:
1859 1858 try:
1860 1859 prompt = self.hooks.generate_prompt(False)
1861 1860 except:
1862 1861 self.showtraceback()
1863 1862 self.write(prompt)
1864 1863
1865 1864 def interact_handle_input(self,line):
1866 1865 """ Handle the input line (in read-eval-print loop)
1867 1866
1868 1867 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1869 1868 used in standard IPython flow.
1870 1869 """
1871 1870 if line.lstrip() == line:
1872 1871 self.shadowhist.add(line.strip())
1873 1872 lineout = self.prefilter(line,self.more)
1874 1873
1875 1874 if line.strip():
1876 1875 if self.more:
1877 1876 self.input_hist_raw[-1] += '%s\n' % line
1878 1877 else:
1879 1878 self.input_hist_raw.append('%s\n' % line)
1880 1879
1881 1880
1882 1881 self.more = self.push_line(lineout)
1883 1882 if (self.SyntaxTB.last_syntax_error and
1884 1883 self.autoedit_syntax):
1885 1884 self.edit_syntax_error()
1886 1885
1887 1886 def interact_with_readline(self):
1888 1887 """ Demo of using interact_handle_input, interact_prompt
1889 1888
1890 1889 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1891 1890 it should work like this.
1892 1891 """
1893 1892 self.readline_startup_hook(self.pre_readline)
1894 1893 while not self.exit_now:
1895 1894 self.interact_prompt()
1896 1895 if self.more:
1897 1896 self.rl_do_indent = True
1898 1897 else:
1899 1898 self.rl_do_indent = False
1900 1899 line = raw_input_original().decode(self.stdin_encoding)
1901 1900 self.interact_handle_input(line)
1902 1901
1903 1902 def interact(self, banner=None):
1904 1903 """Closely emulate the interactive Python console."""
1905 1904
1906 1905 # batch run -> do not interact
1907 1906 if self.exit_now:
1908 1907 return
1909 1908
1910 1909 if self.display_banner:
1911 1910 if banner is None:
1912 1911 banner = self.banner
1913 1912 self.write(banner)
1914 1913
1915 1914 more = 0
1916 1915
1917 1916 # Mark activity in the builtins
1918 1917 __builtin__.__dict__['__IPYTHON__active'] += 1
1919 1918
1920 1919 if self.has_readline:
1921 1920 self.readline_startup_hook(self.pre_readline)
1922 1921 # exit_now is set by a call to %Exit or %Quit, through the
1923 1922 # ask_exit callback.
1924 1923
1925 1924 while not self.exit_now:
1926 1925 self.hooks.pre_prompt_hook()
1927 1926 if more:
1928 1927 try:
1929 1928 prompt = self.hooks.generate_prompt(True)
1930 1929 except:
1931 1930 self.showtraceback()
1932 1931 if self.autoindent:
1933 1932 self.rl_do_indent = True
1934 1933
1935 1934 else:
1936 1935 try:
1937 1936 prompt = self.hooks.generate_prompt(False)
1938 1937 except:
1939 1938 self.showtraceback()
1940 1939 try:
1941 1940 line = self.raw_input(prompt, more)
1942 1941 if self.exit_now:
1943 1942 # quick exit on sys.std[in|out] close
1944 1943 break
1945 1944 if self.autoindent:
1946 1945 self.rl_do_indent = False
1947 1946
1948 1947 except KeyboardInterrupt:
1949 1948 #double-guard against keyboardinterrupts during kbdint handling
1950 1949 try:
1951 1950 self.write('\nKeyboardInterrupt\n')
1952 1951 self.resetbuffer()
1953 1952 # keep cache in sync with the prompt counter:
1954 1953 self.outputcache.prompt_count -= 1
1955 1954
1956 1955 if self.autoindent:
1957 1956 self.indent_current_nsp = 0
1958 1957 more = 0
1959 1958 except KeyboardInterrupt:
1960 1959 pass
1961 1960 except EOFError:
1962 1961 if self.autoindent:
1963 1962 self.rl_do_indent = False
1964 1963 self.readline_startup_hook(None)
1965 1964 self.write('\n')
1966 1965 self.exit()
1967 1966 except bdb.BdbQuit:
1968 1967 warn('The Python debugger has exited with a BdbQuit exception.\n'
1969 1968 'Because of how pdb handles the stack, it is impossible\n'
1970 1969 'for IPython to properly format this particular exception.\n'
1971 1970 'IPython will resume normal operation.')
1972 1971 except:
1973 1972 # exceptions here are VERY RARE, but they can be triggered
1974 1973 # asynchronously by signal handlers, for example.
1975 1974 self.showtraceback()
1976 1975 else:
1977 1976 more = self.push_line(line)
1978 1977 if (self.SyntaxTB.last_syntax_error and
1979 1978 self.autoedit_syntax):
1980 1979 self.edit_syntax_error()
1981 1980
1982 1981 # We are off again...
1983 1982 __builtin__.__dict__['__IPYTHON__active'] -= 1
1984 1983
1985 1984 def excepthook(self, etype, value, tb):
1986 1985 """One more defense for GUI apps that call sys.excepthook.
1987 1986
1988 1987 GUI frameworks like wxPython trap exceptions and call
1989 1988 sys.excepthook themselves. I guess this is a feature that
1990 1989 enables them to keep running after exceptions that would
1991 1990 otherwise kill their mainloop. This is a bother for IPython
1992 1991 which excepts to catch all of the program exceptions with a try:
1993 1992 except: statement.
1994 1993
1995 1994 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1996 1995 any app directly invokes sys.excepthook, it will look to the user like
1997 1996 IPython crashed. In order to work around this, we can disable the
1998 1997 CrashHandler and replace it with this excepthook instead, which prints a
1999 1998 regular traceback using our InteractiveTB. In this fashion, apps which
2000 1999 call sys.excepthook will generate a regular-looking exception from
2001 2000 IPython, and the CrashHandler will only be triggered by real IPython
2002 2001 crashes.
2003 2002
2004 2003 This hook should be used sparingly, only in places which are not likely
2005 2004 to be true IPython errors.
2006 2005 """
2007 2006 self.showtraceback((etype,value,tb),tb_offset=0)
2008 2007
2009 2008 def expand_alias(self, line):
2010 2009 """ Expand an alias in the command line
2011 2010
2012 2011 Returns the provided command line, possibly with the first word
2013 2012 (command) translated according to alias expansion rules.
2014 2013
2015 2014 [ipython]|16> _ip.expand_aliases("np myfile.txt")
2016 2015 <16> 'q:/opt/np/notepad++.exe myfile.txt'
2017 2016 """
2018 2017
2019 2018 pre,fn,rest = self.split_user_input(line)
2020 2019 res = pre + self.expand_aliases(fn, rest)
2021 2020 return res
2022 2021
2023 2022 def expand_aliases(self, fn, rest):
2024 2023 """Expand multiple levels of aliases:
2025 2024
2026 2025 if:
2027 2026
2028 2027 alias foo bar /tmp
2029 2028 alias baz foo
2030 2029
2031 2030 then:
2032 2031
2033 2032 baz huhhahhei -> bar /tmp huhhahhei
2034 2033
2035 2034 """
2036 2035 line = fn + " " + rest
2037 2036
2038 2037 done = set()
2039 2038 while 1:
2040 2039 pre,fn,rest = prefilter.splitUserInput(line,
2041 2040 prefilter.shell_line_split)
2042 2041 if fn in self.alias_table:
2043 2042 if fn in done:
2044 2043 warn("Cyclic alias definition, repeated '%s'" % fn)
2045 2044 return ""
2046 2045 done.add(fn)
2047 2046
2048 2047 l2 = self.transform_alias(fn,rest)
2049 2048 # dir -> dir
2050 2049 # print "alias",line, "->",l2 #dbg
2051 2050 if l2 == line:
2052 2051 break
2053 2052 # ls -> ls -F should not recurse forever
2054 2053 if l2.split(None,1)[0] == line.split(None,1)[0]:
2055 2054 line = l2
2056 2055 break
2057 2056
2058 2057 line=l2
2059 2058
2060 2059
2061 2060 # print "al expand to",line #dbg
2062 2061 else:
2063 2062 break
2064 2063
2065 2064 return line
2066 2065
2067 2066 def transform_alias(self, alias,rest=''):
2068 2067 """ Transform alias to system command string.
2069 2068 """
2070 2069 trg = self.alias_table[alias]
2071 2070
2072 2071 nargs,cmd = trg
2073 2072 # print trg #dbg
2074 2073 if ' ' in cmd and os.path.isfile(cmd):
2075 2074 cmd = '"%s"' % cmd
2076 2075
2077 2076 # Expand the %l special to be the user's input line
2078 2077 if cmd.find('%l') >= 0:
2079 2078 cmd = cmd.replace('%l',rest)
2080 2079 rest = ''
2081 2080 if nargs==0:
2082 2081 # Simple, argument-less aliases
2083 2082 cmd = '%s %s' % (cmd,rest)
2084 2083 else:
2085 2084 # Handle aliases with positional arguments
2086 2085 args = rest.split(None,nargs)
2087 2086 if len(args)< nargs:
2088 2087 error('Alias <%s> requires %s arguments, %s given.' %
2089 2088 (alias,nargs,len(args)))
2090 2089 return None
2091 2090 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
2092 2091 # Now call the macro, evaluating in the user's namespace
2093 2092 #print 'new command: <%r>' % cmd # dbg
2094 2093 return cmd
2095 2094
2096 2095 def call_alias(self,alias,rest=''):
2097 2096 """Call an alias given its name and the rest of the line.
2098 2097
2099 2098 This is only used to provide backwards compatibility for users of
2100 2099 ipalias(), use of which is not recommended for anymore."""
2101 2100
2102 2101 # Now call the macro, evaluating in the user's namespace
2103 2102 cmd = self.transform_alias(alias, rest)
2104 2103 try:
2105 2104 self.system(cmd)
2106 2105 except:
2107 2106 self.showtraceback()
2108 2107
2109 2108 def indent_current_str(self):
2110 2109 """return the current level of indentation as a string"""
2111 2110 return self.indent_current_nsp * ' '
2112 2111
2113 2112 def autoindent_update(self,line):
2114 2113 """Keep track of the indent level."""
2115 2114
2116 2115 #debugx('line')
2117 2116 #debugx('self.indent_current_nsp')
2118 2117 if self.autoindent:
2119 2118 if line:
2120 2119 inisp = num_ini_spaces(line)
2121 2120 if inisp < self.indent_current_nsp:
2122 2121 self.indent_current_nsp = inisp
2123 2122
2124 2123 if line[-1] == ':':
2125 2124 self.indent_current_nsp += 4
2126 2125 elif dedent_re.match(line):
2127 2126 self.indent_current_nsp -= 4
2128 2127 else:
2129 2128 self.indent_current_nsp = 0
2130 2129
2131 2130 def push(self, variables, interactive=True):
2132 2131 """Inject a group of variables into the IPython user namespace.
2133 2132
2134 2133 Parameters
2135 2134 ----------
2136 2135 variables : dict, str or list/tuple of str
2137 2136 The variables to inject into the user's namespace. If a dict,
2138 2137 a simple update is done. If a str, the string is assumed to
2139 2138 have variable names separated by spaces. A list/tuple of str
2140 2139 can also be used to give the variable names. If just the variable
2141 2140 names are give (list/tuple/str) then the variable values looked
2142 2141 up in the callers frame.
2143 2142 interactive : bool
2144 2143 If True (default), the variables will be listed with the ``who``
2145 2144 magic.
2146 2145 """
2147 2146 vdict = None
2148 2147
2149 2148 # We need a dict of name/value pairs to do namespace updates.
2150 2149 if isinstance(variables, dict):
2151 2150 vdict = variables
2152 2151 elif isinstance(variables, (basestring, list, tuple)):
2153 2152 if isinstance(variables, basestring):
2154 2153 vlist = variables.split()
2155 2154 else:
2156 2155 vlist = variables
2157 2156 vdict = {}
2158 2157 cf = sys._getframe(1)
2159 2158 for name in vlist:
2160 2159 try:
2161 2160 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
2162 2161 except:
2163 2162 print ('Could not get variable %s from %s' %
2164 2163 (name,cf.f_code.co_name))
2165 2164 else:
2166 2165 raise ValueError('variables must be a dict/str/list/tuple')
2167 2166
2168 2167 # Propagate variables to user namespace
2169 2168 self.user_ns.update(vdict)
2170 2169
2171 2170 # And configure interactive visibility
2172 2171 config_ns = self.user_config_ns
2173 2172 if interactive:
2174 2173 for name, val in vdict.iteritems():
2175 2174 config_ns.pop(name, None)
2176 2175 else:
2177 2176 for name,val in vdict.iteritems():
2178 2177 config_ns[name] = val
2179 2178
2180 2179 def cleanup_ipy_script(self, script):
2181 2180 """Make a script safe for self.runlines()
2182 2181
2183 2182 Notes
2184 2183 -----
2185 2184 This was copied over from the old ipapi and probably can be done
2186 2185 away with once we move to block based interpreter.
2187 2186
2188 2187 - Removes empty lines Suffixes all indented blocks that end with
2189 2188 - unindented lines with empty lines
2190 2189 """
2191 2190
2192 2191 res = []
2193 2192 lines = script.splitlines()
2194 2193
2195 2194 level = 0
2196 2195 for l in lines:
2197 2196 lstripped = l.lstrip()
2198 2197 stripped = l.strip()
2199 2198 if not stripped:
2200 2199 continue
2201 2200 newlevel = len(l) - len(lstripped)
2202 2201 def is_secondary_block_start(s):
2203 2202 if not s.endswith(':'):
2204 2203 return False
2205 2204 if (s.startswith('elif') or
2206 2205 s.startswith('else') or
2207 2206 s.startswith('except') or
2208 2207 s.startswith('finally')):
2209 2208 return True
2210 2209
2211 2210 if level > 0 and newlevel == 0 and \
2212 2211 not is_secondary_block_start(stripped):
2213 2212 # add empty line
2214 2213 res.append('')
2215 2214
2216 2215 res.append(l)
2217 2216 level = newlevel
2218 2217 return '\n'.join(res) + '\n'
2219 2218
2220 2219 def runlines(self, lines, clean=False):
2221 2220 """Run a string of one or more lines of source.
2222 2221
2223 2222 This method is capable of running a string containing multiple source
2224 2223 lines, as if they had been entered at the IPython prompt. Since it
2225 2224 exposes IPython's processing machinery, the given strings can contain
2226 2225 magic calls (%magic), special shell access (!cmd), etc.
2227 2226 """
2228 2227
2229 2228 if isinstance(lines, (list, tuple)):
2230 2229 lines = '\n'.join(lines)
2231 2230
2232 2231 if clean:
2233 2232 lines = self.cleanup_ipy_script(lines)
2234 2233
2235 2234 # We must start with a clean buffer, in case this is run from an
2236 2235 # interactive IPython session (via a magic, for example).
2237 2236 self.resetbuffer()
2238 2237 lines = lines.splitlines()
2239 2238 more = 0
2240 2239
2241 2240 with self.builtin_trap:
2242 2241 for line in lines:
2243 2242 # skip blank lines so we don't mess up the prompt counter, but do
2244 2243 # NOT skip even a blank line if we are in a code block (more is
2245 2244 # true)
2246 2245
2247 2246 if line or more:
2248 2247 # push to raw history, so hist line numbers stay in sync
2249 2248 self.input_hist_raw.append("# " + line + "\n")
2250 2249 more = self.push_line(self.prefilter(line,more))
2251 2250 # IPython's runsource returns None if there was an error
2252 2251 # compiling the code. This allows us to stop processing right
2253 2252 # away, so the user gets the error message at the right place.
2254 2253 if more is None:
2255 2254 break
2256 2255 else:
2257 2256 self.input_hist_raw.append("\n")
2258 2257 # final newline in case the input didn't have it, so that the code
2259 2258 # actually does get executed
2260 2259 if more:
2261 2260 self.push_line('\n')
2262 2261
2263 2262 def runsource(self, source, filename='<input>', symbol='single'):
2264 2263 """Compile and run some source in the interpreter.
2265 2264
2266 2265 Arguments are as for compile_command().
2267 2266
2268 2267 One several things can happen:
2269 2268
2270 2269 1) The input is incorrect; compile_command() raised an
2271 2270 exception (SyntaxError or OverflowError). A syntax traceback
2272 2271 will be printed by calling the showsyntaxerror() method.
2273 2272
2274 2273 2) The input is incomplete, and more input is required;
2275 2274 compile_command() returned None. Nothing happens.
2276 2275
2277 2276 3) The input is complete; compile_command() returned a code
2278 2277 object. The code is executed by calling self.runcode() (which
2279 2278 also handles run-time exceptions, except for SystemExit).
2280 2279
2281 2280 The return value is:
2282 2281
2283 2282 - True in case 2
2284 2283
2285 2284 - False in the other cases, unless an exception is raised, where
2286 2285 None is returned instead. This can be used by external callers to
2287 2286 know whether to continue feeding input or not.
2288 2287
2289 2288 The return value can be used to decide whether to use sys.ps1 or
2290 2289 sys.ps2 to prompt the next line."""
2291 2290
2292 2291 # if the source code has leading blanks, add 'if 1:\n' to it
2293 2292 # this allows execution of indented pasted code. It is tempting
2294 2293 # to add '\n' at the end of source to run commands like ' a=1'
2295 2294 # directly, but this fails for more complicated scenarios
2296 2295 source=source.encode(self.stdin_encoding)
2297 2296 if source[:1] in [' ', '\t']:
2298 2297 source = 'if 1:\n%s' % source
2299 2298
2300 2299 try:
2301 2300 code = self.compile(source,filename,symbol)
2302 2301 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2303 2302 # Case 1
2304 2303 self.showsyntaxerror(filename)
2305 2304 return None
2306 2305
2307 2306 if code is None:
2308 2307 # Case 2
2309 2308 return True
2310 2309
2311 2310 # Case 3
2312 2311 # We store the code object so that threaded shells and
2313 2312 # custom exception handlers can access all this info if needed.
2314 2313 # The source corresponding to this can be obtained from the
2315 2314 # buffer attribute as '\n'.join(self.buffer).
2316 2315 self.code_to_run = code
2317 2316 # now actually execute the code object
2318 2317 if self.runcode(code) == 0:
2319 2318 return False
2320 2319 else:
2321 2320 return None
2322 2321
2323 2322 def runcode(self,code_obj):
2324 2323 """Execute a code object.
2325 2324
2326 2325 When an exception occurs, self.showtraceback() is called to display a
2327 2326 traceback.
2328 2327
2329 2328 Return value: a flag indicating whether the code to be run completed
2330 2329 successfully:
2331 2330
2332 2331 - 0: successful execution.
2333 2332 - 1: an error occurred.
2334 2333 """
2335 2334
2336 2335 # Set our own excepthook in case the user code tries to call it
2337 2336 # directly, so that the IPython crash handler doesn't get triggered
2338 2337 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2339 2338
2340 2339 # we save the original sys.excepthook in the instance, in case config
2341 2340 # code (such as magics) needs access to it.
2342 2341 self.sys_excepthook = old_excepthook
2343 2342 outflag = 1 # happens in more places, so it's easier as default
2344 2343 try:
2345 2344 try:
2346 2345 self.hooks.pre_runcode_hook()
2347 2346 exec code_obj in self.user_global_ns, self.user_ns
2348 2347 finally:
2349 2348 # Reset our crash handler in place
2350 2349 sys.excepthook = old_excepthook
2351 2350 except SystemExit:
2352 2351 self.resetbuffer()
2353 2352 self.showtraceback()
2354 2353 warn("Type %exit or %quit to exit IPython "
2355 2354 "(%Exit or %Quit do so unconditionally).",level=1)
2356 2355 except self.custom_exceptions:
2357 2356 etype,value,tb = sys.exc_info()
2358 2357 self.CustomTB(etype,value,tb)
2359 2358 except:
2360 2359 self.showtraceback()
2361 2360 else:
2362 2361 outflag = 0
2363 2362 if softspace(sys.stdout, 0):
2364 2363 print
2365 2364 # Flush out code object which has been run (and source)
2366 2365 self.code_to_run = None
2367 2366 return outflag
2368 2367
2369 2368 def push_line(self, line):
2370 2369 """Push a line to the interpreter.
2371 2370
2372 2371 The line should not have a trailing newline; it may have
2373 2372 internal newlines. The line is appended to a buffer and the
2374 2373 interpreter's runsource() method is called with the
2375 2374 concatenated contents of the buffer as source. If this
2376 2375 indicates that the command was executed or invalid, the buffer
2377 2376 is reset; otherwise, the command is incomplete, and the buffer
2378 2377 is left as it was after the line was appended. The return
2379 2378 value is 1 if more input is required, 0 if the line was dealt
2380 2379 with in some way (this is the same as runsource()).
2381 2380 """
2382 2381
2383 2382 # autoindent management should be done here, and not in the
2384 2383 # interactive loop, since that one is only seen by keyboard input. We
2385 2384 # need this done correctly even for code run via runlines (which uses
2386 2385 # push).
2387 2386
2388 2387 #print 'push line: <%s>' % line # dbg
2389 2388 for subline in line.splitlines():
2390 2389 self.autoindent_update(subline)
2391 2390 self.buffer.append(line)
2392 2391 more = self.runsource('\n'.join(self.buffer), self.filename)
2393 2392 if not more:
2394 2393 self.resetbuffer()
2395 2394 return more
2396 2395
2397 2396 def split_user_input(self, line):
2398 2397 # This is really a hold-over to support ipapi and some extensions
2399 2398 return prefilter.splitUserInput(line)
2400 2399
2401 2400 def resetbuffer(self):
2402 2401 """Reset the input buffer."""
2403 2402 self.buffer[:] = []
2404 2403
2405 2404 def raw_input(self,prompt='',continue_prompt=False):
2406 2405 """Write a prompt and read a line.
2407 2406
2408 2407 The returned line does not include the trailing newline.
2409 2408 When the user enters the EOF key sequence, EOFError is raised.
2410 2409
2411 2410 Optional inputs:
2412 2411
2413 2412 - prompt(''): a string to be printed to prompt the user.
2414 2413
2415 2414 - continue_prompt(False): whether this line is the first one or a
2416 2415 continuation in a sequence of inputs.
2417 2416 """
2418 2417
2419 2418 # Code run by the user may have modified the readline completer state.
2420 2419 # We must ensure that our completer is back in place.
2421 2420 if self.has_readline:
2422 2421 self.set_completer()
2423 2422
2424 2423 try:
2425 2424 line = raw_input_original(prompt).decode(self.stdin_encoding)
2426 2425 except ValueError:
2427 2426 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2428 2427 " or sys.stdout.close()!\nExiting IPython!")
2429 2428 self.ask_exit()
2430 2429 return ""
2431 2430
2432 2431 # Try to be reasonably smart about not re-indenting pasted input more
2433 2432 # than necessary. We do this by trimming out the auto-indent initial
2434 2433 # spaces, if the user's actual input started itself with whitespace.
2435 2434 #debugx('self.buffer[-1]')
2436 2435
2437 2436 if self.autoindent:
2438 2437 if num_ini_spaces(line) > self.indent_current_nsp:
2439 2438 line = line[self.indent_current_nsp:]
2440 2439 self.indent_current_nsp = 0
2441 2440
2442 2441 # store the unfiltered input before the user has any chance to modify
2443 2442 # it.
2444 2443 if line.strip():
2445 2444 if continue_prompt:
2446 2445 self.input_hist_raw[-1] += '%s\n' % line
2447 2446 if self.has_readline: # and some config option is set?
2448 2447 try:
2449 2448 histlen = self.readline.get_current_history_length()
2450 2449 if histlen > 1:
2451 2450 newhist = self.input_hist_raw[-1].rstrip()
2452 2451 self.readline.remove_history_item(histlen-1)
2453 2452 self.readline.replace_history_item(histlen-2,
2454 2453 newhist.encode(self.stdin_encoding))
2455 2454 except AttributeError:
2456 2455 pass # re{move,place}_history_item are new in 2.4.
2457 2456 else:
2458 2457 self.input_hist_raw.append('%s\n' % line)
2459 2458 # only entries starting at first column go to shadow history
2460 2459 if line.lstrip() == line:
2461 2460 self.shadowhist.add(line.strip())
2462 2461 elif not continue_prompt:
2463 2462 self.input_hist_raw.append('\n')
2464 2463 try:
2465 2464 lineout = self.prefilter(line,continue_prompt)
2466 2465 except:
2467 2466 # blanket except, in case a user-defined prefilter crashes, so it
2468 2467 # can't take all of ipython with it.
2469 2468 self.showtraceback()
2470 2469 return ''
2471 2470 else:
2472 2471 return lineout
2473 2472
2474 2473 def _prefilter(self, line, continue_prompt):
2475 2474 """Calls different preprocessors, depending on the form of line."""
2476 2475
2477 2476 # All handlers *must* return a value, even if it's blank ('').
2478 2477
2479 2478 # Lines are NOT logged here. Handlers should process the line as
2480 2479 # needed, update the cache AND log it (so that the input cache array
2481 2480 # stays synced).
2482 2481
2483 2482 #.....................................................................
2484 2483 # Code begins
2485 2484
2486 2485 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2487 2486
2488 2487 # save the line away in case we crash, so the post-mortem handler can
2489 2488 # record it
2490 2489 self._last_input_line = line
2491 2490
2492 2491 #print '***line: <%s>' % line # dbg
2493 2492
2494 2493 if not line:
2495 2494 # Return immediately on purely empty lines, so that if the user
2496 2495 # previously typed some whitespace that started a continuation
2497 2496 # prompt, he can break out of that loop with just an empty line.
2498 2497 # This is how the default python prompt works.
2499 2498
2500 2499 # Only return if the accumulated input buffer was just whitespace!
2501 2500 if ''.join(self.buffer).isspace():
2502 2501 self.buffer[:] = []
2503 2502 return ''
2504 2503
2505 2504 line_info = prefilter.LineInfo(line, continue_prompt)
2506 2505
2507 2506 # the input history needs to track even empty lines
2508 2507 stripped = line.strip()
2509 2508
2510 2509 if not stripped:
2511 2510 if not continue_prompt:
2512 2511 self.outputcache.prompt_count -= 1
2513 2512 return self.handle_normal(line_info)
2514 2513
2515 2514 # print '***cont',continue_prompt # dbg
2516 2515 # special handlers are only allowed for single line statements
2517 2516 if continue_prompt and not self.multi_line_specials:
2518 2517 return self.handle_normal(line_info)
2519 2518
2520 2519
2521 2520 # See whether any pre-existing handler can take care of it
2522 2521 rewritten = self.hooks.input_prefilter(stripped)
2523 2522 if rewritten != stripped: # ok, some prefilter did something
2524 2523 rewritten = line_info.pre + rewritten # add indentation
2525 2524 return self.handle_normal(prefilter.LineInfo(rewritten,
2526 2525 continue_prompt))
2527 2526
2528 2527 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2529 2528
2530 2529 return prefilter.prefilter(line_info, self)
2531 2530
2532 2531
2533 2532 def _prefilter_dumb(self, line, continue_prompt):
2534 2533 """simple prefilter function, for debugging"""
2535 2534 return self.handle_normal(line,continue_prompt)
2536 2535
2537 2536
2538 2537 def multiline_prefilter(self, line, continue_prompt):
2539 2538 """ Run _prefilter for each line of input
2540 2539
2541 2540 Covers cases where there are multiple lines in the user entry,
2542 2541 which is the case when the user goes back to a multiline history
2543 2542 entry and presses enter.
2544 2543
2545 2544 """
2546 2545 out = []
2547 2546 for l in line.rstrip('\n').split('\n'):
2548 2547 out.append(self._prefilter(l, continue_prompt))
2549 2548 return '\n'.join(out)
2550 2549
2551 2550 # Set the default prefilter() function (this can be user-overridden)
2552 2551 prefilter = multiline_prefilter
2553 2552
2554 2553 def handle_normal(self,line_info):
2555 2554 """Handle normal input lines. Use as a template for handlers."""
2556 2555
2557 2556 # With autoindent on, we need some way to exit the input loop, and I
2558 2557 # don't want to force the user to have to backspace all the way to
2559 2558 # clear the line. The rule will be in this case, that either two
2560 2559 # lines of pure whitespace in a row, or a line of pure whitespace but
2561 2560 # of a size different to the indent level, will exit the input loop.
2562 2561 line = line_info.line
2563 2562 continue_prompt = line_info.continue_prompt
2564 2563
2565 2564 if (continue_prompt and self.autoindent and line.isspace() and
2566 2565 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2567 2566 (self.buffer[-1]).isspace() )):
2568 2567 line = ''
2569 2568
2570 2569 self.log(line,line,continue_prompt)
2571 2570 return line
2572 2571
2573 2572 def handle_alias(self,line_info):
2574 2573 """Handle alias input lines. """
2575 2574 tgt = self.alias_table[line_info.iFun]
2576 2575 # print "=>",tgt #dbg
2577 2576 if callable(tgt):
2578 2577 if '$' in line_info.line:
2579 2578 call_meth = '(_ip, _ip.var_expand(%s))'
2580 2579 else:
2581 2580 call_meth = '(_ip,%s)'
2582 2581 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2583 2582 line_info.iFun,
2584 2583 make_quoted_expr(line_info.line))
2585 2584 else:
2586 2585 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2587 2586
2588 2587 # pre is needed, because it carries the leading whitespace. Otherwise
2589 2588 # aliases won't work in indented sections.
2590 2589 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2591 2590 make_quoted_expr( transformed ))
2592 2591
2593 2592 self.log(line_info.line,line_out,line_info.continue_prompt)
2594 2593 #print 'line out:',line_out # dbg
2595 2594 return line_out
2596 2595
2597 2596 def handle_shell_escape(self, line_info):
2598 2597 """Execute the line in a shell, empty return value"""
2599 2598 #print 'line in :', `line` # dbg
2600 2599 line = line_info.line
2601 2600 if line.lstrip().startswith('!!'):
2602 2601 # rewrite LineInfo's line, iFun and theRest to properly hold the
2603 2602 # call to %sx and the actual command to be executed, so
2604 2603 # handle_magic can work correctly. Note that this works even if
2605 2604 # the line is indented, so it handles multi_line_specials
2606 2605 # properly.
2607 2606 new_rest = line.lstrip()[2:]
2608 2607 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2609 2608 line_info.iFun = 'sx'
2610 2609 line_info.theRest = new_rest
2611 2610 return self.handle_magic(line_info)
2612 2611 else:
2613 2612 cmd = line.lstrip().lstrip('!')
2614 2613 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2615 2614 make_quoted_expr(cmd))
2616 2615 # update cache/log and return
2617 2616 self.log(line,line_out,line_info.continue_prompt)
2618 2617 return line_out
2619 2618
2620 2619 def handle_magic(self, line_info):
2621 2620 """Execute magic functions."""
2622 2621 iFun = line_info.iFun
2623 2622 theRest = line_info.theRest
2624 2623 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2625 2624 make_quoted_expr(iFun + " " + theRest))
2626 2625 self.log(line_info.line,cmd,line_info.continue_prompt)
2627 2626 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2628 2627 return cmd
2629 2628
2630 2629 def handle_auto(self, line_info):
2631 2630 """Hande lines which can be auto-executed, quoting if requested."""
2632 2631
2633 2632 line = line_info.line
2634 2633 iFun = line_info.iFun
2635 2634 theRest = line_info.theRest
2636 2635 pre = line_info.pre
2637 2636 continue_prompt = line_info.continue_prompt
2638 2637 obj = line_info.ofind(self)['obj']
2639 2638
2640 2639 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2641 2640
2642 2641 # This should only be active for single-line input!
2643 2642 if continue_prompt:
2644 2643 self.log(line,line,continue_prompt)
2645 2644 return line
2646 2645
2647 2646 force_auto = isinstance(obj, IPyAutocall)
2648 2647 auto_rewrite = True
2649 2648
2650 2649 if pre == self.ESC_QUOTE:
2651 2650 # Auto-quote splitting on whitespace
2652 2651 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2653 2652 elif pre == self.ESC_QUOTE2:
2654 2653 # Auto-quote whole string
2655 2654 newcmd = '%s("%s")' % (iFun,theRest)
2656 2655 elif pre == self.ESC_PAREN:
2657 2656 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2658 2657 else:
2659 2658 # Auto-paren.
2660 2659 # We only apply it to argument-less calls if the autocall
2661 2660 # parameter is set to 2. We only need to check that autocall is <
2662 2661 # 2, since this function isn't called unless it's at least 1.
2663 2662 if not theRest and (self.autocall < 2) and not force_auto:
2664 2663 newcmd = '%s %s' % (iFun,theRest)
2665 2664 auto_rewrite = False
2666 2665 else:
2667 2666 if not force_auto and theRest.startswith('['):
2668 2667 if hasattr(obj,'__getitem__'):
2669 2668 # Don't autocall in this case: item access for an object
2670 2669 # which is BOTH callable and implements __getitem__.
2671 2670 newcmd = '%s %s' % (iFun,theRest)
2672 2671 auto_rewrite = False
2673 2672 else:
2674 2673 # if the object doesn't support [] access, go ahead and
2675 2674 # autocall
2676 2675 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2677 2676 elif theRest.endswith(';'):
2678 2677 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2679 2678 else:
2680 2679 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2681 2680
2682 2681 if auto_rewrite:
2683 2682 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2684 2683
2685 2684 try:
2686 2685 # plain ascii works better w/ pyreadline, on some machines, so
2687 2686 # we use it and only print uncolored rewrite if we have unicode
2688 2687 rw = str(rw)
2689 2688 print >>Term.cout, rw
2690 2689 except UnicodeEncodeError:
2691 2690 print "-------------->" + newcmd
2692 2691
2693 2692 # log what is now valid Python, not the actual user input (without the
2694 2693 # final newline)
2695 2694 self.log(line,newcmd,continue_prompt)
2696 2695 return newcmd
2697 2696
2698 2697 def handle_help(self, line_info):
2699 2698 """Try to get some help for the object.
2700 2699
2701 2700 obj? or ?obj -> basic information.
2702 2701 obj?? or ??obj -> more details.
2703 2702 """
2704 2703
2705 2704 line = line_info.line
2706 2705 # We need to make sure that we don't process lines which would be
2707 2706 # otherwise valid python, such as "x=1 # what?"
2708 2707 try:
2709 2708 codeop.compile_command(line)
2710 2709 except SyntaxError:
2711 2710 # We should only handle as help stuff which is NOT valid syntax
2712 2711 if line[0]==self.ESC_HELP:
2713 2712 line = line[1:]
2714 2713 elif line[-1]==self.ESC_HELP:
2715 2714 line = line[:-1]
2716 2715 self.log(line,'#?'+line,line_info.continue_prompt)
2717 2716 if line:
2718 2717 #print 'line:<%r>' % line # dbg
2719 2718 self.magic_pinfo(line)
2720 2719 else:
2721 2720 page(self.usage,screen_lines=self.usable_screen_length)
2722 2721 return '' # Empty string is needed here!
2723 2722 except:
2724 2723 # Pass any other exceptions through to the normal handler
2725 2724 return self.handle_normal(line_info)
2726 2725 else:
2727 2726 # If the code compiles ok, we should handle it normally
2728 2727 return self.handle_normal(line_info)
2729 2728
2730 2729 def handle_emacs(self, line_info):
2731 2730 """Handle input lines marked by python-mode."""
2732 2731
2733 2732 # Currently, nothing is done. Later more functionality can be added
2734 2733 # here if needed.
2735 2734
2736 2735 # The input cache shouldn't be updated
2737 2736 return line_info.line
2738 2737
2739 2738 def var_expand(self,cmd,depth=0):
2740 2739 """Expand python variables in a string.
2741 2740
2742 2741 The depth argument indicates how many frames above the caller should
2743 2742 be walked to look for the local namespace where to expand variables.
2744 2743
2745 2744 The global namespace for expansion is always the user's interactive
2746 2745 namespace.
2747 2746 """
2748 2747
2749 2748 return str(ItplNS(cmd,
2750 2749 self.user_ns, # globals
2751 2750 # Skip our own frame in searching for locals:
2752 2751 sys._getframe(depth+1).f_locals # locals
2753 2752 ))
2754 2753
2755 2754 def mktempfile(self,data=None):
2756 2755 """Make a new tempfile and return its filename.
2757 2756
2758 2757 This makes a call to tempfile.mktemp, but it registers the created
2759 2758 filename internally so ipython cleans it up at exit time.
2760 2759
2761 2760 Optional inputs:
2762 2761
2763 2762 - data(None): if data is given, it gets written out to the temp file
2764 2763 immediately, and the file is closed again."""
2765 2764
2766 2765 filename = tempfile.mktemp('.py','ipython_edit_')
2767 2766 self.tempfiles.append(filename)
2768 2767
2769 2768 if data:
2770 2769 tmp_file = open(filename,'w')
2771 2770 tmp_file.write(data)
2772 2771 tmp_file.close()
2773 2772 return filename
2774 2773
2775 2774 def write(self,data):
2776 2775 """Write a string to the default output"""
2777 2776 Term.cout.write(data)
2778 2777
2779 2778 def write_err(self,data):
2780 2779 """Write a string to the default error output"""
2781 2780 Term.cerr.write(data)
2782 2781
2783 2782 def ask_exit(self):
2784 2783 """ Call for exiting. Can be overiden and used as a callback. """
2785 2784 self.exit_now = True
2786 2785
2787 2786 def exit(self):
2788 2787 """Handle interactive exit.
2789 2788
2790 2789 This method calls the ask_exit callback."""
2791 2790 if self.confirm_exit:
2792 2791 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2793 2792 self.ask_exit()
2794 2793 else:
2795 2794 self.ask_exit()
2796 2795
2797 2796 def safe_execfile(self,fname,*where,**kw):
2798 2797 """A safe version of the builtin execfile().
2799 2798
2800 2799 This version will never throw an exception, and knows how to handle
2801 2800 ipython logs as well.
2802 2801
2803 2802 :Parameters:
2804 2803 fname : string
2805 2804 Name of the file to be executed.
2806 2805
2807 2806 where : tuple
2808 2807 One or two namespaces, passed to execfile() as (globals,locals).
2809 2808 If only one is given, it is passed as both.
2810 2809
2811 2810 :Keywords:
2812 2811 islog : boolean (False)
2813 2812
2814 2813 quiet : boolean (True)
2815 2814
2816 2815 exit_ignore : boolean (False)
2817 2816 """
2818 2817
2819 2818 def syspath_cleanup():
2820 2819 """Internal cleanup routine for sys.path."""
2821 2820 if add_dname:
2822 2821 try:
2823 2822 sys.path.remove(dname)
2824 2823 except ValueError:
2825 2824 # For some reason the user has already removed it, ignore.
2826 2825 pass
2827 2826
2828 2827 fname = os.path.expanduser(fname)
2829 2828
2830 2829 # Find things also in current directory. This is needed to mimic the
2831 2830 # behavior of running a script from the system command line, where
2832 2831 # Python inserts the script's directory into sys.path
2833 2832 dname = os.path.dirname(os.path.abspath(fname))
2834 2833 add_dname = False
2835 2834 if dname not in sys.path:
2836 2835 sys.path.insert(0,dname)
2837 2836 add_dname = True
2838 2837
2839 2838 try:
2840 2839 xfile = open(fname)
2841 2840 except:
2842 2841 print >> Term.cerr, \
2843 2842 'Could not open file <%s> for safe execution.' % fname
2844 2843 syspath_cleanup()
2845 2844 return None
2846 2845
2847 2846 kw.setdefault('islog',0)
2848 2847 kw.setdefault('quiet',1)
2849 2848 kw.setdefault('exit_ignore',0)
2850 2849
2851 2850 first = xfile.readline()
2852 2851 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2853 2852 xfile.close()
2854 2853 # line by line execution
2855 2854 if first.startswith(loghead) or kw['islog']:
2856 2855 print 'Loading log file <%s> one line at a time...' % fname
2857 2856 if kw['quiet']:
2858 2857 stdout_save = sys.stdout
2859 2858 sys.stdout = StringIO.StringIO()
2860 2859 try:
2861 2860 globs,locs = where[0:2]
2862 2861 except:
2863 2862 try:
2864 2863 globs = locs = where[0]
2865 2864 except:
2866 2865 globs = locs = globals()
2867 2866 badblocks = []
2868 2867
2869 2868 # we also need to identify indented blocks of code when replaying
2870 2869 # logs and put them together before passing them to an exec
2871 2870 # statement. This takes a bit of regexp and look-ahead work in the
2872 2871 # file. It's easiest if we swallow the whole thing in memory
2873 2872 # first, and manually walk through the lines list moving the
2874 2873 # counter ourselves.
2875 2874 indent_re = re.compile('\s+\S')
2876 2875 xfile = open(fname)
2877 2876 filelines = xfile.readlines()
2878 2877 xfile.close()
2879 2878 nlines = len(filelines)
2880 2879 lnum = 0
2881 2880 while lnum < nlines:
2882 2881 line = filelines[lnum]
2883 2882 lnum += 1
2884 2883 # don't re-insert logger status info into cache
2885 2884 if line.startswith('#log#'):
2886 2885 continue
2887 2886 else:
2888 2887 # build a block of code (maybe a single line) for execution
2889 2888 block = line
2890 2889 try:
2891 2890 next = filelines[lnum] # lnum has already incremented
2892 2891 except:
2893 2892 next = None
2894 2893 while next and indent_re.match(next):
2895 2894 block += next
2896 2895 lnum += 1
2897 2896 try:
2898 2897 next = filelines[lnum]
2899 2898 except:
2900 2899 next = None
2901 2900 # now execute the block of one or more lines
2902 2901 try:
2903 2902 exec block in globs,locs
2904 2903 except SystemExit:
2905 2904 pass
2906 2905 except:
2907 2906 badblocks.append(block.rstrip())
2908 2907 if kw['quiet']: # restore stdout
2909 2908 sys.stdout.close()
2910 2909 sys.stdout = stdout_save
2911 2910 print 'Finished replaying log file <%s>' % fname
2912 2911 if badblocks:
2913 2912 print >> sys.stderr, ('\nThe following lines/blocks in file '
2914 2913 '<%s> reported errors:' % fname)
2915 2914
2916 2915 for badline in badblocks:
2917 2916 print >> sys.stderr, badline
2918 2917 else: # regular file execution
2919 2918 try:
2920 2919 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2921 2920 # Work around a bug in Python for Windows. The bug was
2922 2921 # fixed in in Python 2.5 r54159 and 54158, but that's still
2923 2922 # SVN Python as of March/07. For details, see:
2924 2923 # http://projects.scipy.org/ipython/ipython/ticket/123
2925 2924 try:
2926 2925 globs,locs = where[0:2]
2927 2926 except:
2928 2927 try:
2929 2928 globs = locs = where[0]
2930 2929 except:
2931 2930 globs = locs = globals()
2932 2931 exec file(fname) in globs,locs
2933 2932 else:
2934 2933 execfile(fname,*where)
2935 2934 except SyntaxError:
2936 2935 self.showsyntaxerror()
2937 2936 warn('Failure executing file: <%s>' % fname)
2938 2937 except SystemExit,status:
2939 2938 # Code that correctly sets the exit status flag to success (0)
2940 2939 # shouldn't be bothered with a traceback. Note that a plain
2941 2940 # sys.exit() does NOT set the message to 0 (it's empty) so that
2942 2941 # will still get a traceback. Note that the structure of the
2943 2942 # SystemExit exception changed between Python 2.4 and 2.5, so
2944 2943 # the checks must be done in a version-dependent way.
2945 2944 show = False
2946 2945
2947 2946 if sys.version_info[:2] > (2,5):
2948 2947 if status.message!=0 and not kw['exit_ignore']:
2949 2948 show = True
2950 2949 else:
2951 2950 if status.code and not kw['exit_ignore']:
2952 2951 show = True
2953 2952 if show:
2954 2953 self.showtraceback()
2955 2954 warn('Failure executing file: <%s>' % fname)
2956 2955 except:
2957 2956 self.showtraceback()
2958 2957 warn('Failure executing file: <%s>' % fname)
2959 2958
2960 2959 syspath_cleanup()
2961 2960
2962 2961 #************************* end of file <iplib.py> *****************************
@@ -1,150 +1,150 b''
1 1 # encoding: utf-8
2 2
3 3 """A class for handling client connections to the controller."""
4 4
5 5 __docformat__ = "restructuredtext en"
6 6
7 7 #-------------------------------------------------------------------------------
8 8 # Copyright (C) 2008 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-------------------------------------------------------------------------------
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Imports
16 16 #-------------------------------------------------------------------------------
17 17
18 18 from twisted.internet import defer
19 19
20 20 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
21 21
22 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 24 from IPython.kernel.fcutil import find_furl
25 25
26 26 co = kernel_config_manager.get_config_obj()
27 27 client_co = co['client']
28 28
29 29 #-------------------------------------------------------------------------------
30 30 # The ClientConnector class
31 31 #-------------------------------------------------------------------------------
32 32
33 33 class ClientConnector(object):
34 34 """
35 35 This class gets remote references from furls and returns the wrapped clients.
36 36
37 37 This class is also used in `client.py` and `asyncclient.py` to create
38 38 a single per client-process Tub.
39 39 """
40 40
41 41 def __init__(self):
42 42 self._remote_refs = {}
43 43 self.tub = Tub()
44 44 self.tub.startService()
45 45
46 46 def get_reference(self, furl_or_file):
47 47 """
48 48 Get a remote reference using a furl or a file containing a furl.
49 49
50 50 Remote references are cached locally so once a remote reference
51 51 has been retrieved for a given furl, the cached version is
52 52 returned.
53 53
54 54 :Parameters:
55 55 furl_or_file : str
56 56 A furl or a filename containing a furl
57 57
58 58 :Returns:
59 59 A deferred to a remote reference
60 60 """
61 61 furl = find_furl(furl_or_file)
62 62 if furl in self._remote_refs:
63 63 d = defer.succeed(self._remote_refs[furl])
64 64 else:
65 65 d = self.tub.getReference(furl)
66 66 d.addCallback(self.save_ref, furl)
67 67 return d
68 68
69 69 def save_ref(self, ref, furl):
70 70 """
71 71 Cache a remote reference by its furl.
72 72 """
73 73 self._remote_refs[furl] = ref
74 74 return ref
75 75
76 76 def get_task_client(self, furl_or_file=''):
77 77 """
78 78 Get the task controller client.
79 79
80 80 This method is a simple wrapper around `get_client` that allow
81 81 `furl_or_file` to be empty, in which case, the furls is taken
82 82 from the default furl file given in the configuration.
83 83
84 84 :Parameters:
85 85 furl_or_file : str
86 86 A furl or a filename containing a furl. If empty, the
87 87 default furl_file will be used
88 88
89 89 :Returns:
90 90 A deferred to the actual client class
91 91 """
92 92 task_co = client_co['client_interfaces']['task']
93 93 if furl_or_file:
94 94 ff = furl_or_file
95 95 else:
96 96 ff = task_co['furl_file']
97 97 return self.get_client(ff)
98 98
99 99 def get_multiengine_client(self, furl_or_file=''):
100 100 """
101 101 Get the multiengine controller client.
102 102
103 103 This method is a simple wrapper around `get_client` that allow
104 104 `furl_or_file` to be empty, in which case, the furls is taken
105 105 from the default furl file given in the configuration.
106 106
107 107 :Parameters:
108 108 furl_or_file : str
109 109 A furl or a filename containing a furl. If empty, the
110 110 default furl_file will be used
111 111
112 112 :Returns:
113 113 A deferred to the actual client class
114 114 """
115 115 task_co = client_co['client_interfaces']['multiengine']
116 116 if furl_or_file:
117 117 ff = furl_or_file
118 118 else:
119 119 ff = task_co['furl_file']
120 120 return self.get_client(ff)
121 121
122 122 def get_client(self, furl_or_file):
123 123 """
124 124 Get a remote reference and wrap it in a client by furl.
125 125
126 126 This method first gets a remote reference and then calls its
127 127 `get_client_name` method to find the apprpriate client class
128 128 that should be used to wrap the remote reference.
129 129
130 130 :Parameters:
131 131 furl_or_file : str
132 132 A furl or a filename containing a furl
133 133
134 134 :Returns:
135 135 A deferred to the actual client class
136 136 """
137 137 furl = find_furl(furl_or_file)
138 138 d = self.get_reference(furl)
139 139 def wrap_remote_reference(rr):
140 140 d = rr.callRemote('get_client_name')
141 141 d.addCallback(lambda name: import_item(name))
142 142 def adapt(client_interface):
143 143 client = client_interface(rr)
144 144 client.tub = self.tub
145 145 return client
146 146 d.addCallback(adapt)
147 147
148 148 return d
149 149 d.addCallback(wrap_remote_reference)
150 150 return d
@@ -1,416 +1,416 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3
4 4 """The IPython controller."""
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 #-------------------------------------------------------------------------------
16 16 # Imports
17 17 #-------------------------------------------------------------------------------
18 18
19 19 # Python looks for an empty string at the beginning of sys.path to enable
20 20 # importing from the cwd.
21 21 import sys
22 22 sys.path.insert(0, '')
23 23
24 24 from optparse import OptionParser
25 25 import os
26 26 import time
27 27 import tempfile
28 28
29 29 from twisted.application import internet, service
30 30 from twisted.internet import reactor, error, defer
31 31 from twisted.python import log
32 32
33 33 from IPython.kernel.fcutil import Tub, UnauthenticatedTub, have_crypto
34 34
35 35 # from IPython.utils import growl
36 36 # growl.start("IPython1 Controller")
37 37
38 38 from IPython.kernel.error import SecurityError
39 39 from IPython.kernel import controllerservice
40 40 from IPython.kernel.fcutil import check_furl_file_security
41 41
42 42 # Create various ipython directories if they don't exist.
43 43 # This must be done before IPython.kernel.config is imported.
44 44 from IPython.core.oldusersetup import user_setup
45 45 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
46 46 if os.name == 'posix':
47 47 rc_suffix = ''
48 48 else:
49 49 rc_suffix = '.ini'
50 50 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
51 51 get_log_dir()
52 52 get_security_dir()
53 53
54 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 59 # Code
60 60 #-------------------------------------------------------------------------------
61 61
62 62 def get_temp_furlfile(filename):
63 63 return tempfile.mktemp(dir=os.path.dirname(filename),
64 64 prefix=os.path.basename(filename))
65 65
66 66 def make_tub(ip, port, secure, cert_file):
67 67 """
68 68 Create a listening tub given an ip, port, and cert_file location.
69 69
70 70 :Parameters:
71 71 ip : str
72 72 The ip address that the tub should listen on. Empty means all
73 73 port : int
74 74 The port that the tub should listen on. A value of 0 means
75 75 pick a random port
76 76 secure: boolean
77 77 Will the connection be secure (in the foolscap sense)
78 78 cert_file:
79 79 A filename of a file to be used for theSSL certificate
80 80 """
81 81 if secure:
82 82 if have_crypto:
83 83 tub = Tub(certFile=cert_file)
84 84 else:
85 85 raise SecurityError("""
86 86 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
87 87 Try running without security using 'ipcontroller -xy'.
88 88 """)
89 89 else:
90 90 tub = UnauthenticatedTub()
91 91
92 92 # Set the strport based on the ip and port and start listening
93 93 if ip == '':
94 94 strport = "tcp:%i" % port
95 95 else:
96 96 strport = "tcp:%i:interface=%s" % (port, ip)
97 97 listener = tub.listenOn(strport)
98 98
99 99 return tub, listener
100 100
101 101 def make_client_service(controller_service, config):
102 102 """
103 103 Create a service that will listen for clients.
104 104
105 105 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
106 106 registered with it.
107 107 """
108 108
109 109 # Now create the foolscap tub
110 110 ip = config['controller']['client_tub']['ip']
111 111 port = config['controller']['client_tub'].as_int('port')
112 112 location = config['controller']['client_tub']['location']
113 113 secure = config['controller']['client_tub']['secure']
114 114 cert_file = config['controller']['client_tub']['cert_file']
115 115 client_tub, client_listener = make_tub(ip, port, secure, cert_file)
116 116
117 117 # Set the location in the trivial case of localhost
118 118 if ip == 'localhost' or ip == '127.0.0.1':
119 119 location = "127.0.0.1"
120 120
121 121 if not secure:
122 122 log.msg("WARNING: you are running the controller with no client security")
123 123
124 124 def set_location_and_register():
125 125 """Set the location for the tub and return a deferred."""
126 126
127 127 def register(empty, ref, furl_file):
128 128 # We create and then move to make sure that when the file
129 129 # appears to other processes, the buffer has the flushed
130 130 # and the file has been closed
131 131 temp_furl_file = get_temp_furlfile(furl_file)
132 132 client_tub.registerReference(ref, furlFile=temp_furl_file)
133 133 os.rename(temp_furl_file, furl_file)
134 134
135 135 if location == '':
136 136 d = client_tub.setLocationAutomatically()
137 137 else:
138 138 d = defer.maybeDeferred(client_tub.setLocation, "%s:%i" % (location, client_listener.getPortnum()))
139 139
140 140 for ciname, ci in config['controller']['controller_interfaces'].iteritems():
141 141 log.msg("Adapting Controller to interface: %s" % ciname)
142 142 furl_file = ci['furl_file']
143 143 log.msg("Saving furl for interface [%s] to file: %s" % (ciname, furl_file))
144 144 check_furl_file_security(furl_file, secure)
145 145 adapted_controller = import_item(ci['controller_interface'])(controller_service)
146 146 d.addCallback(register, import_item(ci['fc_interface'])(adapted_controller),
147 147 furl_file=ci['furl_file'])
148 148
149 149 reactor.callWhenRunning(set_location_and_register)
150 150 return client_tub
151 151
152 152
153 153 def make_engine_service(controller_service, config):
154 154 """
155 155 Create a service that will listen for engines.
156 156
157 157 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
158 158 registered with it.
159 159 """
160 160
161 161 # Now create the foolscap tub
162 162 ip = config['controller']['engine_tub']['ip']
163 163 port = config['controller']['engine_tub'].as_int('port')
164 164 location = config['controller']['engine_tub']['location']
165 165 secure = config['controller']['engine_tub']['secure']
166 166 cert_file = config['controller']['engine_tub']['cert_file']
167 167 engine_tub, engine_listener = make_tub(ip, port, secure, cert_file)
168 168
169 169 # Set the location in the trivial case of localhost
170 170 if ip == 'localhost' or ip == '127.0.0.1':
171 171 location = "127.0.0.1"
172 172
173 173 if not secure:
174 174 log.msg("WARNING: you are running the controller with no engine security")
175 175
176 176 def set_location_and_register():
177 177 """Set the location for the tub and return a deferred."""
178 178
179 179 def register(empty, ref, furl_file):
180 180 # We create and then move to make sure that when the file
181 181 # appears to other processes, the buffer has the flushed
182 182 # and the file has been closed
183 183 temp_furl_file = get_temp_furlfile(furl_file)
184 184 engine_tub.registerReference(ref, furlFile=temp_furl_file)
185 185 os.rename(temp_furl_file, furl_file)
186 186
187 187 if location == '':
188 188 d = engine_tub.setLocationAutomatically()
189 189 else:
190 190 d = defer.maybeDeferred(engine_tub.setLocation, "%s:%i" % (location, engine_listener.getPortnum()))
191 191
192 192 furl_file = config['controller']['engine_furl_file']
193 193 engine_fc_interface = import_item(config['controller']['engine_fc_interface'])
194 194 log.msg("Saving furl for the engine to file: %s" % furl_file)
195 195 check_furl_file_security(furl_file, secure)
196 196 fc_controller = engine_fc_interface(controller_service)
197 197 d.addCallback(register, fc_controller, furl_file=furl_file)
198 198
199 199 reactor.callWhenRunning(set_location_and_register)
200 200 return engine_tub
201 201
202 202 def start_controller():
203 203 """
204 204 Start the controller by creating the service hierarchy and starting the reactor.
205 205
206 206 This method does the following:
207 207
208 208 * It starts the controller logging
209 209 * In execute an import statement for the controller
210 210 * It creates 2 `foolscap.Tub` instances for the client and the engines
211 211 and registers `foolscap.Referenceables` with the tubs to expose the
212 212 controller to engines and clients.
213 213 """
214 214 config = kernel_config_manager.get_config_obj()
215 215
216 216 # Start logging
217 217 logfile = config['controller']['logfile']
218 218 if logfile:
219 219 logfile = logfile + str(os.getpid()) + '.log'
220 220 try:
221 221 openLogFile = open(logfile, 'w')
222 222 except:
223 223 openLogFile = sys.stdout
224 224 else:
225 225 openLogFile = sys.stdout
226 226 log.startLogging(openLogFile)
227 227
228 228 # Execute any user defined import statements
229 229 cis = config['controller']['import_statement']
230 230 if cis:
231 231 try:
232 232 exec cis in globals(), locals()
233 233 except:
234 234 log.msg("Error running import_statement: %s" % cis)
235 235
236 236 # Delete old furl files unless the reuse_furls is set
237 237 reuse = config['controller']['reuse_furls']
238 238 if not reuse:
239 239 paths = (config['controller']['engine_furl_file'],
240 240 config['controller']['controller_interfaces']['task']['furl_file'],
241 241 config['controller']['controller_interfaces']['multiengine']['furl_file']
242 242 )
243 243 for p in paths:
244 244 if os.path.isfile(p):
245 245 os.remove(p)
246 246
247 247 # Create the service hierarchy
248 248 main_service = service.MultiService()
249 249 # The controller service
250 250 controller_service = controllerservice.ControllerService()
251 251 controller_service.setServiceParent(main_service)
252 252 # The client tub and all its refereceables
253 253 client_service = make_client_service(controller_service, config)
254 254 client_service.setServiceParent(main_service)
255 255 # The engine tub
256 256 engine_service = make_engine_service(controller_service, config)
257 257 engine_service.setServiceParent(main_service)
258 258 # Start the controller service and set things running
259 259 main_service.startService()
260 260 reactor.run()
261 261
262 262 def init_config():
263 263 """
264 264 Initialize the configuration using default and command line options.
265 265 """
266 266
267 267 parser = OptionParser("""ipcontroller [options]
268 268
269 269 Start an IPython controller.
270 270
271 271 Use the IPYTHONDIR environment variable to change your IPython directory
272 272 from the default of .ipython or _ipython. The log and security
273 273 subdirectories of your IPython directory will be used by this script
274 274 for log files and security files.""")
275 275
276 276 # Client related options
277 277 parser.add_option(
278 278 "--client-ip",
279 279 type="string",
280 280 dest="client_ip",
281 281 help="the IP address or hostname the controller will listen on for client connections"
282 282 )
283 283 parser.add_option(
284 284 "--client-port",
285 285 type="int",
286 286 dest="client_port",
287 287 help="the port the controller will listen on for client connections"
288 288 )
289 289 parser.add_option(
290 290 '--client-location',
291 291 type="string",
292 292 dest="client_location",
293 293 help="hostname or ip for clients to connect to"
294 294 )
295 295 parser.add_option(
296 296 "-x",
297 297 action="store_false",
298 298 dest="client_secure",
299 299 help="turn off all client security"
300 300 )
301 301 parser.add_option(
302 302 '--client-cert-file',
303 303 type="string",
304 304 dest="client_cert_file",
305 305 help="file to store the client SSL certificate"
306 306 )
307 307 parser.add_option(
308 308 '--task-furl-file',
309 309 type="string",
310 310 dest="task_furl_file",
311 311 help="file to store the FURL for task clients to connect with"
312 312 )
313 313 parser.add_option(
314 314 '--multiengine-furl-file',
315 315 type="string",
316 316 dest="multiengine_furl_file",
317 317 help="file to store the FURL for multiengine clients to connect with"
318 318 )
319 319 # Engine related options
320 320 parser.add_option(
321 321 "--engine-ip",
322 322 type="string",
323 323 dest="engine_ip",
324 324 help="the IP address or hostname the controller will listen on for engine connections"
325 325 )
326 326 parser.add_option(
327 327 "--engine-port",
328 328 type="int",
329 329 dest="engine_port",
330 330 help="the port the controller will listen on for engine connections"
331 331 )
332 332 parser.add_option(
333 333 '--engine-location',
334 334 type="string",
335 335 dest="engine_location",
336 336 help="hostname or ip for engines to connect to"
337 337 )
338 338 parser.add_option(
339 339 "-y",
340 340 action="store_false",
341 341 dest="engine_secure",
342 342 help="turn off all engine security"
343 343 )
344 344 parser.add_option(
345 345 '--engine-cert-file',
346 346 type="string",
347 347 dest="engine_cert_file",
348 348 help="file to store the engine SSL certificate"
349 349 )
350 350 parser.add_option(
351 351 '--engine-furl-file',
352 352 type="string",
353 353 dest="engine_furl_file",
354 354 help="file to store the FURL for engines to connect with"
355 355 )
356 356 parser.add_option(
357 357 "-l", "--logfile",
358 358 type="string",
359 359 dest="logfile",
360 360 help="log file name (default is stdout)"
361 361 )
362 362 parser.add_option(
363 363 "-r",
364 364 action="store_true",
365 365 dest="reuse_furls",
366 366 help="try to reuse all furl files"
367 367 )
368 368
369 369 (options, args) = parser.parse_args()
370 370
371 371 config = kernel_config_manager.get_config_obj()
372 372
373 373 # Update with command line options
374 374 if options.client_ip is not None:
375 375 config['controller']['client_tub']['ip'] = options.client_ip
376 376 if options.client_port is not None:
377 377 config['controller']['client_tub']['port'] = options.client_port
378 378 if options.client_location is not None:
379 379 config['controller']['client_tub']['location'] = options.client_location
380 380 if options.client_secure is not None:
381 381 config['controller']['client_tub']['secure'] = options.client_secure
382 382 if options.client_cert_file is not None:
383 383 config['controller']['client_tub']['cert_file'] = options.client_cert_file
384 384 if options.task_furl_file is not None:
385 385 config['controller']['controller_interfaces']['task']['furl_file'] = options.task_furl_file
386 386 if options.multiengine_furl_file is not None:
387 387 config['controller']['controller_interfaces']['multiengine']['furl_file'] = options.multiengine_furl_file
388 388 if options.engine_ip is not None:
389 389 config['controller']['engine_tub']['ip'] = options.engine_ip
390 390 if options.engine_port is not None:
391 391 config['controller']['engine_tub']['port'] = options.engine_port
392 392 if options.engine_location is not None:
393 393 config['controller']['engine_tub']['location'] = options.engine_location
394 394 if options.engine_secure is not None:
395 395 config['controller']['engine_tub']['secure'] = options.engine_secure
396 396 if options.engine_cert_file is not None:
397 397 config['controller']['engine_tub']['cert_file'] = options.engine_cert_file
398 398 if options.engine_furl_file is not None:
399 399 config['controller']['engine_furl_file'] = options.engine_furl_file
400 400 if options.reuse_furls is not None:
401 401 config['controller']['reuse_furls'] = options.reuse_furls
402 402
403 403 if options.logfile is not None:
404 404 config['controller']['logfile'] = options.logfile
405 405
406 406 kernel_config_manager.update_config_obj(config)
407 407
408 408 def main():
409 409 """
410 410 After creating the configuration information, start the controller.
411 411 """
412 412 init_config()
413 413 start_controller()
414 414
415 415 if __name__ == "__main__":
416 416 main()
@@ -1,193 +1,193 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3
4 4 """Start the IPython Engine."""
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 #-------------------------------------------------------------------------------
16 16 # Imports
17 17 #-------------------------------------------------------------------------------
18 18
19 19 # Python looks for an empty string at the beginning of sys.path to enable
20 20 # importing from the cwd.
21 21 import sys
22 22 sys.path.insert(0, '')
23 23
24 24 from optparse import OptionParser
25 25 import os
26 26
27 27 from twisted.application import service
28 28 from twisted.internet import reactor
29 29 from twisted.python import log
30 30
31 31 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
32 32
33 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 35 from IPython.kernel.engineservice import EngineService
36 36
37 37 # Create various ipython directories if they don't exist.
38 38 # This must be done before IPython.kernel.config is imported.
39 39 from IPython.core.oldusersetup import user_setup
40 40 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
41 41 if os.name == 'posix':
42 42 rc_suffix = ''
43 43 else:
44 44 rc_suffix = '.ini'
45 45 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
46 46 get_log_dir()
47 47 get_security_dir()
48 48
49 49 from IPython.kernel.config import config_manager as kernel_config_manager
50 50 from IPython.kernel.engineconnector import EngineConnector
51 51
52 52
53 53 #-------------------------------------------------------------------------------
54 54 # Code
55 55 #-------------------------------------------------------------------------------
56 56
57 57 def start_engine():
58 58 """
59 59 Start the engine, by creating it and starting the Twisted reactor.
60 60
61 61 This method does:
62 62
63 63 * If it exists, runs the `mpi_import_statement` to call `MPI_Init`
64 64 * Starts the engine logging
65 65 * Creates an IPython shell and wraps it in an `EngineService`
66 66 * Creates a `foolscap.Tub` to use in connecting to a controller.
67 67 * Uses the tub and the `EngineService` along with a Foolscap URL
68 68 (or FURL) to connect to the controller and register the engine
69 69 with the controller
70 70 """
71 71 kernel_config = kernel_config_manager.get_config_obj()
72 72 core_config = core_config_manager.get_config_obj()
73 73
74 74
75 75 # Execute the mpi import statement that needs to call MPI_Init
76 76 global mpi
77 77 mpikey = kernel_config['mpi']['default']
78 78 mpi_import_statement = kernel_config['mpi'].get(mpikey, None)
79 79 if mpi_import_statement is not None:
80 80 try:
81 81 exec mpi_import_statement in globals()
82 82 except:
83 83 mpi = None
84 84 else:
85 85 mpi = None
86 86
87 87 # Start logging
88 88 logfile = kernel_config['engine']['logfile']
89 89 if logfile:
90 90 logfile = logfile + str(os.getpid()) + '.log'
91 91 try:
92 92 openLogFile = open(logfile, 'w')
93 93 except:
94 94 openLogFile = sys.stdout
95 95 else:
96 96 openLogFile = sys.stdout
97 97 log.startLogging(openLogFile)
98 98
99 99 # Create the underlying shell class and EngineService
100 100 shell_class = import_item(core_config['shell']['shell_class'])
101 101 engine_service = EngineService(shell_class, mpi=mpi)
102 102 shell_import_statement = core_config['shell']['import_statement']
103 103 if shell_import_statement:
104 104 try:
105 105 engine_service.execute(shell_import_statement)
106 106 except:
107 107 log.msg("Error running import_statement: %s" % shell_import_statement)
108 108
109 109 # Create the service hierarchy
110 110 main_service = service.MultiService()
111 111 engine_service.setServiceParent(main_service)
112 112 tub_service = Tub()
113 113 tub_service.setServiceParent(main_service)
114 114 # This needs to be called before the connection is initiated
115 115 main_service.startService()
116 116
117 117 # This initiates the connection to the controller and calls
118 118 # register_engine to tell the controller we are ready to do work
119 119 engine_connector = EngineConnector(tub_service)
120 120 furl_file = kernel_config['engine']['furl_file']
121 121 log.msg("Using furl file: %s" % furl_file)
122 122
123 123 def call_connect(engine_service, furl_file):
124 124 d = engine_connector.connect_to_controller(engine_service, furl_file)
125 125 def handle_error(f):
126 126 # If this print statement is replaced by a log.err(f) I get
127 127 # an unhandled error, which makes no sense. I shouldn't have
128 128 # to use a print statement here. My only thought is that
129 129 # at the beginning of the process the logging is still starting up
130 130 print "error connecting to controller:", f.getErrorMessage()
131 131 reactor.callLater(0.1, reactor.stop)
132 132 d.addErrback(handle_error)
133 133
134 134 reactor.callWhenRunning(call_connect, engine_service, furl_file)
135 135 reactor.run()
136 136
137 137
138 138 def init_config():
139 139 """
140 140 Initialize the configuration using default and command line options.
141 141 """
142 142
143 143 parser = OptionParser("""ipengine [options]
144 144
145 145 Start an IPython engine.
146 146
147 147 Use the IPYTHONDIR environment variable to change your IPython directory
148 148 from the default of .ipython or _ipython. The log and security
149 149 subdirectories of your IPython directory will be used by this script
150 150 for log files and security files.""")
151 151
152 152 parser.add_option(
153 153 "--furl-file",
154 154 type="string",
155 155 dest="furl_file",
156 156 help="The filename containing the FURL of the controller"
157 157 )
158 158 parser.add_option(
159 159 "--mpi",
160 160 type="string",
161 161 dest="mpi",
162 162 help="How to enable MPI (mpi4py, pytrilinos, or empty string to disable)"
163 163 )
164 164 parser.add_option(
165 165 "-l",
166 166 "--logfile",
167 167 type="string",
168 168 dest="logfile",
169 169 help="log file name (default is stdout)"
170 170 )
171 171
172 172 (options, args) = parser.parse_args()
173 173
174 174 kernel_config = kernel_config_manager.get_config_obj()
175 175 # Now override with command line options
176 176 if options.furl_file is not None:
177 177 kernel_config['engine']['furl_file'] = options.furl_file
178 178 if options.logfile is not None:
179 179 kernel_config['engine']['logfile'] = options.logfile
180 180 if options.mpi is not None:
181 181 kernel_config['mpi']['default'] = options.mpi
182 182
183 183
184 184 def main():
185 185 """
186 186 After creating the configuration information, start the engine.
187 187 """
188 188 init_config()
189 189 start_engine()
190 190
191 191
192 192 if __name__ == "__main__":
193 193 main()
@@ -1,670 +1,687 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Tests for IPython.utils.traitlets.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Enthought, Inc. Some of the code in this file comes from enthought.traits
10 10 and is licensed under the BSD license. Also, many of the ideas also come
11 11 from enthought.traits even though our implementation is very different.
12 12 """
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Copyright (C) 2008-2009 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-----------------------------------------------------------------------------
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Imports
23 23 #-----------------------------------------------------------------------------
24 24
25 25 import sys
26 26 import os
27 27
28 28
29 29 from unittest import TestCase
30 30
31 31 from IPython.utils.traitlets import (
32 32 HasTraitlets, MetaHasTraitlets, TraitletType, Any,
33 33 Int, Long, Float, Complex, Str, Unicode, Bool, TraitletError,
34 34 Undefined, Type, This, Instance
35 35 )
36 36
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Helper classes for testing
40 40 #-----------------------------------------------------------------------------
41 41
42 42
43 43 class HasTraitletsStub(HasTraitlets):
44 44
45 45 def _notify_traitlet(self, name, old, new):
46 46 self._notify_name = name
47 47 self._notify_old = old
48 48 self._notify_new = new
49 49
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Test classes
53 53 #-----------------------------------------------------------------------------
54 54
55 55
56 56 class TestTraitletType(TestCase):
57 57
58 58 def test_get_undefined(self):
59 59 class A(HasTraitlets):
60 60 a = TraitletType
61 61 a = A()
62 62 self.assertEquals(a.a, Undefined)
63 63
64 64 def test_set(self):
65 65 class A(HasTraitletsStub):
66 66 a = TraitletType
67 67
68 68 a = A()
69 69 a.a = 10
70 70 self.assertEquals(a.a, 10)
71 71 self.assertEquals(a._notify_name, 'a')
72 72 self.assertEquals(a._notify_old, Undefined)
73 73 self.assertEquals(a._notify_new, 10)
74 74
75 75 def test_validate(self):
76 76 class MyTT(TraitletType):
77 77 def validate(self, inst, value):
78 78 return -1
79 79 class A(HasTraitletsStub):
80 80 tt = MyTT
81 81
82 82 a = A()
83 83 a.tt = 10
84 84 self.assertEquals(a.tt, -1)
85 85
86 86 def test_default_validate(self):
87 87 class MyIntTT(TraitletType):
88 88 def validate(self, obj, value):
89 89 if isinstance(value, int):
90 90 return value
91 91 self.error(obj, value)
92 92 class A(HasTraitlets):
93 93 tt = MyIntTT(10)
94 94 a = A()
95 95 self.assertEquals(a.tt, 10)
96 96
97 97 # Defaults are validated when the HasTraitlets is instantiated
98 98 class B(HasTraitlets):
99 99 tt = MyIntTT('bad default')
100 100 self.assertRaises(TraitletError, B)
101 101
102 102 def test_is_valid_for(self):
103 103 class MyTT(TraitletType):
104 104 def is_valid_for(self, value):
105 105 return True
106 106 class A(HasTraitlets):
107 107 tt = MyTT
108 108
109 109 a = A()
110 110 a.tt = 10
111 111 self.assertEquals(a.tt, 10)
112 112
113 113 def test_value_for(self):
114 114 class MyTT(TraitletType):
115 115 def value_for(self, value):
116 116 return 20
117 117 class A(HasTraitlets):
118 118 tt = MyTT
119 119
120 120 a = A()
121 121 a.tt = 10
122 122 self.assertEquals(a.tt, 20)
123 123
124 124 def test_info(self):
125 125 class A(HasTraitlets):
126 126 tt = TraitletType
127 127 a = A()
128 128 self.assertEquals(A.tt.info(), 'any value')
129 129
130 130 def test_error(self):
131 131 class A(HasTraitlets):
132 132 tt = TraitletType
133 133 a = A()
134 134 self.assertRaises(TraitletError, A.tt.error, a, 10)
135 135
136 136
137 137 class TestHasTraitletsMeta(TestCase):
138 138
139 139 def test_metaclass(self):
140 140 self.assertEquals(type(HasTraitlets), MetaHasTraitlets)
141 141
142 142 class A(HasTraitlets):
143 143 a = Int
144 144
145 145 a = A()
146 146 self.assertEquals(type(a.__class__), MetaHasTraitlets)
147 147 self.assertEquals(a.a,0)
148 148 a.a = 10
149 149 self.assertEquals(a.a,10)
150 150
151 151 class B(HasTraitlets):
152 152 b = Int()
153 153
154 154 b = B()
155 155 self.assertEquals(b.b,0)
156 156 b.b = 10
157 157 self.assertEquals(b.b,10)
158 158
159 159 class C(HasTraitlets):
160 160 c = Int(30)
161 161
162 162 c = C()
163 163 self.assertEquals(c.c,30)
164 164 c.c = 10
165 165 self.assertEquals(c.c,10)
166 166
167 167 def test_this_class(self):
168 168 class A(HasTraitlets):
169 169 t = This()
170 170 tt = This()
171 171 class B(A):
172 172 tt = This()
173 173 ttt = This()
174 174 self.assertEquals(A.t.this_class, A)
175 175 self.assertEquals(B.t.this_class, A)
176 176 self.assertEquals(B.tt.this_class, B)
177 177 self.assertEquals(B.ttt.this_class, B)
178 178
179 179 class TestHasTraitletsNotify(TestCase):
180 180
181 181 def setUp(self):
182 182 self._notify1 = []
183 183 self._notify2 = []
184 184
185 185 def notify1(self, name, old, new):
186 186 self._notify1.append((name, old, new))
187 187
188 188 def notify2(self, name, old, new):
189 189 self._notify2.append((name, old, new))
190 190
191 191 def test_notify_all(self):
192 192
193 193 class A(HasTraitlets):
194 194 a = Int
195 195 b = Float
196 196
197 197 a = A()
198 198 a.on_traitlet_change(self.notify1)
199 199 a.a = 0
200 200 self.assertEquals(len(self._notify1),0)
201 201 a.b = 0.0
202 202 self.assertEquals(len(self._notify1),0)
203 203 a.a = 10
204 204 self.assert_(('a',0,10) in self._notify1)
205 205 a.b = 10.0
206 206 self.assert_(('b',0.0,10.0) in self._notify1)
207 207 self.assertRaises(TraitletError,setattr,a,'a','bad string')
208 208 self.assertRaises(TraitletError,setattr,a,'b','bad string')
209 209 self._notify1 = []
210 210 a.on_traitlet_change(self.notify1,remove=True)
211 211 a.a = 20
212 212 a.b = 20.0
213 213 self.assertEquals(len(self._notify1),0)
214 214
215 215 def test_notify_one(self):
216 216
217 217 class A(HasTraitlets):
218 218 a = Int
219 219 b = Float
220 220
221 221 a = A()
222 222 a.on_traitlet_change(self.notify1, 'a')
223 223 a.a = 0
224 224 self.assertEquals(len(self._notify1),0)
225 225 a.a = 10
226 226 self.assert_(('a',0,10) in self._notify1)
227 227 self.assertRaises(TraitletError,setattr,a,'a','bad string')
228 228
229 229 def test_subclass(self):
230 230
231 231 class A(HasTraitlets):
232 232 a = Int
233 233
234 234 class B(A):
235 235 b = Float
236 236
237 237 b = B()
238 238 self.assertEquals(b.a,0)
239 239 self.assertEquals(b.b,0.0)
240 240 b.a = 100
241 241 b.b = 100.0
242 242 self.assertEquals(b.a,100)
243 243 self.assertEquals(b.b,100.0)
244 244
245 245 def test_notify_subclass(self):
246 246
247 247 class A(HasTraitlets):
248 248 a = Int
249 249
250 250 class B(A):
251 251 b = Float
252 252
253 253 b = B()
254 254 b.on_traitlet_change(self.notify1, 'a')
255 255 b.on_traitlet_change(self.notify2, 'b')
256 256 b.a = 0
257 257 b.b = 0.0
258 258 self.assertEquals(len(self._notify1),0)
259 259 self.assertEquals(len(self._notify2),0)
260 260 b.a = 10
261 261 b.b = 10.0
262 262 self.assert_(('a',0,10) in self._notify1)
263 263 self.assert_(('b',0.0,10.0) in self._notify2)
264 264
265 265 def test_static_notify(self):
266 266
267 267 class A(HasTraitlets):
268 268 a = Int
269 269 _notify1 = []
270 270 def _a_changed(self, name, old, new):
271 271 self._notify1.append((name, old, new))
272 272
273 273 a = A()
274 274 a.a = 0
275 275 # This is broken!!!
276 276 self.assertEquals(len(a._notify1),0)
277 277 a.a = 10
278 278 self.assert_(('a',0,10) in a._notify1)
279 279
280 280 class B(A):
281 281 b = Float
282 282 _notify2 = []
283 283 def _b_changed(self, name, old, new):
284 284 self._notify2.append((name, old, new))
285 285
286 286 b = B()
287 287 b.a = 10
288 288 b.b = 10.0
289 289 self.assert_(('a',0,10) in b._notify1)
290 290 self.assert_(('b',0.0,10.0) in b._notify2)
291 291
292 292 def test_notify_args(self):
293 293
294 294 def callback0():
295 295 self.cb = ()
296 296 def callback1(name):
297 297 self.cb = (name,)
298 298 def callback2(name, new):
299 299 self.cb = (name, new)
300 300 def callback3(name, old, new):
301 301 self.cb = (name, old, new)
302 302
303 303 class A(HasTraitlets):
304 304 a = Int
305 305
306 306 a = A()
307 307 a.on_traitlet_change(callback0, 'a')
308 308 a.a = 10
309 309 self.assertEquals(self.cb,())
310 310 a.on_traitlet_change(callback0, 'a', remove=True)
311 311
312 312 a.on_traitlet_change(callback1, 'a')
313 313 a.a = 100
314 314 self.assertEquals(self.cb,('a',))
315 315 a.on_traitlet_change(callback1, 'a', remove=True)
316 316
317 317 a.on_traitlet_change(callback2, 'a')
318 318 a.a = 1000
319 319 self.assertEquals(self.cb,('a',1000))
320 320 a.on_traitlet_change(callback2, 'a', remove=True)
321 321
322 322 a.on_traitlet_change(callback3, 'a')
323 323 a.a = 10000
324 324 self.assertEquals(self.cb,('a',1000,10000))
325 325 a.on_traitlet_change(callback3, 'a', remove=True)
326 326
327 327 self.assertEquals(len(a._traitlet_notifiers['a']),0)
328 328
329 329
330 330 class TestHasTraitlets(TestCase):
331 331
332 332 def test_traitlet_names(self):
333 333 class A(HasTraitlets):
334 334 i = Int
335 335 f = Float
336 336 a = A()
337 337 self.assertEquals(a.traitlet_names(),['i','f'])
338 338
339 339 def test_traitlet_metadata(self):
340 340 class A(HasTraitlets):
341 341 i = Int(config_key='MY_VALUE')
342 342 a = A()
343 343 self.assertEquals(a.traitlet_metadata('i','config_key'), 'MY_VALUE')
344 344
345 345 def test_traitlets(self):
346 346 class A(HasTraitlets):
347 347 i = Int
348 348 f = Float
349 349 a = A()
350 350 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
351 351
352 352 def test_traitlets_metadata(self):
353 353 class A(HasTraitlets):
354 354 i = Int(config_key='VALUE1', other_thing='VALUE2')
355 355 f = Float(config_key='VALUE3', other_thing='VALUE2')
356 356 a = A()
357 357 self.assertEquals(a.traitlets(), dict(i=A.i, f=A.f))
358 358 traitlets = a.traitlets(config_key=lambda v: True)
359 359 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
360 360 traitlets = a.traitlets(config_key='VALUE1', other_thing='VALUE2')
361 361 self.assertEquals(traitlets, dict(i=A.i))
362 362 traitlets = a.traitlets('config_key')
363 363 self.assertEquals(traitlets, dict(i=A.i, f=A.f))
364 364
365 365 #-----------------------------------------------------------------------------
366 366 # Tests for specific traitlet types
367 367 #-----------------------------------------------------------------------------
368 368
369 369
370 370 class TestType(TestCase):
371 371
372 372 def test_default(self):
373 373
374 374 class B(object): pass
375 375 class A(HasTraitlets):
376 376 klass = Type
377 377
378 378 a = A()
379 379 self.assertEquals(a.klass, None)
380
380 381 a.klass = B
381 382 self.assertEquals(a.klass, B)
382 383 self.assertRaises(TraitletError, setattr, a, 'klass', 10)
383 384
384 385 def test_value(self):
385 386
386 387 class B(object): pass
387 388 class C(object): pass
388 389 class A(HasTraitlets):
389 390 klass = Type(B)
390 391
391 392 a = A()
392 393 self.assertEquals(a.klass, B)
393 394 self.assertRaises(TraitletError, setattr, a, 'klass', C)
394 395 self.assertRaises(TraitletError, setattr, a, 'klass', object)
395 396 a.klass = B
396 397
397 398 def test_allow_none(self):
398 399
399 400 class B(object): pass
400 401 class C(B): pass
401 402 class A(HasTraitlets):
402 403 klass = Type(B, allow_none=False)
403 404
404 405 a = A()
405 406 self.assertEquals(a.klass, B)
406 407 self.assertRaises(TraitletError, setattr, a, 'klass', None)
407 408 a.klass = C
408 409 self.assertEquals(a.klass, C)
409 410
410 411 def test_validate_klass(self):
411 412
412 def inner():
413 class A(HasTraitlets):
414 klass = Type('no strings allowed')
413 class A(HasTraitlets):
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 423 def test_validate_default(self):
419 424
420 425 class B(object): pass
421 426 class A(HasTraitlets):
422 427 klass = Type('bad default', B)
423 428
424 self.assertRaises(TraitletError, A)
429 self.assertRaises(ImportError, A)
425 430
426 431 class C(HasTraitlets):
427 432 klass = Type(None, B, allow_none=False)
428 433
429 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 448 class TestInstance(TestCase):
432 449
433 450 def test_basic(self):
434 451 class Foo(object): pass
435 452 class Bar(Foo): pass
436 453 class Bah(object): pass
437 454
438 455 class A(HasTraitlets):
439 456 inst = Instance(Foo)
440 457
441 458 a = A()
442 459 self.assert_(a.inst is None)
443 460 a.inst = Foo()
444 461 self.assert_(isinstance(a.inst, Foo))
445 462 a.inst = Bar()
446 463 self.assert_(isinstance(a.inst, Foo))
447 464 self.assertRaises(TraitletError, setattr, a, 'inst', Foo)
448 465 self.assertRaises(TraitletError, setattr, a, 'inst', Bar)
449 466 self.assertRaises(TraitletError, setattr, a, 'inst', Bah())
450 467
451 468 def test_unique_default_value(self):
452 class Foo(object): pass
469 class Foo(object): pass
453 470 class A(HasTraitlets):
454 471 inst = Instance(Foo,(),{})
455 472
456 473 a = A()
457 474 b = A()
458 475 self.assert_(a.inst is not b.inst)
459 476
460 477 def test_args_kw(self):
461 478 class Foo(object):
462 479 def __init__(self, c): self.c = c
463 480 class Bar(object): pass
464 481 class Bah(object):
465 482 def __init__(self, c, d):
466 483 self.c = c; self.d = d
467 484
468 485 class A(HasTraitlets):
469 486 inst = Instance(Foo, (10,))
470 487 a = A()
471 488 self.assertEquals(a.inst.c, 10)
472 489
473 490 class B(HasTraitlets):
474 491 inst = Instance(Bah, args=(10,), kw=dict(d=20))
475 492 b = B()
476 493 self.assertEquals(b.inst.c, 10)
477 494 self.assertEquals(b.inst.d, 20)
478 495
479 496 class C(HasTraitlets):
480 497 inst = Instance(Foo)
481 498 c = C()
482 499 self.assert_(c.inst is None)
483 500
484 501 def test_bad_default(self):
485 502 class Foo(object): pass
486 503
487 504 class A(HasTraitlets):
488 505 inst = Instance(Foo, allow_none=False)
489 506
490 507 self.assertRaises(TraitletError, A)
491 508
492 509 def test_instance(self):
493 510 class Foo(object): pass
494 511
495 512 def inner():
496 513 class A(HasTraitlets):
497 514 inst = Instance(Foo())
498 515
499 516 self.assertRaises(TraitletError, inner)
500 517
501 518
502 519 class TestThis(TestCase):
503 520
504 521 def test_this_class(self):
505 522 class Foo(HasTraitlets):
506 523 this = This
507 524
508 525 f = Foo()
509 526 self.assertEquals(f.this, None)
510 527 g = Foo()
511 528 f.this = g
512 529 self.assertEquals(f.this, g)
513 530 self.assertRaises(TraitletError, setattr, f, 'this', 10)
514 531
515 532 def test_this_inst(self):
516 533 class Foo(HasTraitlets):
517 534 this = This()
518 535
519 536 f = Foo()
520 537 f.this = Foo()
521 538 self.assert_(isinstance(f.this, Foo))
522 539
523 540 def test_subclass(self):
524 541 class Foo(HasTraitlets):
525 542 t = This()
526 543 class Bar(Foo):
527 544 pass
528 545 f = Foo()
529 546 b = Bar()
530 547 f.t = b
531 548 b.t = f
532 549 self.assertEquals(f.t, b)
533 550 self.assertEquals(b.t, f)
534 551
535 552 def test_subclass_override(self):
536 553 class Foo(HasTraitlets):
537 554 t = This()
538 555 class Bar(Foo):
539 556 t = This()
540 557 f = Foo()
541 558 b = Bar()
542 559 f.t = b
543 560 self.assertEquals(f.t, b)
544 561 self.assertRaises(TraitletError, setattr, b, 't', f)
545 562
546 563 class TraitletTestBase(TestCase):
547 564 """A best testing class for basic traitlet types."""
548 565
549 566 def assign(self, value):
550 567 self.obj.value = value
551 568
552 569 def coerce(self, value):
553 570 return value
554 571
555 572 def test_good_values(self):
556 573 if hasattr(self, '_good_values'):
557 574 for value in self._good_values:
558 575 self.assign(value)
559 576 self.assertEquals(self.obj.value, self.coerce(value))
560 577
561 578 def test_bad_values(self):
562 579 if hasattr(self, '_bad_values'):
563 580 for value in self._bad_values:
564 581 self.assertRaises(TraitletError, self.assign, value)
565 582
566 583 def test_default_value(self):
567 584 if hasattr(self, '_default_value'):
568 585 self.assertEquals(self._default_value, self.obj.value)
569 586
570 587
571 588 class AnyTraitlet(HasTraitlets):
572 589
573 590 value = Any
574 591
575 592 class AnyTraitTest(TraitletTestBase):
576 593
577 594 obj = AnyTraitlet()
578 595
579 596 _default_value = None
580 597 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
581 598 _bad_values = []
582 599
583 600
584 601 class IntTraitlet(HasTraitlets):
585 602
586 603 value = Int(99)
587 604
588 605 class TestInt(TraitletTestBase):
589 606
590 607 obj = IntTraitlet()
591 608 _default_value = 99
592 609 _good_values = [10, -10]
593 610 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L,
594 611 -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
595 612 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
596 613
597 614
598 615 class LongTraitlet(HasTraitlets):
599 616
600 617 value = Long(99L)
601 618
602 619 class TestLong(TraitletTestBase):
603 620
604 621 obj = LongTraitlet()
605 622
606 623 _default_value = 99L
607 624 _good_values = [10, -10, 10L, -10L]
608 625 _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,),
609 626 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
610 627 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
611 628 u'-10.1']
612 629
613 630
614 631 class FloatTraitlet(HasTraitlets):
615 632
616 633 value = Float(99.0)
617 634
618 635 class TestFloat(TraitletTestBase):
619 636
620 637 obj = FloatTraitlet()
621 638
622 639 _default_value = 99.0
623 640 _good_values = [10, -10, 10.1, -10.1]
624 641 _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None,
625 642 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
626 643 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
627 644
628 645
629 646 class ComplexTraitlet(HasTraitlets):
630 647
631 648 value = Complex(99.0-99.0j)
632 649
633 650 class TestComplex(TraitletTestBase):
634 651
635 652 obj = ComplexTraitlet()
636 653
637 654 _default_value = 99.0-99.0j
638 655 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
639 656 10.1j, 10.1+10.1j, 10.1-10.1j]
640 657 _bad_values = [10L, -10L, u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
641 658
642 659
643 660 class StringTraitlet(HasTraitlets):
644 661
645 662 value = Str('string')
646 663
647 664 class TestString(TraitletTestBase):
648 665
649 666 obj = StringTraitlet()
650 667
651 668 _default_value = 'string'
652 669 _good_values = ['10', '-10', '10L',
653 670 '-10L', '10.1', '-10.1', 'string']
654 671 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j, [10],
655 672 ['ten'],{'ten': 10},(10,), None, u'string']
656 673
657 674
658 675 class UnicodeTraitlet(HasTraitlets):
659 676
660 677 value = Unicode(u'unicode')
661 678
662 679 class TestUnicode(TraitletTestBase):
663 680
664 681 obj = UnicodeTraitlet()
665 682
666 683 _default_value = u'unicode'
667 684 _good_values = ['10', '-10', '10L', '-10L', '10.1',
668 685 '-10.1', '', u'', 'string', u'string', ]
669 686 _bad_values = [10, -10, 10L, -10L, 10.1, -10.1, 1j,
670 687 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
@@ -1,925 +1,974 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 A lightweight Traits like module.
5 5
6 6 This is designed to provide a lightweight, simple, pure Python version of
7 7 many of the capabilities of enthought.traits. This includes:
8 8
9 9 * Validation
10 10 * Type specification with defaults
11 11 * Static and dynamic notification
12 12 * Basic predefined types
13 13 * An API that is similar to enthought.traits
14 14
15 15 We don't support:
16 16
17 17 * Delegation
18 18 * Automatic GUI generation
19 19 * A full set of trait types. Most importantly, we don't provide container
20 20 traitlets (list, dict, tuple) that can trigger notifications if their
21 21 contents change.
22 22 * API compatibility with enthought.traits
23 23
24 24 There are also some important difference in our design:
25 25
26 26 * enthought.traits does not validate default values. We do.
27 27
28 28 We choose to create this module because we need these capabilities, but
29 29 we need them to be pure Python so they work in all Python implementations,
30 30 including Jython and IronPython.
31 31
32 32 Authors:
33 33
34 34 * Brian Granger
35 35 * Enthought, Inc. Some of the code in this file comes from enthought.traits
36 36 and is licensed under the BSD license. Also, many of the ideas also come
37 37 from enthought.traits even though our implementation is very different.
38 38 """
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Copyright (C) 2008-2009 The IPython Development Team
42 42 #
43 43 # Distributed under the terms of the BSD License. The full license is in
44 44 # the file COPYING, distributed as part of this software.
45 45 #-----------------------------------------------------------------------------
46 46
47 47 #-----------------------------------------------------------------------------
48 48 # Imports
49 49 #-----------------------------------------------------------------------------
50 50
51 51
52 52 import inspect
53 53 import sys
54 54 import types
55 55 from types import (
56 56 InstanceType, ClassType, FunctionType,
57 57 ListType, TupleType
58 58 )
59 59
60 from IPython.utils.importstring import import_item
61
60 62 ClassTypes = (ClassType, type)
61 63
62 64 SequenceTypes = (ListType, TupleType)
63 65
64 66 #-----------------------------------------------------------------------------
65 67 # Basic classes
66 68 #-----------------------------------------------------------------------------
67 69
68 70
69 71 class NoDefaultSpecified ( object ): pass
70 72 NoDefaultSpecified = NoDefaultSpecified()
71 73
72 74
73 75 class Undefined ( object ): pass
74 76 Undefined = Undefined()
75 77
76 78
77 79 class TraitletError(Exception):
78 80 pass
79 81
80 82
81 83 #-----------------------------------------------------------------------------
82 84 # Utilities
83 85 #-----------------------------------------------------------------------------
84 86
85 87
86 88 def class_of ( object ):
87 89 """ Returns a string containing the class name of an object with the
88 90 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
89 91 'a PlotValue').
90 92 """
91 93 if isinstance( object, basestring ):
92 94 return add_article( object )
93 95
94 96 return add_article( object.__class__.__name__ )
95 97
96 98
97 99 def add_article ( name ):
98 100 """ Returns a string containing the correct indefinite article ('a' or 'an')
99 101 prefixed to the specified string.
100 102 """
101 103 if name[:1].lower() in 'aeiou':
102 104 return 'an ' + name
103 105
104 106 return 'a ' + name
105 107
106 108
107 109 def repr_type(obj):
108 110 """ Return a string representation of a value and its type for readable
109 111 error messages.
110 112 """
111 113 the_type = type(obj)
112 114 if the_type is InstanceType:
113 115 # Old-style class.
114 116 the_type = obj.__class__
115 117 msg = '%r %r' % (obj, the_type)
116 118 return msg
117 119
118 120
119 121 def parse_notifier_name(name):
120 122 """Convert the name argument to a list of names.
121 123
122 124 Examples
123 125 --------
124 126
125 127 >>> parse_notifier_name('a')
126 128 ['a']
127 129 >>> parse_notifier_name(['a','b'])
128 130 ['a', 'b']
129 131 >>> parse_notifier_name(None)
130 132 ['anytraitlet']
131 133 """
132 134 if isinstance(name, str):
133 135 return [name]
134 136 elif name is None:
135 137 return ['anytraitlet']
136 138 elif isinstance(name, (list, tuple)):
137 139 for n in name:
138 140 assert isinstance(n, str), "names must be strings"
139 141 return name
140 142
141 143
142 144 class _SimpleTest:
143 145 def __init__ ( self, value ): self.value = value
144 146 def __call__ ( self, test ):
145 print test, self.value
146 147 return test == self.value
147 148 def __repr__(self):
148 149 return "<SimpleTest(%r)" % self.value
149 150 def __str__(self):
150 151 return self.__repr__()
151 152
152 153
153 154 #-----------------------------------------------------------------------------
154 155 # Base TraitletType for all traitlets
155 156 #-----------------------------------------------------------------------------
156 157
157 158
158 159 class TraitletType(object):
159 160 """A base class for all traitlet descriptors.
160 161
161 162 Notes
162 163 -----
163 164 Our implementation of traitlets is based on Python's descriptor
164 165 prototol. This class is the base class for all such descriptors. The
165 166 only magic we use is a custom metaclass for the main :class:`HasTraitlets`
166 167 class that does the following:
167 168
168 169 1. Sets the :attr:`name` attribute of every :class:`TraitletType`
169 170 instance in the class dict to the name of the attribute.
170 171 2. Sets the :attr:`this_class` attribute of every :class:`TraitletType`
171 172 instance in the class dict to the *class* that declared the traitlet.
172 173 This is used by the :class:`This` traitlet to allow subclasses to
173 174 accept superclasses for :class:`This` values.
174 175 """
175 176
176 177
177 178 metadata = {}
178 179 default_value = Undefined
179 180 info_text = 'any value'
180 181
181 182 def __init__(self, default_value=NoDefaultSpecified, **metadata):
182 183 """Create a TraitletType.
183 184 """
184 185 if default_value is not NoDefaultSpecified:
185 186 self.default_value = default_value
186 187
187 188 if len(metadata) > 0:
188 189 if len(self.metadata) > 0:
189 190 self._metadata = self.metadata.copy()
190 191 self._metadata.update(metadata)
191 192 else:
192 193 self._metadata = metadata
193 194 else:
194 195 self._metadata = self.metadata
195 196
196 197 self.init()
197 198
198 199 def init(self):
199 200 pass
200 201
201 202 def get_default_value(self):
202 203 """Create a new instance of the default value."""
203 204 dv = self.default_value
204 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 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 235 dv = self.get_default_value()
208 236 newdv = self._validate(obj, dv)
209 237 obj._traitlet_values[self.name] = newdv
210
211 238
212 239 def __get__(self, obj, cls=None):
213 240 """Get the value of the traitlet by self.name for the instance.
214 241
215 242 Default values are instantiated when :meth:`HasTraitlets.__new__`
216 243 is called. Thus by the time this method gets called either the
217 244 default value or a user defined value (they called :meth:`__set__`)
218 245 is in the :class:`HasTraitlets` instance.
219 246 """
220 247 if obj is None:
221 248 return self
222 249 else:
223 250 try:
224 251 value = obj._traitlet_values[self.name]
225 252 except:
226 253 # HasTraitlets should call set_default_value to populate
227 254 # this. So this should never be reached.
228 255 raise TraitletError('Unexpected error in TraitletType: '
229 256 'default value not set properly')
230 257 else:
231 258 return value
232 259
233 260 def __set__(self, obj, value):
234 261 new_value = self._validate(obj, value)
235 262 old_value = self.__get__(obj)
236 263 if old_value != new_value:
237 264 obj._traitlet_values[self.name] = new_value
238 265 obj._notify_traitlet(self.name, old_value, new_value)
239 266
240 267 def _validate(self, obj, value):
241 268 if hasattr(self, 'validate'):
242 269 return self.validate(obj, value)
243 270 elif hasattr(self, 'is_valid_for'):
244 271 valid = self.is_valid_for(value)
245 272 if valid:
246 273 return value
247 274 else:
248 275 raise TraitletError('invalid value for type: %r' % value)
249 276 elif hasattr(self, 'value_for'):
250 277 return self.value_for(value)
251 278 else:
252 279 return value
253 280
254 281 def info(self):
255 282 return self.info_text
256 283
257 284 def error(self, obj, value):
258 285 if obj is not None:
259 286 e = "The '%s' traitlet of %s instance must be %s, but a value of %s was specified." \
260 287 % (self.name, class_of(obj),
261 288 self.info(), repr_type(value))
262 289 else:
263 290 e = "The '%s' traitlet must be %s, but a value of %r was specified." \
264 291 % (self.name, self.info(), repr_type(value))
265 292 raise TraitletError(e)
266 293
267 294 def get_metadata(self, key):
268 295 return getattr(self, '_metadata', {}).get(key, None)
269 296
270 297 def set_metadata(self, key, value):
271 298 getattr(self, '_metadata', {})[key] = value
272 299
273 300
274 301 #-----------------------------------------------------------------------------
275 302 # The HasTraitlets implementation
276 303 #-----------------------------------------------------------------------------
277 304
278 305
279 306 class MetaHasTraitlets(type):
280 307 """A metaclass for HasTraitlets.
281 308
282 309 This metaclass makes sure that any TraitletType class attributes are
283 310 instantiated and sets their name attribute.
284 311 """
285 312
286 313 def __new__(mcls, name, bases, classdict):
287 314 """Create the HasTraitlets class.
288 315
289 316 This instantiates all TraitletTypes in the class dict and sets their
290 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 319 for k,v in classdict.iteritems():
299 320 if isinstance(v, TraitletType):
300 321 v.name = k
301 322 elif inspect.isclass(v):
302 323 if issubclass(v, TraitletType):
303 324 vinst = v()
304 325 vinst.name = k
305 326 classdict[k] = vinst
306 327 return super(MetaHasTraitlets, mcls).__new__(mcls, name, bases, classdict)
307 328
308 329 def __init__(cls, name, bases, classdict):
309 330 """Finish initializing the HasTraitlets class.
310 331
311 332 This sets the :attr:`this_class` attribute of each TraitletType in the
312 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 335 for k, v in classdict.iteritems():
321 336 if isinstance(v, TraitletType):
322 337 v.this_class = cls
323 338 super(MetaHasTraitlets, cls).__init__(name, bases, classdict)
324 339
325 340 class HasTraitlets(object):
326 341
327 342 __metaclass__ = MetaHasTraitlets
328 343
329 344 def __new__(cls, *args, **kw):
330 345 inst = super(HasTraitlets, cls).__new__(cls, *args, **kw)
331 346 inst._traitlet_values = {}
332 347 inst._traitlet_notifiers = {}
333 348 # Here we tell all the TraitletType instances to set their default
334 349 # values on the instance.
335 350 for key in dir(cls):
336 351 value = getattr(cls, key)
337 352 if isinstance(value, TraitletType):
338 value.set_default_value(inst)
353 value.instance_init(inst)
339 354 return inst
340 355
341 356 # def __init__(self):
342 357 # self._traitlet_values = {}
343 358 # self._traitlet_notifiers = {}
344 359
345 360 def _notify_traitlet(self, name, old_value, new_value):
346 361
347 362 # First dynamic ones
348 363 callables = self._traitlet_notifiers.get(name,[])
349 364 more_callables = self._traitlet_notifiers.get('anytraitlet',[])
350 365 callables.extend(more_callables)
351 366
352 367 # Now static ones
353 368 try:
354 369 cb = getattr(self, '_%s_changed' % name)
355 370 except:
356 371 pass
357 372 else:
358 373 callables.append(cb)
359 374
360 375 # Call them all now
361 376 for c in callables:
362 377 # Traits catches and logs errors here. I allow them to raise
363 378 if callable(c):
364 379 argspec = inspect.getargspec(c)
365 380 nargs = len(argspec[0])
366 381 # Bound methods have an additional 'self' argument
367 382 # I don't know how to treat unbound methods, but they
368 383 # can't really be used for callbacks.
369 384 if isinstance(c, types.MethodType):
370 385 offset = -1
371 386 else:
372 387 offset = 0
373 388 if nargs + offset == 0:
374 389 c()
375 390 elif nargs + offset == 1:
376 391 c(name)
377 392 elif nargs + offset == 2:
378 393 c(name, new_value)
379 394 elif nargs + offset == 3:
380 395 c(name, old_value, new_value)
381 396 else:
382 397 raise TraitletError('a traitlet changed callback '
383 398 'must have 0-3 arguments.')
384 399 else:
385 400 raise TraitletError('a traitlet changed callback '
386 401 'must be callable.')
387 402
388 403
389 404 def _add_notifiers(self, handler, name):
390 405 if not self._traitlet_notifiers.has_key(name):
391 406 nlist = []
392 407 self._traitlet_notifiers[name] = nlist
393 408 else:
394 409 nlist = self._traitlet_notifiers[name]
395 410 if handler not in nlist:
396 411 nlist.append(handler)
397 412
398 413 def _remove_notifiers(self, handler, name):
399 414 if self._traitlet_notifiers.has_key(name):
400 415 nlist = self._traitlet_notifiers[name]
401 416 try:
402 417 index = nlist.index(handler)
403 418 except ValueError:
404 419 pass
405 420 else:
406 421 del nlist[index]
407 422
408 423 def on_traitlet_change(self, handler, name=None, remove=False):
409 424 """Setup a handler to be called when a traitlet changes.
410 425
411 426 This is used to setup dynamic notifications of traitlet changes.
412 427
413 428 Static handlers can be created by creating methods on a HasTraitlets
414 429 subclass with the naming convention '_[traitletname]_changed'. Thus,
415 430 to create static handler for the traitlet 'a', create the method
416 431 _a_changed(self, name, old, new) (fewer arguments can be used, see
417 432 below).
418 433
419 434 Parameters
420 435 ----------
421 436 handler : callable
422 437 A callable that is called when a traitlet changes. Its
423 438 signature can be handler(), handler(name), handler(name, new)
424 439 or handler(name, old, new).
425 440 name : list, str, None
426 441 If None, the handler will apply to all traitlets. If a list
427 442 of str, handler will apply to all names in the list. If a
428 443 str, the handler will apply just to that name.
429 444 remove : bool
430 445 If False (the default), then install the handler. If True
431 446 then unintall it.
432 447 """
433 448 if remove:
434 449 names = parse_notifier_name(name)
435 450 for n in names:
436 451 self._remove_notifiers(handler, n)
437 452 else:
438 453 names = parse_notifier_name(name)
439 454 for n in names:
440 455 self._add_notifiers(handler, n)
441 456
442 457 def traitlet_names(self, **metadata):
443 458 """Get a list of all the names of this classes traitlets."""
444 459 return self.traitlets(**metadata).keys()
445 460
446 461 def traitlets(self, *args, **metadata):
447 462 """Get a list of all the traitlets of this class.
448 463
449 464 The TraitletTypes returned don't know anything about the values
450 465 that the various HasTraitlet's instances are holding.
451 466 """
452 467 traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \
453 468 isinstance(memb[1], TraitletType)])
454 469 if len(metadata) == 0 and len(args) == 0:
455 470 return traitlets
456 471
457 472 for meta_name in args:
458 473 metadata[meta_name] = lambda _: True
459 474
460 475 for meta_name, meta_eval in metadata.items():
461 476 if type(meta_eval) is not FunctionType:
462 477 metadata[meta_name] = _SimpleTest(meta_eval)
463 478
464 479 result = {}
465 480 for name, traitlet in traitlets.items():
466 481 for meta_name, meta_eval in metadata.items():
467 482 if not meta_eval(traitlet.get_metadata(meta_name)):
468 483 break
469 484 else:
470 485 result[name] = traitlet
471 486
472 487 return result
473 488
474 489 def traitlet_metadata(self, traitletname, key):
475 490 """Get metadata values for traitlet by key."""
476 491 try:
477 492 traitlet = getattr(self.__class__, traitletname)
478 493 except AttributeError:
479 494 raise TraitletError("Class %s does not have a traitlet named %s" %
480 495 (self.__class__.__name__, traitletname))
481 496 else:
482 497 return traitlet.get_metadata(key)
483 498
484 499 #-----------------------------------------------------------------------------
485 500 # Actual TraitletTypes implementations/subclasses
486 501 #-----------------------------------------------------------------------------
487 502
488 503 #-----------------------------------------------------------------------------
489 504 # TraitletTypes subclasses for handling classes and instances of classes
490 505 #-----------------------------------------------------------------------------
491 506
492 507
493 508 class ClassBasedTraitletType(TraitletType):
494 509 """A traitlet with error reporting for Type, Instance and This."""
495 510
496 511 def error(self, obj, value):
497 512 kind = type(value)
498 513 if kind is InstanceType:
499 514 msg = 'class %s' % value.__class__.__name__
500 515 else:
501 516 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
502 517
503 518 super(ClassBasedTraitletType, self).error(obj, msg)
504 519
505 520
506 521 class Type(ClassBasedTraitletType):
507 522 """A traitlet whose value must be a subclass of a specified class."""
508 523
509 524 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
510 525 """Construct a Type traitlet
511 526
512 527 A Type traitlet specifies that its values must be subclasses of
513 528 a particular class.
514 529
530 If only ``default_value`` is given, it is used for the ``klass`` as
531 well.
532
515 533 Parameters
516 534 ----------
517 default_value : class
518 The default value must be a subclass of klass.
535 default_value : class, str or None
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 540 klass : class, str, None
520 541 Values of this traitlet must be a subclass of klass. The klass
521 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 545 allow_none : boolean
523 546 Indicates whether None is allowed as an assignable value. Even if
524 547 ``False``, the default value may be ``None``.
525 548 """
526 549 if default_value is None:
527 550 if klass is None:
528 551 klass = object
529 552 elif klass is None:
530 553 klass = default_value
531 554
532 if not inspect.isclass(klass):
555 if not (inspect.isclass(klass) or isinstance(klass, basestring)):
533 556 raise TraitletError("A Type traitlet must specify a class.")
534 557
535 558 self.klass = klass
536 559 self._allow_none = allow_none
537 560
538 561 super(Type, self).__init__(default_value, **metadata)
539 562
540 563 def validate(self, obj, value):
541 564 """Validates that the value is a valid object instance."""
542 565 try:
543 566 if issubclass(value, self.klass):
544 567 return value
545 568 except:
546 569 if (value is None) and (self._allow_none):
547 570 return value
548 571
549 572 self.error(obj, value)
550 573
551 574 def info(self):
552 575 """ Returns a description of the trait."""
553 klass = self.klass.__name__
576 if isinstance(self.klass, basestring):
577 klass = self.klass
578 else:
579 klass = self.klass.__name__
554 580 result = 'a subclass of ' + klass
555 581 if self._allow_none:
556 582 return result + ' or None'
557 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 599 class DefaultValueGenerator(object):
561 600 """A class for generating new default value instances."""
562 601
563 def __init__(self, klass, *args, **kw):
564 self.klass = klass
602 def __init__(self, *args, **kw):
565 603 self.args = args
566 604 self.kw = kw
567 605
568 def generate(self):
569 return self.klass(*self.args, **self.kw)
606 def generate(self, klass):
607 return klass(*self.args, **self.kw)
570 608
571 609
572 610 class Instance(ClassBasedTraitletType):
573 611 """A trait whose value must be an instance of a specified class.
574 612
575 613 The value can also be an instance of a subclass of the specified class.
576 614 """
577 615
578 616 def __init__(self, klass=None, args=None, kw=None,
579 617 allow_none=True, **metadata ):
580 618 """Construct an Instance traitlet.
581 619
582 620 This traitlet allows values that are instances of a particular
583 621 class or its sublclasses. Our implementation is quite different
584 622 from that of enthough.traits as we don't allow instances to be used
585 623 for klass and we handle the ``args`` and ``kw`` arguments differently.
586 624
587 625 Parameters
588 626 ----------
589 klass : class
590 The class that forms the basis for the traitlet. Instances
591 and strings are not allowed.
627 klass : class, str
628 The class that forms the basis for the traitlet. Class names
629 can also be specified as strings, like 'foo.bar.Bar'.
592 630 args : tuple
593 631 Positional arguments for generating the default value.
594 632 kw : dict
595 633 Keyword arguments for generating the default value.
596 634 allow_none : bool
597 635 Indicates whether None is allowed as a value.
598 636
599 637 Default Value
600 638 -------------
601 639 If both ``args`` and ``kw`` are None, then the default value is None.
602 640 If ``args`` is a tuple and ``kw`` is a dict, then the default is
603 641 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
604 642 not (but not both), None is replace by ``()`` or ``{}``.
605 643 """
606 644
607 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 648 raise TraitletError('The klass argument must be a class'
611 649 ' you gave: %r' % klass)
612 650 self.klass = klass
613 651
614 652 # self.klass is a class, so handle default_value
615 653 if args is None and kw is None:
616 654 default_value = None
617 655 else:
618 656 if args is None:
619 657 # kw is not None
620 658 args = ()
621 659 elif kw is None:
622 660 # args is not None
623 661 kw = {}
624 662
625 663 if not isinstance(kw, dict):
626 664 raise TraitletError("The 'kw' argument must be a dict or None.")
627 665 if not isinstance(args, tuple):
628 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 670 super(Instance, self).__init__(default_value, **metadata)
633 671
634 672 def validate(self, obj, value):
635 673 if value is None:
636 674 if self._allow_none:
637 675 return value
638 676 self.error(obj, value)
639 677
640 678 if isinstance(value, self.klass):
641 679 return value
642 680 else:
643 681 self.error(obj, value)
644 682
645 683 def info(self):
646 klass = self.klass.__name__
684 if isinstance(self.klass, basestring):
685 klass = self.klass
686 else:
687 klass = self.klass.__name__
647 688 result = class_of(klass)
648 689 if self._allow_none:
649 690 return result + ' or None'
650 691
651 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 702 def get_default_value(self):
654 703 """Instantiate a default value instance.
655 704
656 705 This is called when the containing HasTraitlets classes'
657 706 :meth:`__new__` method is called to ensure that a unique instance
658 707 is created for each HasTraitlets instance.
659 708 """
660 709 dv = self.default_value
661 710 if isinstance(dv, DefaultValueGenerator):
662 return dv.generate()
711 return dv.generate(self.klass)
663 712 else:
664 713 return dv
665 714
666 715
667 716 class This(ClassBasedTraitletType):
668 717 """A traitlet for instances of the class containing this trait.
669 718
670 719 Because how how and when class bodies are executed, the ``This``
671 720 traitlet can only have a default value of None. This, and because we
672 721 always validate default values, ``allow_none`` is *always* true.
673 722 """
674 723
675 724 info_text = 'an instance of the same type as the receiver or None'
676 725
677 726 def __init__(self, **metadata):
678 727 super(This, self).__init__(None, **metadata)
679 728
680 729 def validate(self, obj, value):
681 730 # What if value is a superclass of obj.__class__? This is
682 731 # complicated if it was the superclass that defined the This
683 732 # traitlet.
684 733 if isinstance(value, self.this_class) or (value is None):
685 734 return value
686 735 else:
687 736 self.error(obj, value)
688 737
689 738
690 739 #-----------------------------------------------------------------------------
691 740 # Basic TraitletTypes implementations/subclasses
692 741 #-----------------------------------------------------------------------------
693 742
694 743
695 744 class Any(TraitletType):
696 745 default_value = None
697 746 info_text = 'any value'
698 747
699 748
700 749 class Int(TraitletType):
701 750 """A integer traitlet."""
702 751
703 752 evaluate = int
704 753 default_value = 0
705 754 info_text = 'an integer'
706 755
707 756 def validate(self, obj, value):
708 757 if isinstance(value, int):
709 758 return value
710 759 self.error(obj, value)
711 760
712 761 class CInt(Int):
713 762 """A casting version of the int traitlet."""
714 763
715 764 def validate(self, obj, value):
716 765 try:
717 766 return int(value)
718 767 except:
719 768 self.error(obj, value)
720 769
721 770
722 771 class Long(TraitletType):
723 772 """A long integer traitlet."""
724 773
725 774 evaluate = long
726 775 default_value = 0L
727 776 info_text = 'a long'
728 777
729 778 def validate(self, obj, value):
730 779 if isinstance(value, long):
731 780 return value
732 781 if isinstance(value, int):
733 782 return long(value)
734 783 self.error(obj, value)
735 784
736 785
737 786 class CLong(Long):
738 787 """A casting version of the long integer traitlet."""
739 788
740 789 def validate(self, obj, value):
741 790 try:
742 791 return long(value)
743 792 except:
744 793 self.error(obj, value)
745 794
746 795
747 796 class Float(TraitletType):
748 797 """A float traitlet."""
749 798
750 799 evaluate = float
751 800 default_value = 0.0
752 801 info_text = 'a float'
753 802
754 803 def validate(self, obj, value):
755 804 if isinstance(value, float):
756 805 return value
757 806 if isinstance(value, int):
758 807 return float(value)
759 808 self.error(obj, value)
760 809
761 810
762 811 class CFloat(Float):
763 812 """A casting version of the float traitlet."""
764 813
765 814 def validate(self, obj, value):
766 815 try:
767 816 return float(value)
768 817 except:
769 818 self.error(obj, value)
770 819
771 820 class Complex(TraitletType):
772 821 """A traitlet for complex numbers."""
773 822
774 823 evaluate = complex
775 824 default_value = 0.0 + 0.0j
776 825 info_text = 'a complex number'
777 826
778 827 def validate(self, obj, value):
779 828 if isinstance(value, complex):
780 829 return value
781 830 if isinstance(value, (float, int)):
782 831 return complex(value)
783 832 self.error(obj, value)
784 833
785 834
786 835 class CComplex(Complex):
787 836 """A casting version of the complex number traitlet."""
788 837
789 838 def validate (self, obj, value):
790 839 try:
791 840 return complex(value)
792 841 except:
793 842 self.error(obj, value)
794 843
795 844
796 845 class Str(TraitletType):
797 846 """A traitlet for strings."""
798 847
799 848 evaluate = lambda x: x
800 849 default_value = ''
801 850 info_text = 'a string'
802 851
803 852 def validate(self, obj, value):
804 853 if isinstance(value, str):
805 854 return value
806 855 self.error(obj, value)
807 856
808 857
809 858 class CStr(Str):
810 859 """A casting version of the string traitlet."""
811 860
812 861 def validate(self, obj, value):
813 862 try:
814 863 return str(value)
815 864 except:
816 865 try:
817 866 return unicode(value)
818 867 except:
819 868 self.error(obj, value)
820 869
821 870
822 871 class Unicode(TraitletType):
823 872 """A traitlet for unicode strings."""
824 873
825 874 evaluate = unicode
826 875 default_value = u''
827 876 info_text = 'a unicode string'
828 877
829 878 def validate(self, obj, value):
830 879 if isinstance(value, unicode):
831 880 return value
832 881 if isinstance(value, str):
833 882 return unicode(value)
834 883 self.error(obj, value)
835 884
836 885
837 886 class CUnicode(Unicode):
838 887 """A casting version of the unicode traitlet."""
839 888
840 889 def validate(self, obj, value):
841 890 try:
842 891 return unicode(value)
843 892 except:
844 893 self.error(obj, value)
845 894
846 895
847 896 class Bool(TraitletType):
848 897 """A boolean (True, False) traitlet."""
849 898 evaluate = bool
850 899 default_value = False
851 900 info_text = 'a boolean'
852 901
853 902 def validate(self, obj, value):
854 903 if isinstance(value, bool):
855 904 return value
856 905 self.error(obj, value)
857 906
858 907
859 908 class CBool(Bool):
860 909 """A casting version of the boolean traitlet."""
861 910
862 911 def validate(self, obj, value):
863 912 try:
864 913 return bool(value)
865 914 except:
866 915 self.error(obj, value)
867 916
868 917
869 918 class Enum(TraitletType):
870 919 """An enum that whose value must be in a given sequence."""
871 920
872 921 def __init__(self, values, default_value=None, allow_none=True, **metadata):
873 922 self.values = values
874 923 self._allow_none = allow_none
875 924 super(Enum, self).__init__(default_value, **metadata)
876 925
877 926 def validate(self, obj, value):
878 927 if value is None:
879 928 if self._allow_none:
880 929 return value
881 930
882 931 if value in self.values:
883 932 return value
884 933 self.error(obj, value)
885 934
886 935 def info(self):
887 936 """ Returns a description of the trait."""
888 937 result = 'any of ' + repr(self.values)
889 938 if self._allow_none:
890 939 return result + ' or None'
891 940 return result
892 941
893 942 class CaselessStrEnum(Enum):
894 943 """An enum of strings that are caseless in validate."""
895 944
896 945 def validate(self, obj, value):
897 946 if value is None:
898 947 if self._allow_none:
899 948 return value
900 949
901 950 if not isinstance(value, str):
902 951 self.error(obj, value)
903 952
904 953 for v in self.values:
905 954 if v.lower() == value.lower():
906 955 return v
907 956 self.error(obj, value)
908 957
909 958
910 959 class List(Instance):
911 960 """An instance of a Python list."""
912 961
913 962 def __init__(self, default_value=None, allow_none=True, **metadata):
914 963 """Create a list traitlet type from a list or tuple.
915 964
916 965 The default value is created by doing ``list(default_value)``,
917 966 which creates a copy of the ``default_value``.
918 967 """
919 968 if default_value is None:
920 969 args = ((),)
921 970 elif isinstance(default_value, SequenceTypes):
922 971 args = (default_value,)
923 972
924 973 super(List,self).__init__(klass=list, args=args,
925 974 allow_none=allow_none, **metadata)
General Comments 0
You need to be logged in to leave comments. Login now