##// END OF EJS Templates
update copyright to 2011/20xx-2011...
Matthias BUSSONNIER -
Show More

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

@@ -1,14 +1,14 b''
1 1 # encoding: utf-8
2 2
3 3 __docformat__ = "restructuredtext en"
4 4
5 5 #-------------------------------------------------------------------------------
6 # Copyright (C) 2008 The IPython Development Team
6 # Copyright (C) 2008-2011 The IPython Development Team
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #-------------------------------------------------------------------------------
11 11
12 12 #-------------------------------------------------------------------------------
13 13 # Imports
14 14 #------------------------------------------------------------------------------- No newline at end of file
@@ -1,183 +1,183 b''
1 1 # encoding: utf-8
2 2 """
3 3 Tests for IPython.config.configurable
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez (design help)
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2008-2011 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 from unittest import TestCase
23 23
24 24 from IPython.config.configurable import (
25 25 Configurable,
26 26 SingletonConfigurable
27 27 )
28 28
29 29 from IPython.utils.traitlets import (
30 30 Integer, Float, Unicode
31 31 )
32 32
33 33 from IPython.config.loader import Config
34 34 from IPython.utils.py3compat import PY3
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Test cases
38 38 #-----------------------------------------------------------------------------
39 39
40 40
41 41 class MyConfigurable(Configurable):
42 42 a = Integer(1, config=True, help="The integer a.")
43 43 b = Float(1.0, config=True, help="The integer b.")
44 44 c = Unicode('no config')
45 45
46 46
47 47 mc_help=u"""MyConfigurable options
48 48 ----------------------
49 49 --MyConfigurable.a=<Integer>
50 50 Default: 1
51 51 The integer a.
52 52 --MyConfigurable.b=<Float>
53 53 Default: 1.0
54 54 The integer b."""
55 55
56 56 mc_help_inst=u"""MyConfigurable options
57 57 ----------------------
58 58 --MyConfigurable.a=<Integer>
59 59 Current: 5
60 60 The integer a.
61 61 --MyConfigurable.b=<Float>
62 62 Current: 4.0
63 63 The integer b."""
64 64
65 65 # On Python 3, the Integer trait is a synonym for Int
66 66 if PY3:
67 67 mc_help = mc_help.replace(u"<Integer>", u"<Int>")
68 68 mc_help_inst = mc_help_inst.replace(u"<Integer>", u"<Int>")
69 69
70 70 class Foo(Configurable):
71 71 a = Integer(0, config=True, help="The integer a.")
72 72 b = Unicode('nope', config=True)
73 73
74 74
75 75 class Bar(Foo):
76 76 b = Unicode('gotit', config=False, help="The string b.")
77 77 c = Float(config=True, help="The string c.")
78 78
79 79
80 80 class TestConfigurable(TestCase):
81 81
82 82 def test_default(self):
83 83 c1 = Configurable()
84 84 c2 = Configurable(config=c1.config)
85 85 c3 = Configurable(config=c2.config)
86 86 self.assertEquals(c1.config, c2.config)
87 87 self.assertEquals(c2.config, c3.config)
88 88
89 89 def test_custom(self):
90 90 config = Config()
91 91 config.foo = 'foo'
92 92 config.bar = 'bar'
93 93 c1 = Configurable(config=config)
94 94 c2 = Configurable(config=c1.config)
95 95 c3 = Configurable(config=c2.config)
96 96 self.assertEquals(c1.config, config)
97 97 self.assertEquals(c2.config, config)
98 98 self.assertEquals(c3.config, config)
99 99 # Test that copies are not made
100 100 self.assert_(c1.config is config)
101 101 self.assert_(c2.config is config)
102 102 self.assert_(c3.config is config)
103 103 self.assert_(c1.config is c2.config)
104 104 self.assert_(c2.config is c3.config)
105 105
106 106 def test_inheritance(self):
107 107 config = Config()
108 108 config.MyConfigurable.a = 2
109 109 config.MyConfigurable.b = 2.0
110 110 c1 = MyConfigurable(config=config)
111 111 c2 = MyConfigurable(config=c1.config)
112 112 self.assertEquals(c1.a, config.MyConfigurable.a)
113 113 self.assertEquals(c1.b, config.MyConfigurable.b)
114 114 self.assertEquals(c2.a, config.MyConfigurable.a)
115 115 self.assertEquals(c2.b, config.MyConfigurable.b)
116 116
117 117 def test_parent(self):
118 118 config = Config()
119 119 config.Foo.a = 10
120 120 config.Foo.b = "wow"
121 121 config.Bar.b = 'later'
122 122 config.Bar.c = 100.0
123 123 f = Foo(config=config)
124 124 b = Bar(config=f.config)
125 125 self.assertEquals(f.a, 10)
126 126 self.assertEquals(f.b, 'wow')
127 127 self.assertEquals(b.b, 'gotit')
128 128 self.assertEquals(b.c, 100.0)
129 129
130 130 def test_override1(self):
131 131 config = Config()
132 132 config.MyConfigurable.a = 2
133 133 config.MyConfigurable.b = 2.0
134 134 c = MyConfigurable(a=3, config=config)
135 135 self.assertEquals(c.a, 3)
136 136 self.assertEquals(c.b, config.MyConfigurable.b)
137 137 self.assertEquals(c.c, 'no config')
138 138
139 139 def test_override2(self):
140 140 config = Config()
141 141 config.Foo.a = 1
142 142 config.Bar.b = 'or' # Up above b is config=False, so this won't do it.
143 143 config.Bar.c = 10.0
144 144 c = Bar(config=config)
145 145 self.assertEquals(c.a, config.Foo.a)
146 146 self.assertEquals(c.b, 'gotit')
147 147 self.assertEquals(c.c, config.Bar.c)
148 148 c = Bar(a=2, b='and', c=20.0, config=config)
149 149 self.assertEquals(c.a, 2)
150 150 self.assertEquals(c.b, 'and')
151 151 self.assertEquals(c.c, 20.0)
152 152
153 153 def test_help(self):
154 154 self.assertEquals(MyConfigurable.class_get_help(), mc_help)
155 155
156 156 def test_help_inst(self):
157 157 inst = MyConfigurable(a=5, b=4)
158 158 self.assertEquals(MyConfigurable.class_get_help(inst), mc_help_inst)
159 159
160 160
161 161 class TestSingletonConfigurable(TestCase):
162 162
163 163 def test_instance(self):
164 164 from IPython.config.configurable import SingletonConfigurable
165 165 class Foo(SingletonConfigurable): pass
166 166 self.assertEquals(Foo.initialized(), False)
167 167 foo = Foo.instance()
168 168 self.assertEquals(Foo.initialized(), True)
169 169 self.assertEquals(foo, Foo.instance())
170 170 self.assertEquals(SingletonConfigurable._instance, None)
171 171
172 172 def test_inheritance(self):
173 173 class Bar(SingletonConfigurable): pass
174 174 class Bam(Bar): pass
175 175 self.assertEquals(Bar.initialized(), False)
176 176 self.assertEquals(Bam.initialized(), False)
177 177 bam = Bam.instance()
178 178 bam == Bar.instance()
179 179 self.assertEquals(Bar.initialized(), True)
180 180 self.assertEquals(Bam.initialized(), True)
181 181 self.assertEquals(bam, Bam._instance)
182 182 self.assertEquals(bam, Bar._instance)
183 183 self.assertEquals(SingletonConfigurable._instance, None)
@@ -1,255 +1,255 b''
1 1 # encoding: utf-8
2 2 """
3 3 Tests for IPython.config.loader
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez (design help)
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2008-2011 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 os
23 23 import sys
24 24 from tempfile import mkstemp
25 25 from unittest import TestCase
26 26
27 27 from nose import SkipTest
28 28
29 29 from IPython.testing.tools import mute_warn
30 30
31 31 from IPython.utils.traitlets import Unicode
32 32 from IPython.config.configurable import Configurable
33 33 from IPython.config.loader import (
34 34 Config,
35 35 PyFileConfigLoader,
36 36 KeyValueConfigLoader,
37 37 ArgParseConfigLoader,
38 38 KVArgParseConfigLoader,
39 39 ConfigError
40 40 )
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Actual tests
44 44 #-----------------------------------------------------------------------------
45 45
46 46
47 47 pyfile = """
48 48 c = get_config()
49 49 c.a=10
50 50 c.b=20
51 51 c.Foo.Bar.value=10
52 52 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
53 53 c.D.C.value='hi there'
54 54 """
55 55
56 56 class TestPyFileCL(TestCase):
57 57
58 58 def test_basic(self):
59 59 fd, fname = mkstemp('.py')
60 60 f = os.fdopen(fd, 'w')
61 61 f.write(pyfile)
62 62 f.close()
63 63 # Unlink the file
64 64 cl = PyFileConfigLoader(fname)
65 65 config = cl.load_config()
66 66 self.assertEquals(config.a, 10)
67 67 self.assertEquals(config.b, 20)
68 68 self.assertEquals(config.Foo.Bar.value, 10)
69 69 self.assertEquals(config.Foo.Bam.value, range(10))
70 70 self.assertEquals(config.D.C.value, 'hi there')
71 71
72 72 class MyLoader1(ArgParseConfigLoader):
73 73 def _add_arguments(self, aliases=None, flags=None):
74 74 p = self.parser
75 75 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
76 76 p.add_argument('-b', dest='MyClass.bar', type=int)
77 77 p.add_argument('-n', dest='n', action='store_true')
78 78 p.add_argument('Global.bam', type=str)
79 79
80 80 class MyLoader2(ArgParseConfigLoader):
81 81 def _add_arguments(self, aliases=None, flags=None):
82 82 subparsers = self.parser.add_subparsers(dest='subparser_name')
83 83 subparser1 = subparsers.add_parser('1')
84 84 subparser1.add_argument('-x',dest='Global.x')
85 85 subparser2 = subparsers.add_parser('2')
86 86 subparser2.add_argument('y')
87 87
88 88 class TestArgParseCL(TestCase):
89 89
90 90 def test_basic(self):
91 91 cl = MyLoader1()
92 92 config = cl.load_config('-f hi -b 10 -n wow'.split())
93 93 self.assertEquals(config.Global.foo, 'hi')
94 94 self.assertEquals(config.MyClass.bar, 10)
95 95 self.assertEquals(config.n, True)
96 96 self.assertEquals(config.Global.bam, 'wow')
97 97 config = cl.load_config(['wow'])
98 98 self.assertEquals(config.keys(), ['Global'])
99 99 self.assertEquals(config.Global.keys(), ['bam'])
100 100 self.assertEquals(config.Global.bam, 'wow')
101 101
102 102 def test_add_arguments(self):
103 103 cl = MyLoader2()
104 104 config = cl.load_config('2 frobble'.split())
105 105 self.assertEquals(config.subparser_name, '2')
106 106 self.assertEquals(config.y, 'frobble')
107 107 config = cl.load_config('1 -x frobble'.split())
108 108 self.assertEquals(config.subparser_name, '1')
109 109 self.assertEquals(config.Global.x, 'frobble')
110 110
111 111 def test_argv(self):
112 112 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
113 113 config = cl.load_config()
114 114 self.assertEquals(config.Global.foo, 'hi')
115 115 self.assertEquals(config.MyClass.bar, 10)
116 116 self.assertEquals(config.n, True)
117 117 self.assertEquals(config.Global.bam, 'wow')
118 118
119 119
120 120 class TestKeyValueCL(TestCase):
121 121 klass = KeyValueConfigLoader
122 122
123 123 def test_basic(self):
124 124 cl = self.klass()
125 125 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
126 126 with mute_warn():
127 127 config = cl.load_config(argv)
128 128 self.assertEquals(config.a, 10)
129 129 self.assertEquals(config.b, 20)
130 130 self.assertEquals(config.Foo.Bar.value, 10)
131 131 self.assertEquals(config.Foo.Bam.value, range(10))
132 132 self.assertEquals(config.D.C.value, 'hi there')
133 133
134 134 def test_expanduser(self):
135 135 cl = self.klass()
136 136 argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
137 137 with mute_warn():
138 138 config = cl.load_config(argv)
139 139 self.assertEquals(config.a, os.path.expanduser('~/1/2/3'))
140 140 self.assertEquals(config.b, os.path.expanduser('~'))
141 141 self.assertEquals(config.c, os.path.expanduser('~/'))
142 142 self.assertEquals(config.d, '~/')
143 143
144 144 def test_extra_args(self):
145 145 cl = self.klass()
146 146 with mute_warn():
147 147 config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
148 148 self.assertEquals(cl.extra_args, ['b', 'd'])
149 149 self.assertEquals(config.a, 5)
150 150 self.assertEquals(config.c, 10)
151 151 with mute_warn():
152 152 config = cl.load_config(['--', '--a=5', '--c=10'])
153 153 self.assertEquals(cl.extra_args, ['--a=5', '--c=10'])
154 154
155 155 def test_unicode_args(self):
156 156 cl = self.klass()
157 157 argv = [u'--a=épsîlön']
158 158 with mute_warn():
159 159 config = cl.load_config(argv)
160 160 self.assertEquals(config.a, u'épsîlön')
161 161
162 162 def test_unicode_bytes_args(self):
163 163 uarg = u'--a=é'
164 164 try:
165 165 barg = uarg.encode(sys.stdin.encoding)
166 166 except (TypeError, UnicodeEncodeError):
167 167 raise SkipTest("sys.stdin.encoding can't handle 'é'")
168 168
169 169 cl = self.klass()
170 170 with mute_warn():
171 171 config = cl.load_config([barg])
172 172 self.assertEquals(config.a, u'é')
173 173
174 174 def test_unicode_alias(self):
175 175 cl = self.klass()
176 176 argv = [u'--a=épsîlön']
177 177 with mute_warn():
178 178 config = cl.load_config(argv, aliases=dict(a='A.a'))
179 179 self.assertEquals(config.A.a, u'épsîlön')
180 180
181 181
182 182 class TestArgParseKVCL(TestKeyValueCL):
183 183 klass = KVArgParseConfigLoader
184 184
185 185 def test_expanduser2(self):
186 186 cl = self.klass()
187 187 argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
188 188 with mute_warn():
189 189 config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
190 190 self.assertEquals(config.A.a, os.path.expanduser('~/1/2/3'))
191 191 self.assertEquals(config.A.b, '~/1/2/3')
192 192
193 193 class TestConfig(TestCase):
194 194
195 195 def test_setget(self):
196 196 c = Config()
197 197 c.a = 10
198 198 self.assertEquals(c.a, 10)
199 199 self.assertEquals(c.has_key('b'), False)
200 200
201 201 def test_auto_section(self):
202 202 c = Config()
203 203 self.assertEquals(c.has_key('A'), True)
204 204 self.assertEquals(c._has_section('A'), False)
205 205 A = c.A
206 206 A.foo = 'hi there'
207 207 self.assertEquals(c._has_section('A'), True)
208 208 self.assertEquals(c.A.foo, 'hi there')
209 209 del c.A
210 210 self.assertEquals(len(c.A.keys()),0)
211 211
212 212 def test_merge_doesnt_exist(self):
213 213 c1 = Config()
214 214 c2 = Config()
215 215 c2.bar = 10
216 216 c2.Foo.bar = 10
217 217 c1._merge(c2)
218 218 self.assertEquals(c1.Foo.bar, 10)
219 219 self.assertEquals(c1.bar, 10)
220 220 c2.Bar.bar = 10
221 221 c1._merge(c2)
222 222 self.assertEquals(c1.Bar.bar, 10)
223 223
224 224 def test_merge_exists(self):
225 225 c1 = Config()
226 226 c2 = Config()
227 227 c1.Foo.bar = 10
228 228 c1.Foo.bam = 30
229 229 c2.Foo.bar = 20
230 230 c2.Foo.wow = 40
231 231 c1._merge(c2)
232 232 self.assertEquals(c1.Foo.bam, 30)
233 233 self.assertEquals(c1.Foo.bar, 20)
234 234 self.assertEquals(c1.Foo.wow, 40)
235 235 c2.Foo.Bam.bam = 10
236 236 c1._merge(c2)
237 237 self.assertEquals(c1.Foo.Bam.bam, 10)
238 238
239 239 def test_deepcopy(self):
240 240 c1 = Config()
241 241 c1.Foo.bar = 10
242 242 c1.Foo.bam = 30
243 243 c1.a = 'asdf'
244 244 c1.b = range(10)
245 245 import copy
246 246 c2 = copy.deepcopy(c1)
247 247 self.assertEquals(c1, c2)
248 248 self.assert_(c1 is not c2)
249 249 self.assert_(c1.Foo is not c2.Foo)
250 250
251 251 def test_builtin(self):
252 252 c1 = Config()
253 253 exec 'foo = True' in c1
254 254 self.assertEquals(c1.foo, True)
255 255 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
@@ -1,263 +1,263 b''
1 1 # encoding: utf-8
2 2 """
3 3 System command aliases.
4 4
5 5 Authors:
6 6
7 7 * Fernando Perez
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License.
15 15 #
16 16 # The full license is in the file COPYING.txt, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import __builtin__
24 24 import keyword
25 25 import os
26 26 import re
27 27 import sys
28 28
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.core.splitinput import split_user_input
31 31
32 32 from IPython.utils.traitlets import List, Instance
33 33 from IPython.utils.autoattr import auto_attr
34 34 from IPython.utils.warn import warn, error
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Utilities
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # This is used as the pattern for calls to split_user_input.
41 41 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
42 42
43 43 def default_aliases():
44 44 """Return list of shell aliases to auto-define.
45 45 """
46 46 # Note: the aliases defined here should be safe to use on a kernel
47 47 # regardless of what frontend it is attached to. Frontends that use a
48 48 # kernel in-process can define additional aliases that will only work in
49 49 # their case. For example, things like 'less' or 'clear' that manipulate
50 50 # the terminal should NOT be declared here, as they will only work if the
51 51 # kernel is running inside a true terminal, and not over the network.
52 52
53 53 if os.name == 'posix':
54 54 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
55 55 ('mv', 'mv -i'), ('rm', 'rm -i'), ('cp', 'cp -i'),
56 56 ('cat', 'cat'),
57 57 ]
58 58 # Useful set of ls aliases. The GNU and BSD options are a little
59 59 # different, so we make aliases that provide as similar as possible
60 60 # behavior in ipython, by passing the right flags for each platform
61 61 if sys.platform.startswith('linux'):
62 62 ls_aliases = [('ls', 'ls -F --color'),
63 63 # long ls
64 64 ('ll', 'ls -F -o --color'),
65 65 # ls normal files only
66 66 ('lf', 'ls -F -o --color %l | grep ^-'),
67 67 # ls symbolic links
68 68 ('lk', 'ls -F -o --color %l | grep ^l'),
69 69 # directories or links to directories,
70 70 ('ldir', 'ls -F -o --color %l | grep /$'),
71 71 # things which are executable
72 72 ('lx', 'ls -F -o --color %l | grep ^-..x'),
73 73 ]
74 74 else:
75 75 # BSD, OSX, etc.
76 76 ls_aliases = [('ls', 'ls -F'),
77 77 # long ls
78 78 ('ll', 'ls -F -l'),
79 79 # ls normal files only
80 80 ('lf', 'ls -F -l %l | grep ^-'),
81 81 # ls symbolic links
82 82 ('lk', 'ls -F -l %l | grep ^l'),
83 83 # directories or links to directories,
84 84 ('ldir', 'ls -F -l %l | grep /$'),
85 85 # things which are executable
86 86 ('lx', 'ls -F -l %l | grep ^-..x'),
87 87 ]
88 88 default_aliases = default_aliases + ls_aliases
89 89 elif os.name in ['nt', 'dos']:
90 90 default_aliases = [('ls', 'dir /on'),
91 91 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
92 92 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
93 93 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
94 94 ]
95 95 else:
96 96 default_aliases = []
97 97
98 98 return default_aliases
99 99
100 100
101 101 class AliasError(Exception):
102 102 pass
103 103
104 104
105 105 class InvalidAliasError(AliasError):
106 106 pass
107 107
108 108 #-----------------------------------------------------------------------------
109 109 # Main AliasManager class
110 110 #-----------------------------------------------------------------------------
111 111
112 112 class AliasManager(Configurable):
113 113
114 114 default_aliases = List(default_aliases(), config=True)
115 115 user_aliases = List(default_value=[], config=True)
116 116 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
117 117
118 118 def __init__(self, shell=None, config=None):
119 119 super(AliasManager, self).__init__(shell=shell, config=config)
120 120 self.alias_table = {}
121 121 self.exclude_aliases()
122 122 self.init_aliases()
123 123
124 124 def __contains__(self, name):
125 125 return name in self.alias_table
126 126
127 127 @property
128 128 def aliases(self):
129 129 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
130 130
131 131 def exclude_aliases(self):
132 132 # set of things NOT to alias (keywords, builtins and some magics)
133 133 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
134 134 no_alias.update(set(keyword.kwlist))
135 135 no_alias.update(set(__builtin__.__dict__.keys()))
136 136 self.no_alias = no_alias
137 137
138 138 def init_aliases(self):
139 139 # Load default aliases
140 140 for name, cmd in self.default_aliases:
141 141 self.soft_define_alias(name, cmd)
142 142
143 143 # Load user aliases
144 144 for name, cmd in self.user_aliases:
145 145 self.soft_define_alias(name, cmd)
146 146
147 147 def clear_aliases(self):
148 148 self.alias_table.clear()
149 149
150 150 def soft_define_alias(self, name, cmd):
151 151 """Define an alias, but don't raise on an AliasError."""
152 152 try:
153 153 self.define_alias(name, cmd)
154 154 except AliasError, e:
155 155 error("Invalid alias: %s" % e)
156 156
157 157 def define_alias(self, name, cmd):
158 158 """Define a new alias after validating it.
159 159
160 160 This will raise an :exc:`AliasError` if there are validation
161 161 problems.
162 162 """
163 163 nargs = self.validate_alias(name, cmd)
164 164 self.alias_table[name] = (nargs, cmd)
165 165
166 166 def undefine_alias(self, name):
167 167 if self.alias_table.has_key(name):
168 168 del self.alias_table[name]
169 169
170 170 def validate_alias(self, name, cmd):
171 171 """Validate an alias and return the its number of arguments."""
172 172 if name in self.no_alias:
173 173 raise InvalidAliasError("The name %s can't be aliased "
174 174 "because it is a keyword or builtin." % name)
175 175 if not (isinstance(cmd, basestring)):
176 176 raise InvalidAliasError("An alias command must be a string, "
177 177 "got: %r" % cmd)
178 178 nargs = cmd.count('%s')
179 179 if nargs>0 and cmd.find('%l')>=0:
180 180 raise InvalidAliasError('The %s and %l specifiers are mutually '
181 181 'exclusive in alias definitions.')
182 182 return nargs
183 183
184 184 def call_alias(self, alias, rest=''):
185 185 """Call an alias given its name and the rest of the line."""
186 186 cmd = self.transform_alias(alias, rest)
187 187 try:
188 188 self.shell.system(cmd)
189 189 except:
190 190 self.shell.showtraceback()
191 191
192 192 def transform_alias(self, alias,rest=''):
193 193 """Transform alias to system command string."""
194 194 nargs, cmd = self.alias_table[alias]
195 195
196 196 if ' ' in cmd and os.path.isfile(cmd):
197 197 cmd = '"%s"' % cmd
198 198
199 199 # Expand the %l special to be the user's input line
200 200 if cmd.find('%l') >= 0:
201 201 cmd = cmd.replace('%l', rest)
202 202 rest = ''
203 203 if nargs==0:
204 204 # Simple, argument-less aliases
205 205 cmd = '%s %s' % (cmd, rest)
206 206 else:
207 207 # Handle aliases with positional arguments
208 208 args = rest.split(None, nargs)
209 209 if len(args) < nargs:
210 210 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
211 211 (alias, nargs, len(args)))
212 212 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
213 213 return cmd
214 214
215 215 def expand_alias(self, line):
216 216 """ Expand an alias in the command line
217 217
218 218 Returns the provided command line, possibly with the first word
219 219 (command) translated according to alias expansion rules.
220 220
221 221 [ipython]|16> _ip.expand_aliases("np myfile.txt")
222 222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
223 223 """
224 224
225 225 pre,_,fn,rest = split_user_input(line)
226 226 res = pre + self.expand_aliases(fn, rest)
227 227 return res
228 228
229 229 def expand_aliases(self, fn, rest):
230 230 """Expand multiple levels of aliases:
231 231
232 232 if:
233 233
234 234 alias foo bar /tmp
235 235 alias baz foo
236 236
237 237 then:
238 238
239 239 baz huhhahhei -> bar /tmp huhhahhei
240 240 """
241 241 line = fn + " " + rest
242 242
243 243 done = set()
244 244 while 1:
245 245 pre,_,fn,rest = split_user_input(line, shell_line_split)
246 246 if fn in self.alias_table:
247 247 if fn in done:
248 248 warn("Cyclic alias definition, repeated '%s'" % fn)
249 249 return ""
250 250 done.add(fn)
251 251
252 252 l2 = self.transform_alias(fn, rest)
253 253 if l2 == line:
254 254 break
255 255 # ls -> ls -F should not recurse forever
256 256 if l2.split(None,1)[0] == line.split(None,1)[0]:
257 257 line = l2
258 258 break
259 259 line=l2
260 260 else:
261 261 break
262 262
263 263 return line
@@ -1,70 +1,70 b''
1 1 # encoding: utf-8
2 2 """
3 3 Autocall capabilities for IPython.core.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Thomas Kluyver
10 10
11 11 Notes
12 12 -----
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
16 # Copyright (C) 2008-2011 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Code
29 29 #-----------------------------------------------------------------------------
30 30
31 31 class IPyAutocall(object):
32 32 """ Instances of this class are always autocalled
33 33
34 34 This happens regardless of 'autocall' variable state. Use this to
35 35 develop macro-like mechanisms.
36 36 """
37 37 _ip = None
38 38 rewrite = True
39 39 def __init__(self, ip=None):
40 40 self._ip = ip
41 41
42 42 def set_ip(self, ip):
43 43 """ Will be used to set _ip point to current ipython instance b/f call
44 44
45 45 Override this method if you don't want this to happen.
46 46
47 47 """
48 48 self._ip = ip
49 49
50 50
51 51 class ExitAutocall(IPyAutocall):
52 52 """An autocallable object which will be added to the user namespace so that
53 53 exit, exit(), quit or quit() are all valid ways to close the shell."""
54 54 rewrite = False
55 55
56 56 def __call__(self):
57 57 self._ip.ask_exit()
58 58
59 59 class ZMQExitAutocall(ExitAutocall):
60 60 """Exit IPython. Autocallable, so it needn't be explicitly called.
61 61
62 62 Parameters
63 63 ----------
64 64 keep_kernel : bool
65 65 If True, leave the kernel alive. Otherwise, tell the kernel to exit too
66 66 (default).
67 67 """
68 68 def __call__(self, keep_kernel=False):
69 69 self._ip.keepkernel_on_exit = keep_kernel
70 70 self._ip.ask_exit()
@@ -1,128 +1,128 b''
1 1 """
2 2 A context manager for managing things injected into :mod:`__builtin__`.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 * Fernando Perez
8 8 """
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010 The IPython Development Team.
10 # Copyright (C) 2010-2011 The IPython Development Team.
11 11 #
12 12 # Distributed under the terms of the BSD License.
13 13 #
14 14 # Complete license in the file COPYING.txt, distributed with this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 import __builtin__
22 22
23 23 from IPython.config.configurable import Configurable
24 24
25 25 from IPython.utils.traitlets import Instance
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Classes and functions
29 29 #-----------------------------------------------------------------------------
30 30
31 31 class __BuiltinUndefined(object): pass
32 32 BuiltinUndefined = __BuiltinUndefined()
33 33
34 34 class __HideBuiltin(object): pass
35 35 HideBuiltin = __HideBuiltin()
36 36
37 37
38 38 class BuiltinTrap(Configurable):
39 39
40 40 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
41 41
42 42 def __init__(self, shell=None):
43 43 super(BuiltinTrap, self).__init__(shell=shell, config=None)
44 44 self._orig_builtins = {}
45 45 # We define this to track if a single BuiltinTrap is nested.
46 46 # Only turn off the trap when the outermost call to __exit__ is made.
47 47 self._nested_level = 0
48 48 self.shell = shell
49 49 # builtins we always add - if set to HideBuiltin, they will just
50 50 # be removed instead of being replaced by something else
51 51 self.auto_builtins = {'exit': HideBuiltin,
52 52 'quit': HideBuiltin,
53 53 'get_ipython': self.shell.get_ipython,
54 54 }
55 55 # Recursive reload function
56 56 try:
57 57 from IPython.lib import deepreload
58 58 if self.shell.deep_reload:
59 59 self.auto_builtins['reload'] = deepreload.reload
60 60 else:
61 61 self.auto_builtins['dreload']= deepreload.reload
62 62 except ImportError:
63 63 pass
64 64
65 65 def __enter__(self):
66 66 if self._nested_level == 0:
67 67 self.activate()
68 68 self._nested_level += 1
69 69 # I return self, so callers can use add_builtin in a with clause.
70 70 return self
71 71
72 72 def __exit__(self, type, value, traceback):
73 73 if self._nested_level == 1:
74 74 self.deactivate()
75 75 self._nested_level -= 1
76 76 # Returning False will cause exceptions to propagate
77 77 return False
78 78
79 79 def add_builtin(self, key, value):
80 80 """Add a builtin and save the original."""
81 81 bdict = __builtin__.__dict__
82 82 orig = bdict.get(key, BuiltinUndefined)
83 83 if value is HideBuiltin:
84 84 if orig is not BuiltinUndefined: #same as 'key in bdict'
85 85 self._orig_builtins[key] = orig
86 86 del bdict[key]
87 87 else:
88 88 self._orig_builtins[key] = orig
89 89 bdict[key] = value
90 90
91 91 def remove_builtin(self, key):
92 92 """Remove an added builtin and re-set the original."""
93 93 try:
94 94 orig = self._orig_builtins.pop(key)
95 95 except KeyError:
96 96 pass
97 97 else:
98 98 if orig is BuiltinUndefined:
99 99 del __builtin__.__dict__[key]
100 100 else:
101 101 __builtin__.__dict__[key] = orig
102 102
103 103 def activate(self):
104 104 """Store ipython references in the __builtin__ namespace."""
105 105
106 106 add_builtin = self.add_builtin
107 107 for name, func in self.auto_builtins.iteritems():
108 108 add_builtin(name, func)
109 109
110 110 # Keep in the builtins a flag for when IPython is active. We set it
111 111 # with setdefault so that multiple nested IPythons don't clobber one
112 112 # another.
113 113 __builtin__.__dict__.setdefault('__IPYTHON__active', 0)
114 114
115 115 def deactivate(self):
116 116 """Remove any builtins which might have been added by add_builtins, or
117 117 restore overwritten ones to their previous values."""
118 118 # Note: must iterate over a static keys() list because we'll be
119 119 # mutating the dict itself
120 120 remove_builtin = self.remove_builtin
121 121 for key in self._orig_builtins.keys():
122 122 remove_builtin(key)
123 123 self._orig_builtins.clear()
124 124 self._builtins_added = False
125 125 try:
126 126 del __builtin__.__dict__['__IPYTHON__active']
127 127 except KeyError:
128 128 pass
@@ -1,131 +1,131 b''
1 1 """Compiler tools with improved interactive support.
2 2
3 3 Provides compilation machinery similar to codeop, but with caching support so
4 4 we can provide interactive tracebacks.
5 5
6 6 Authors
7 7 -------
8 8 * Robert Kern
9 9 * Fernando Perez
10 10 * Thomas Kluyver
11 11 """
12 12
13 13 # Note: though it might be more natural to name this module 'compiler', that
14 14 # name is in the stdlib and name collisions with the stdlib tend to produce
15 15 # weird problems (often with third-party tools).
16 16
17 17 #-----------------------------------------------------------------------------
18 # Copyright (C) 2010 The IPython Development Team.
18 # Copyright (C) 2010-2011 The IPython Development Team.
19 19 #
20 20 # Distributed under the terms of the BSD License.
21 21 #
22 22 # The full license is in the file COPYING.txt, distributed with this software.
23 23 #-----------------------------------------------------------------------------
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Imports
27 27 #-----------------------------------------------------------------------------
28 28 from __future__ import print_function
29 29
30 30 # Stdlib imports
31 31 from ast import PyCF_ONLY_AST
32 32 import codeop
33 33 import hashlib
34 34 import linecache
35 35 import time
36 36
37 37 #-----------------------------------------------------------------------------
38 38 # Local utilities
39 39 #-----------------------------------------------------------------------------
40 40
41 41 def code_name(code, number=0):
42 42 """ Compute a (probably) unique name for code for caching.
43 43
44 44 This now expects code to be unicode.
45 45 """
46 46 hash_digest = hashlib.md5(code.encode("utf-8")).hexdigest()
47 47 # Include the number and 12 characters of the hash in the name. It's
48 48 # pretty much impossible that in a single session we'll have collisions
49 49 # even with truncated hashes, and the full one makes tracebacks too long
50 50 return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])
51 51
52 52 #-----------------------------------------------------------------------------
53 53 # Classes and functions
54 54 #-----------------------------------------------------------------------------
55 55
56 56 class CachingCompiler(codeop.Compile):
57 57 """A compiler that caches code compiled from interactive statements.
58 58 """
59 59
60 60 def __init__(self):
61 61 codeop.Compile.__init__(self)
62 62
63 63 # This is ugly, but it must be done this way to allow multiple
64 64 # simultaneous ipython instances to coexist. Since Python itself
65 65 # directly accesses the data structures in the linecache module, and
66 66 # the cache therein is global, we must work with that data structure.
67 67 # We must hold a reference to the original checkcache routine and call
68 68 # that in our own check_cache() below, but the special IPython cache
69 69 # must also be shared by all IPython instances. If we were to hold
70 70 # separate caches (one in each CachingCompiler instance), any call made
71 71 # by Python itself to linecache.checkcache() would obliterate the
72 72 # cached data from the other IPython instances.
73 73 if not hasattr(linecache, '_ipython_cache'):
74 74 linecache._ipython_cache = {}
75 75 if not hasattr(linecache, '_checkcache_ori'):
76 76 linecache._checkcache_ori = linecache.checkcache
77 77 # Now, we must monkeypatch the linecache directly so that parts of the
78 78 # stdlib that call it outside our control go through our codepath
79 79 # (otherwise we'd lose our tracebacks).
80 80 linecache.checkcache = self.check_cache
81 81
82 82 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
83 83 """Parse code to an AST with the current compiler flags active.
84 84
85 85 Arguments are exactly the same as ast.parse (in the standard library),
86 86 and are passed to the built-in compile function."""
87 87 return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
88 88
89 89 def reset_compiler_flags(self):
90 90 """Reset compiler flags to default state."""
91 91 # This value is copied from codeop.Compile.__init__, so if that ever
92 92 # changes, it will need to be updated.
93 93 self.flags = codeop.PyCF_DONT_IMPLY_DEDENT
94 94
95 95 @property
96 96 def compiler_flags(self):
97 97 """Flags currently active in the compilation process.
98 98 """
99 99 return self.flags
100 100
101 101 def cache(self, code, number=0):
102 102 """Make a name for a block of code, and cache the code.
103 103
104 104 Parameters
105 105 ----------
106 106 code : str
107 107 The Python source code to cache.
108 108 number : int
109 109 A number which forms part of the code's name. Used for the execution
110 110 counter.
111 111
112 112 Returns
113 113 -------
114 114 The name of the cached code (as a string). Pass this as the filename
115 115 argument to compilation, so that tracebacks are correctly hooked up.
116 116 """
117 117 name = code_name(code, number)
118 118 entry = (len(code), time.time(),
119 119 [line+'\n' for line in code.splitlines()], name)
120 120 linecache.cache[name] = entry
121 121 linecache._ipython_cache[name] = entry
122 122 return name
123 123
124 124 def check_cache(self, *args):
125 125 """Call linecache.checkcache() safely protecting our cached values.
126 126 """
127 127 # First call the orignal checkcache as intended
128 128 linecache._checkcache_ori(*args)
129 129 # Then, update back the cache with our data, so that tracebacks related
130 130 # to our compiled codes can be produced.
131 131 linecache.cache.update(linecache._ipython_cache)
@@ -1,925 +1,925 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 Original rlcompleter documentation:
10 10
11 11 This requires the latest extension to the readline module (the
12 12 completes keywords, built-ins and globals in __main__; when completing
13 13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 14 completes its attributes.
15 15
16 16 It's very cool to do "import string" type "string.", hit the
17 17 completion key (twice), and see the list of names defined by the
18 18 string module!
19 19
20 20 Tip: to use the tab key as the completion key, call
21 21
22 22 readline.parse_and_bind("tab: complete")
23 23
24 24 Notes:
25 25
26 26 - Exceptions raised by the completer function are *ignored* (and
27 27 generally cause the completion to fail). This is a feature -- since
28 28 readline sets the tty device in raw (or cbreak) mode, printing a
29 29 traceback wouldn't work well without some complicated hoopla to save,
30 30 reset and restore the tty state.
31 31
32 32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 33 application defined code to be executed if an object with a
34 34 __getattr__ hook is found. Since it is the responsibility of the
35 35 application (or the user) to enable this feature, I consider this an
36 36 acceptable risk. More complicated expressions (e.g. function calls or
37 37 indexing operations) are *not* evaluated.
38 38
39 39 - GNU readline is also used by the built-in functions input() and
40 40 raw_input(), and thus these also benefit/suffer from the completer
41 41 features. Clearly an interactive application can benefit by
42 42 specifying its own completer function and using raw_input() for all
43 43 its input.
44 44
45 45 - When the original stdin is not a tty device, GNU readline is never
46 46 used, and this module (and the readline module) are silently inactive.
47 47 """
48 48
49 49 #*****************************************************************************
50 50 #
51 51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 52 # module which is part of the standard Python distribution, I assume that the
53 53 # proper procedure is to maintain its copyright as belonging to the Python
54 54 # Software Foundation (in addition to my own, for all new code).
55 55 #
56 # Copyright (C) 2008-2010 IPython Development Team
56 # Copyright (C) 2008-2011 IPython Development Team
57 57 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
62 62 #
63 63 #*****************************************************************************
64 64 from __future__ import print_function
65 65
66 66 #-----------------------------------------------------------------------------
67 67 # Imports
68 68 #-----------------------------------------------------------------------------
69 69
70 70 import __builtin__
71 71 import __main__
72 72 import glob
73 73 import inspect
74 74 import itertools
75 75 import keyword
76 76 import os
77 77 import re
78 78 import shlex
79 79 import sys
80 80
81 81 from IPython.config.configurable import Configurable
82 82 from IPython.core.error import TryNext
83 83 from IPython.core.prefilter import ESC_MAGIC
84 84 from IPython.utils import generics
85 85 from IPython.utils import io
86 86 from IPython.utils.dir2 import dir2
87 87 from IPython.utils.process import arg_split
88 88 from IPython.utils.traitlets import CBool, Enum
89 89
90 90 #-----------------------------------------------------------------------------
91 91 # Globals
92 92 #-----------------------------------------------------------------------------
93 93
94 94 # Public API
95 95 __all__ = ['Completer','IPCompleter']
96 96
97 97 if sys.platform == 'win32':
98 98 PROTECTABLES = ' '
99 99 else:
100 100 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
101 101
102 102 #-----------------------------------------------------------------------------
103 103 # Main functions and classes
104 104 #-----------------------------------------------------------------------------
105 105
106 106 def has_open_quotes(s):
107 107 """Return whether a string has open quotes.
108 108
109 109 This simply counts whether the number of quote characters of either type in
110 110 the string is odd.
111 111
112 112 Returns
113 113 -------
114 114 If there is an open quote, the quote character is returned. Else, return
115 115 False.
116 116 """
117 117 # We check " first, then ', so complex cases with nested quotes will get
118 118 # the " to take precedence.
119 119 if s.count('"') % 2:
120 120 return '"'
121 121 elif s.count("'") % 2:
122 122 return "'"
123 123 else:
124 124 return False
125 125
126 126
127 127 def protect_filename(s):
128 128 """Escape a string to protect certain characters."""
129 129
130 130 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
131 131 for ch in s])
132 132
133 133
134 134 def mark_dirs(matches):
135 135 """Mark directories in input list by appending '/' to their names."""
136 136 out = []
137 137 isdir = os.path.isdir
138 138 for x in matches:
139 139 if isdir(x):
140 140 out.append(x+'/')
141 141 else:
142 142 out.append(x)
143 143 return out
144 144
145 145
146 146 def expand_user(path):
147 147 """Expand '~'-style usernames in strings.
148 148
149 149 This is similar to :func:`os.path.expanduser`, but it computes and returns
150 150 extra information that will be useful if the input was being used in
151 151 computing completions, and you wish to return the completions with the
152 152 original '~' instead of its expanded value.
153 153
154 154 Parameters
155 155 ----------
156 156 path : str
157 157 String to be expanded. If no ~ is present, the output is the same as the
158 158 input.
159 159
160 160 Returns
161 161 -------
162 162 newpath : str
163 163 Result of ~ expansion in the input path.
164 164 tilde_expand : bool
165 165 Whether any expansion was performed or not.
166 166 tilde_val : str
167 167 The value that ~ was replaced with.
168 168 """
169 169 # Default values
170 170 tilde_expand = False
171 171 tilde_val = ''
172 172 newpath = path
173 173
174 174 if path.startswith('~'):
175 175 tilde_expand = True
176 176 rest = len(path)-1
177 177 newpath = os.path.expanduser(path)
178 178 if rest:
179 179 tilde_val = newpath[:-rest]
180 180 else:
181 181 tilde_val = newpath
182 182
183 183 return newpath, tilde_expand, tilde_val
184 184
185 185
186 186 def compress_user(path, tilde_expand, tilde_val):
187 187 """Does the opposite of expand_user, with its outputs.
188 188 """
189 189 if tilde_expand:
190 190 return path.replace(tilde_val, '~')
191 191 else:
192 192 return path
193 193
194 194
195 195 def single_dir_expand(matches):
196 196 "Recursively expand match lists containing a single dir."
197 197
198 198 if len(matches) == 1 and os.path.isdir(matches[0]):
199 199 # Takes care of links to directories also. Use '/'
200 200 # explicitly, even under Windows, so that name completions
201 201 # don't end up escaped.
202 202 d = matches[0]
203 203 if d[-1] in ['/','\\']:
204 204 d = d[:-1]
205 205
206 206 subdirs = os.listdir(d)
207 207 if subdirs:
208 208 matches = [ (d + '/' + p) for p in subdirs]
209 209 return single_dir_expand(matches)
210 210 else:
211 211 return matches
212 212 else:
213 213 return matches
214 214
215 215
216 216 class Bunch(object): pass
217 217
218 218 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
219 219 GREEDY_DELIMS = ' \r\n'
220 220
221 221 class CompletionSplitter(object):
222 222 """An object to split an input line in a manner similar to readline.
223 223
224 224 By having our own implementation, we can expose readline-like completion in
225 225 a uniform manner to all frontends. This object only needs to be given the
226 226 line of text to be split and the cursor position on said line, and it
227 227 returns the 'word' to be completed on at the cursor after splitting the
228 228 entire line.
229 229
230 230 What characters are used as splitting delimiters can be controlled by
231 231 setting the `delims` attribute (this is a property that internally
232 232 automatically builds the necessary """
233 233
234 234 # Private interface
235 235
236 236 # A string of delimiter characters. The default value makes sense for
237 237 # IPython's most typical usage patterns.
238 238 _delims = DELIMS
239 239
240 240 # The expression (a normal string) to be compiled into a regular expression
241 241 # for actual splitting. We store it as an attribute mostly for ease of
242 242 # debugging, since this type of code can be so tricky to debug.
243 243 _delim_expr = None
244 244
245 245 # The regular expression that does the actual splitting
246 246 _delim_re = None
247 247
248 248 def __init__(self, delims=None):
249 249 delims = CompletionSplitter._delims if delims is None else delims
250 250 self.set_delims(delims)
251 251
252 252 def set_delims(self, delims):
253 253 """Set the delimiters for line splitting."""
254 254 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
255 255 self._delim_re = re.compile(expr)
256 256 self._delims = delims
257 257 self._delim_expr = expr
258 258
259 259 def get_delims(self):
260 260 """Return the string of delimiter characters."""
261 261 return self._delims
262 262
263 263 def split_line(self, line, cursor_pos=None):
264 264 """Split a line of text with a cursor at the given position.
265 265 """
266 266 l = line if cursor_pos is None else line[:cursor_pos]
267 267 return self._delim_re.split(l)[-1]
268 268
269 269
270 270 class Completer(Configurable):
271 271
272 272 greedy = CBool(False, config=True,
273 273 help="""Activate greedy completion
274 274
275 275 This will enable completion on elements of lists, results of function calls, etc.,
276 276 but can be unsafe because the code is actually evaluated on TAB.
277 277 """
278 278 )
279 279
280 280
281 281 def __init__(self, namespace=None, global_namespace=None, config=None, **kwargs):
282 282 """Create a new completer for the command line.
283 283
284 284 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
285 285
286 286 If unspecified, the default namespace where completions are performed
287 287 is __main__ (technically, __main__.__dict__). Namespaces should be
288 288 given as dictionaries.
289 289
290 290 An optional second namespace can be given. This allows the completer
291 291 to handle cases where both the local and global scopes need to be
292 292 distinguished.
293 293
294 294 Completer instances should be used as the completion mechanism of
295 295 readline via the set_completer() call:
296 296
297 297 readline.set_completer(Completer(my_namespace).complete)
298 298 """
299 299
300 300 # Don't bind to namespace quite yet, but flag whether the user wants a
301 301 # specific namespace or to use __main__.__dict__. This will allow us
302 302 # to bind to __main__.__dict__ at completion time, not now.
303 303 if namespace is None:
304 304 self.use_main_ns = 1
305 305 else:
306 306 self.use_main_ns = 0
307 307 self.namespace = namespace
308 308
309 309 # The global namespace, if given, can be bound directly
310 310 if global_namespace is None:
311 311 self.global_namespace = {}
312 312 else:
313 313 self.global_namespace = global_namespace
314 314
315 315 super(Completer, self).__init__(config=config, **kwargs)
316 316
317 317 def complete(self, text, state):
318 318 """Return the next possible completion for 'text'.
319 319
320 320 This is called successively with state == 0, 1, 2, ... until it
321 321 returns None. The completion should begin with 'text'.
322 322
323 323 """
324 324 if self.use_main_ns:
325 325 self.namespace = __main__.__dict__
326 326
327 327 if state == 0:
328 328 if "." in text:
329 329 self.matches = self.attr_matches(text)
330 330 else:
331 331 self.matches = self.global_matches(text)
332 332 try:
333 333 return self.matches[state]
334 334 except IndexError:
335 335 return None
336 336
337 337 def global_matches(self, text):
338 338 """Compute matches when text is a simple name.
339 339
340 340 Return a list of all keywords, built-in functions and names currently
341 341 defined in self.namespace or self.global_namespace that match.
342 342
343 343 """
344 344 #print 'Completer->global_matches, txt=%r' % text # dbg
345 345 matches = []
346 346 match_append = matches.append
347 347 n = len(text)
348 348 for lst in [keyword.kwlist,
349 349 __builtin__.__dict__.keys(),
350 350 self.namespace.keys(),
351 351 self.global_namespace.keys()]:
352 352 for word in lst:
353 353 if word[:n] == text and word != "__builtins__":
354 354 match_append(word)
355 355 return matches
356 356
357 357 def attr_matches(self, text):
358 358 """Compute matches when text contains a dot.
359 359
360 360 Assuming the text is of the form NAME.NAME....[NAME], and is
361 361 evaluatable in self.namespace or self.global_namespace, it will be
362 362 evaluated and its attributes (as revealed by dir()) are used as
363 363 possible completions. (For class instances, class members are are
364 364 also considered.)
365 365
366 366 WARNING: this can still invoke arbitrary C code, if an object
367 367 with a __getattr__ hook is evaluated.
368 368
369 369 """
370 370
371 371 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
372 372 # Another option, seems to work great. Catches things like ''.<tab>
373 373 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
374 374
375 375 if m:
376 376 expr, attr = m.group(1, 3)
377 377 elif self.greedy:
378 378 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
379 379 if not m2:
380 380 return []
381 381 expr, attr = m2.group(1,2)
382 382 else:
383 383 return []
384 384
385 385 try:
386 386 obj = eval(expr, self.namespace)
387 387 except:
388 388 try:
389 389 obj = eval(expr, self.global_namespace)
390 390 except:
391 391 return []
392 392
393 393 words = dir2(obj)
394 394
395 395 try:
396 396 words = generics.complete_object(obj, words)
397 397 except TryNext:
398 398 pass
399 399 except Exception:
400 400 # Silence errors from completion function
401 401 #raise # dbg
402 402 pass
403 403 # Build match list to return
404 404 n = len(attr)
405 405 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
406 406 return res
407 407
408 408
409 409 class IPCompleter(Completer):
410 410 """Extension of the completer class with IPython-specific features"""
411 411
412 412 def _greedy_changed(self, name, old, new):
413 413 """update the splitter and readline delims when greedy is changed"""
414 414 if new:
415 415 self.splitter.set_delims(GREEDY_DELIMS)
416 416 else:
417 417 self.splitter.set_delims(DELIMS)
418 418
419 419 if self.readline:
420 420 self.readline.set_completer_delims(self.splitter.get_delims())
421 421
422 422 merge_completions = CBool(True, config=True,
423 423 help="""Whether to merge completion results into a single list
424 424
425 425 If False, only the completion results from the first non-empty
426 426 completer will be returned.
427 427 """
428 428 )
429 429 omit__names = Enum((0,1,2), default_value=2, config=True,
430 430 help="""Instruct the completer to omit private method names
431 431
432 432 Specifically, when completing on ``object.<tab>``.
433 433
434 434 When 2 [default]: all names that start with '_' will be excluded.
435 435
436 436 When 1: all 'magic' names (``__foo__``) will be excluded.
437 437
438 438 When 0: nothing will be excluded.
439 439 """
440 440 )
441 441
442 442 def __init__(self, shell=None, namespace=None, global_namespace=None,
443 443 alias_table=None, use_readline=True,
444 444 config=None, **kwargs):
445 445 """IPCompleter() -> completer
446 446
447 447 Return a completer object suitable for use by the readline library
448 448 via readline.set_completer().
449 449
450 450 Inputs:
451 451
452 452 - shell: a pointer to the ipython shell itself. This is needed
453 453 because this completer knows about magic functions, and those can
454 454 only be accessed via the ipython instance.
455 455
456 456 - namespace: an optional dict where completions are performed.
457 457
458 458 - global_namespace: secondary optional dict for completions, to
459 459 handle cases (such as IPython embedded inside functions) where
460 460 both Python scopes are visible.
461 461
462 462 - If alias_table is supplied, it should be a dictionary of aliases
463 463 to complete.
464 464
465 465 use_readline : bool, optional
466 466 If true, use the readline library. This completer can still function
467 467 without readline, though in that case callers must provide some extra
468 468 information on each call about the current line."""
469 469
470 470 self.magic_escape = ESC_MAGIC
471 471 self.splitter = CompletionSplitter()
472 472
473 473 # Readline configuration, only used by the rlcompleter method.
474 474 if use_readline:
475 475 # We store the right version of readline so that later code
476 476 import IPython.utils.rlineimpl as readline
477 477 self.readline = readline
478 478 else:
479 479 self.readline = None
480 480
481 481 # _greedy_changed() depends on splitter and readline being defined:
482 482 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
483 483 config=config, **kwargs)
484 484
485 485 # List where completion matches will be stored
486 486 self.matches = []
487 487 self.shell = shell.shell
488 488 if alias_table is None:
489 489 alias_table = {}
490 490 self.alias_table = alias_table
491 491 # Regexp to split filenames with spaces in them
492 492 self.space_name_re = re.compile(r'([^\\] )')
493 493 # Hold a local ref. to glob.glob for speed
494 494 self.glob = glob.glob
495 495
496 496 # Determine if we are running on 'dumb' terminals, like (X)Emacs
497 497 # buffers, to avoid completion problems.
498 498 term = os.environ.get('TERM','xterm')
499 499 self.dumb_terminal = term in ['dumb','emacs']
500 500
501 501 # Special handling of backslashes needed in win32 platforms
502 502 if sys.platform == "win32":
503 503 self.clean_glob = self._clean_glob_win32
504 504 else:
505 505 self.clean_glob = self._clean_glob
506 506
507 507 # All active matcher routines for completion
508 508 self.matchers = [self.python_matches,
509 509 self.file_matches,
510 510 self.magic_matches,
511 511 self.alias_matches,
512 512 self.python_func_kw_matches,
513 513 ]
514 514
515 515 def all_completions(self, text):
516 516 """
517 517 Wrapper around the complete method for the benefit of emacs
518 518 and pydb.
519 519 """
520 520 return self.complete(text)[1]
521 521
522 522 def _clean_glob(self,text):
523 523 return self.glob("%s*" % text)
524 524
525 525 def _clean_glob_win32(self,text):
526 526 return [f.replace("\\","/")
527 527 for f in self.glob("%s*" % text)]
528 528
529 529 def file_matches(self, text):
530 530 """Match filenames, expanding ~USER type strings.
531 531
532 532 Most of the seemingly convoluted logic in this completer is an
533 533 attempt to handle filenames with spaces in them. And yet it's not
534 534 quite perfect, because Python's readline doesn't expose all of the
535 535 GNU readline details needed for this to be done correctly.
536 536
537 537 For a filename with a space in it, the printed completions will be
538 538 only the parts after what's already been typed (instead of the
539 539 full completions, as is normally done). I don't think with the
540 540 current (as of Python 2.3) Python readline it's possible to do
541 541 better."""
542 542
543 543 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
544 544
545 545 # chars that require escaping with backslash - i.e. chars
546 546 # that readline treats incorrectly as delimiters, but we
547 547 # don't want to treat as delimiters in filename matching
548 548 # when escaped with backslash
549 549 if text.startswith('!'):
550 550 text = text[1:]
551 551 text_prefix = '!'
552 552 else:
553 553 text_prefix = ''
554 554
555 555 text_until_cursor = self.text_until_cursor
556 556 # track strings with open quotes
557 557 open_quotes = has_open_quotes(text_until_cursor)
558 558
559 559 if '(' in text_until_cursor or '[' in text_until_cursor:
560 560 lsplit = text
561 561 else:
562 562 try:
563 563 # arg_split ~ shlex.split, but with unicode bugs fixed by us
564 564 lsplit = arg_split(text_until_cursor)[-1]
565 565 except ValueError:
566 566 # typically an unmatched ", or backslash without escaped char.
567 567 if open_quotes:
568 568 lsplit = text_until_cursor.split(open_quotes)[-1]
569 569 else:
570 570 return []
571 571 except IndexError:
572 572 # tab pressed on empty line
573 573 lsplit = ""
574 574
575 575 if not open_quotes and lsplit != protect_filename(lsplit):
576 576 # if protectables are found, do matching on the whole escaped name
577 577 has_protectables = True
578 578 text0,text = text,lsplit
579 579 else:
580 580 has_protectables = False
581 581 text = os.path.expanduser(text)
582 582
583 583 if text == "":
584 584 return [text_prefix + protect_filename(f) for f in self.glob("*")]
585 585
586 586 # Compute the matches from the filesystem
587 587 m0 = self.clean_glob(text.replace('\\',''))
588 588
589 589 if has_protectables:
590 590 # If we had protectables, we need to revert our changes to the
591 591 # beginning of filename so that we don't double-write the part
592 592 # of the filename we have so far
593 593 len_lsplit = len(lsplit)
594 594 matches = [text_prefix + text0 +
595 595 protect_filename(f[len_lsplit:]) for f in m0]
596 596 else:
597 597 if open_quotes:
598 598 # if we have a string with an open quote, we don't need to
599 599 # protect the names at all (and we _shouldn't_, as it
600 600 # would cause bugs when the filesystem call is made).
601 601 matches = m0
602 602 else:
603 603 matches = [text_prefix +
604 604 protect_filename(f) for f in m0]
605 605
606 606 #io.rprint('mm', matches) # dbg
607 607 return mark_dirs(matches)
608 608
609 609 def magic_matches(self, text):
610 610 """Match magics"""
611 611 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
612 612 # Get all shell magics now rather than statically, so magics loaded at
613 613 # runtime show up too
614 614 magics = self.shell.lsmagic()
615 615 pre = self.magic_escape
616 616 baretext = text.lstrip(pre)
617 617 return [ pre+m for m in magics if m.startswith(baretext)]
618 618
619 619 def alias_matches(self, text):
620 620 """Match internal system aliases"""
621 621 #print 'Completer->alias_matches:',text,'lb',self.text_until_cursor # dbg
622 622
623 623 # if we are not in the first 'item', alias matching
624 624 # doesn't make sense - unless we are starting with 'sudo' command.
625 625 main_text = self.text_until_cursor.lstrip()
626 626 if ' ' in main_text and not main_text.startswith('sudo'):
627 627 return []
628 628 text = os.path.expanduser(text)
629 629 aliases = self.alias_table.keys()
630 630 if text == '':
631 631 return aliases
632 632 else:
633 633 return [a for a in aliases if a.startswith(text)]
634 634
635 635 def python_matches(self,text):
636 636 """Match attributes or global python names"""
637 637
638 638 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
639 639 if "." in text:
640 640 try:
641 641 matches = self.attr_matches(text)
642 642 if text.endswith('.') and self.omit__names:
643 643 if self.omit__names == 1:
644 644 # true if txt is _not_ a __ name, false otherwise:
645 645 no__name = (lambda txt:
646 646 re.match(r'.*\.__.*?__',txt) is None)
647 647 else:
648 648 # true if txt is _not_ a _ name, false otherwise:
649 649 no__name = (lambda txt:
650 650 re.match(r'.*\._.*?',txt) is None)
651 651 matches = filter(no__name, matches)
652 652 except NameError:
653 653 # catches <undefined attributes>.<tab>
654 654 matches = []
655 655 else:
656 656 matches = self.global_matches(text)
657 657
658 658 return matches
659 659
660 660 def _default_arguments(self, obj):
661 661 """Return the list of default arguments of obj if it is callable,
662 662 or empty list otherwise."""
663 663
664 664 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
665 665 # for classes, check for __init__,__new__
666 666 if inspect.isclass(obj):
667 667 obj = (getattr(obj,'__init__',None) or
668 668 getattr(obj,'__new__',None))
669 669 # for all others, check if they are __call__able
670 670 elif hasattr(obj, '__call__'):
671 671 obj = obj.__call__
672 672 # XXX: is there a way to handle the builtins ?
673 673 try:
674 674 args,_,_1,defaults = inspect.getargspec(obj)
675 675 if defaults:
676 676 return args[-len(defaults):]
677 677 except TypeError: pass
678 678 return []
679 679
680 680 def python_func_kw_matches(self,text):
681 681 """Match named parameters (kwargs) of the last open function"""
682 682
683 683 if "." in text: # a parameter cannot be dotted
684 684 return []
685 685 try: regexp = self.__funcParamsRegex
686 686 except AttributeError:
687 687 regexp = self.__funcParamsRegex = re.compile(r'''
688 688 '.*?' | # single quoted strings or
689 689 ".*?" | # double quoted strings or
690 690 \w+ | # identifier
691 691 \S # other characters
692 692 ''', re.VERBOSE | re.DOTALL)
693 693 # 1. find the nearest identifier that comes before an unclosed
694 694 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
695 695 tokens = regexp.findall(self.line_buffer)
696 696 tokens.reverse()
697 697 iterTokens = iter(tokens); openPar = 0
698 698 for token in iterTokens:
699 699 if token == ')':
700 700 openPar -= 1
701 701 elif token == '(':
702 702 openPar += 1
703 703 if openPar > 0:
704 704 # found the last unclosed parenthesis
705 705 break
706 706 else:
707 707 return []
708 708 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
709 709 ids = []
710 710 isId = re.compile(r'\w+$').match
711 711 while True:
712 712 try:
713 713 ids.append(iterTokens.next())
714 714 if not isId(ids[-1]):
715 715 ids.pop(); break
716 716 if not iterTokens.next() == '.':
717 717 break
718 718 except StopIteration:
719 719 break
720 720 # lookup the candidate callable matches either using global_matches
721 721 # or attr_matches for dotted names
722 722 if len(ids) == 1:
723 723 callableMatches = self.global_matches(ids[0])
724 724 else:
725 725 callableMatches = self.attr_matches('.'.join(ids[::-1]))
726 726 argMatches = []
727 727 for callableMatch in callableMatches:
728 728 try:
729 729 namedArgs = self._default_arguments(eval(callableMatch,
730 730 self.namespace))
731 731 except:
732 732 continue
733 733 for namedArg in namedArgs:
734 734 if namedArg.startswith(text):
735 735 argMatches.append("%s=" %namedArg)
736 736 return argMatches
737 737
738 738 def dispatch_custom_completer(self, text):
739 739 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
740 740 line = self.line_buffer
741 741 if not line.strip():
742 742 return None
743 743
744 744 # Create a little structure to pass all the relevant information about
745 745 # the current completion to any custom completer.
746 746 event = Bunch()
747 747 event.line = line
748 748 event.symbol = text
749 749 cmd = line.split(None,1)[0]
750 750 event.command = cmd
751 751 event.text_until_cursor = self.text_until_cursor
752 752
753 753 #print "\ncustom:{%s]\n" % event # dbg
754 754
755 755 # for foo etc, try also to find completer for %foo
756 756 if not cmd.startswith(self.magic_escape):
757 757 try_magic = self.custom_completers.s_matches(
758 758 self.magic_escape + cmd)
759 759 else:
760 760 try_magic = []
761 761
762 762 for c in itertools.chain(self.custom_completers.s_matches(cmd),
763 763 try_magic,
764 764 self.custom_completers.flat_matches(self.text_until_cursor)):
765 765 #print "try",c # dbg
766 766 try:
767 767 res = c(event)
768 768 if res:
769 769 # first, try case sensitive match
770 770 withcase = [r for r in res if r.startswith(text)]
771 771 if withcase:
772 772 return withcase
773 773 # if none, then case insensitive ones are ok too
774 774 text_low = text.lower()
775 775 return [r for r in res if r.lower().startswith(text_low)]
776 776 except TryNext:
777 777 pass
778 778
779 779 return None
780 780
781 781 def complete(self, text=None, line_buffer=None, cursor_pos=None):
782 782 """Find completions for the given text and line context.
783 783
784 784 This is called successively with state == 0, 1, 2, ... until it
785 785 returns None. The completion should begin with 'text'.
786 786
787 787 Note that both the text and the line_buffer are optional, but at least
788 788 one of them must be given.
789 789
790 790 Parameters
791 791 ----------
792 792 text : string, optional
793 793 Text to perform the completion on. If not given, the line buffer
794 794 is split using the instance's CompletionSplitter object.
795 795
796 796 line_buffer : string, optional
797 797 If not given, the completer attempts to obtain the current line
798 798 buffer via readline. This keyword allows clients which are
799 799 requesting for text completions in non-readline contexts to inform
800 800 the completer of the entire text.
801 801
802 802 cursor_pos : int, optional
803 803 Index of the cursor in the full line buffer. Should be provided by
804 804 remote frontends where kernel has no access to frontend state.
805 805
806 806 Returns
807 807 -------
808 808 text : str
809 809 Text that was actually used in the completion.
810 810
811 811 matches : list
812 812 A list of completion matches.
813 813 """
814 814 #io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
815 815
816 816 # if the cursor position isn't given, the only sane assumption we can
817 817 # make is that it's at the end of the line (the common case)
818 818 if cursor_pos is None:
819 819 cursor_pos = len(line_buffer) if text is None else len(text)
820 820
821 821 # if text is either None or an empty string, rely on the line buffer
822 822 if not text:
823 823 text = self.splitter.split_line(line_buffer, cursor_pos)
824 824
825 825 # If no line buffer is given, assume the input text is all there was
826 826 if line_buffer is None:
827 827 line_buffer = text
828 828
829 829 self.line_buffer = line_buffer
830 830 self.text_until_cursor = self.line_buffer[:cursor_pos]
831 831 #io.rprint('\nCOMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
832 832
833 833 # Start with a clean slate of completions
834 834 self.matches[:] = []
835 835 custom_res = self.dispatch_custom_completer(text)
836 836 if custom_res is not None:
837 837 # did custom completers produce something?
838 838 self.matches = custom_res
839 839 else:
840 840 # Extend the list of completions with the results of each
841 841 # matcher, so we return results to the user from all
842 842 # namespaces.
843 843 if self.merge_completions:
844 844 self.matches = []
845 845 for matcher in self.matchers:
846 846 try:
847 847 self.matches.extend(matcher(text))
848 848 except:
849 849 # Show the ugly traceback if the matcher causes an
850 850 # exception, but do NOT crash the kernel!
851 851 sys.excepthook(*sys.exc_info())
852 852 else:
853 853 for matcher in self.matchers:
854 854 self.matches = matcher(text)
855 855 if self.matches:
856 856 break
857 857 # FIXME: we should extend our api to return a dict with completions for
858 858 # different types of objects. The rlcomplete() method could then
859 859 # simply collapse the dict into a list for readline, but we'd have
860 860 # richer completion semantics in other evironments.
861 861 self.matches = sorted(set(self.matches))
862 862 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
863 863 return text, self.matches
864 864
865 865 def rlcomplete(self, text, state):
866 866 """Return the state-th possible completion for 'text'.
867 867
868 868 This is called successively with state == 0, 1, 2, ... until it
869 869 returns None. The completion should begin with 'text'.
870 870
871 871 Parameters
872 872 ----------
873 873 text : string
874 874 Text to perform the completion on.
875 875
876 876 state : int
877 877 Counter used by readline.
878 878 """
879 879 if state==0:
880 880
881 881 self.line_buffer = line_buffer = self.readline.get_line_buffer()
882 882 cursor_pos = self.readline.get_endidx()
883 883
884 884 #io.rprint("\nRLCOMPLETE: %r %r %r" %
885 885 # (text, line_buffer, cursor_pos) ) # dbg
886 886
887 887 # if there is only a tab on a line with only whitespace, instead of
888 888 # the mostly useless 'do you want to see all million completions'
889 889 # message, just do the right thing and give the user his tab!
890 890 # Incidentally, this enables pasting of tabbed text from an editor
891 891 # (as long as autoindent is off).
892 892
893 893 # It should be noted that at least pyreadline still shows file
894 894 # completions - is there a way around it?
895 895
896 896 # don't apply this on 'dumb' terminals, such as emacs buffers, so
897 897 # we don't interfere with their own tab-completion mechanism.
898 898 if not (self.dumb_terminal or line_buffer.strip()):
899 899 self.readline.insert_text('\t')
900 900 sys.stdout.flush()
901 901 return None
902 902
903 903 # Note: debugging exceptions that may occur in completion is very
904 904 # tricky, because readline unconditionally silences them. So if
905 905 # during development you suspect a bug in the completion code, turn
906 906 # this flag on temporarily by uncommenting the second form (don't
907 907 # flip the value in the first line, as the '# dbg' marker can be
908 908 # automatically detected and is used elsewhere).
909 909 DEBUG = False
910 910 #DEBUG = True # dbg
911 911 if DEBUG:
912 912 try:
913 913 self.complete(text, line_buffer, cursor_pos)
914 914 except:
915 915 import traceback; traceback.print_exc()
916 916 else:
917 917 # The normal production version is here
918 918
919 919 # This method computes the self.matches array
920 920 self.complete(text, line_buffer, cursor_pos)
921 921
922 922 try:
923 923 return self.matches[state]
924 924 except IndexError:
925 925 return None
@@ -1,347 +1,347 b''
1 1 """Implementations for various useful completers.
2 2
3 3 These are all loaded by default by IPython.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2010 The IPython Development Team.
6 # Copyright (C) 2010-2011 The IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib imports
19 19 import glob
20 20 import inspect
21 21 import os
22 22 import re
23 23 import shlex
24 24 import sys
25 25
26 26 # Third-party imports
27 27 from time import time
28 28 from zipimport import zipimporter
29 29
30 30 # Our own imports
31 31 from IPython.core.completer import expand_user, compress_user
32 32 from IPython.core.error import TryNext
33 33 from IPython.utils import py3compat
34 34
35 35 # FIXME: this should be pulled in with the right call via the component system
36 36 from IPython.core.ipapi import get as get_ipython
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Globals and constants
40 40 #-----------------------------------------------------------------------------
41 41
42 42 # Time in seconds after which the rootmodules will be stored permanently in the
43 43 # ipython ip.db database (kept in the user's .ipython dir).
44 44 TIMEOUT_STORAGE = 2
45 45
46 46 # Time in seconds after which we give up
47 47 TIMEOUT_GIVEUP = 20
48 48
49 49 # Regular expression for the python import statement
50 50 import_re = re.compile(r'.*(\.so|\.py[cod]?)$')
51 51
52 52 # RE for the ipython %run command (python + ipython scripts)
53 53 magic_run_re = re.compile(r'.*(\.ipy|\.py[w]?)$')
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Local utilities
57 57 #-----------------------------------------------------------------------------
58 58
59 59 def shlex_split(x):
60 60 """Helper function to split lines into segments.
61 61 """
62 62 # shlex.split raises an exception if there is a syntax error in sh syntax
63 63 # for example if no closing " is found. This function keeps dropping the
64 64 # last character of the line until shlex.split does not raise
65 65 # an exception. It adds end of the line to the result of shlex.split
66 66 #
67 67 # Example:
68 68 # %run "c:/python -> ['%run','"c:/python']
69 69
70 70 # shlex.split has unicode bugs in Python 2, so encode first to str
71 71 if not py3compat.PY3:
72 72 x = py3compat.cast_bytes(x)
73 73
74 74 endofline = []
75 75 while x != '':
76 76 try:
77 77 comps = shlex.split(x)
78 78 if len(endofline) >= 1:
79 79 comps.append(''.join(endofline))
80 80 return comps
81 81
82 82 except ValueError:
83 83 endofline = [x[-1:]]+endofline
84 84 x = x[:-1]
85 85
86 86 return [''.join(endofline)]
87 87
88 88 def module_list(path):
89 89 """
90 90 Return the list containing the names of the modules available in the given
91 91 folder.
92 92 """
93 93
94 94 if os.path.isdir(path):
95 95 folder_list = os.listdir(path)
96 96 elif path.endswith('.egg'):
97 97 try:
98 98 folder_list = [f for f in zipimporter(path)._files]
99 99 except:
100 100 folder_list = []
101 101 else:
102 102 folder_list = []
103 103
104 104 if not folder_list:
105 105 return []
106 106
107 107 # A few local constants to be used in loops below
108 108 isfile = os.path.isfile
109 109 pjoin = os.path.join
110 110 basename = os.path.basename
111 111
112 112 # Now find actual path matches for packages or modules
113 113 folder_list = [p for p in folder_list
114 114 if isfile(pjoin(path, p,'__init__.py'))
115 115 or import_re.match(p) ]
116 116
117 117 return [basename(p).split('.')[0] for p in folder_list]
118 118
119 119 def get_root_modules():
120 120 """
121 121 Returns a list containing the names of all the modules available in the
122 122 folders of the pythonpath.
123 123 """
124 124 ip = get_ipython()
125 125
126 126 if 'rootmodules' in ip.db:
127 127 return ip.db['rootmodules']
128 128
129 129 t = time()
130 130 store = False
131 131 modules = list(sys.builtin_module_names)
132 132 for path in sys.path:
133 133 modules += module_list(path)
134 134 if time() - t >= TIMEOUT_STORAGE and not store:
135 135 store = True
136 136 print("\nCaching the list of root modules, please wait!")
137 137 print("(This will only be done once - type '%rehashx' to "
138 138 "reset cache!)\n")
139 139 sys.stdout.flush()
140 140 if time() - t > TIMEOUT_GIVEUP:
141 141 print("This is taking too long, we give up.\n")
142 142 ip.db['rootmodules'] = []
143 143 return []
144 144
145 145 modules = set(modules)
146 146 if '__init__' in modules:
147 147 modules.remove('__init__')
148 148 modules = list(modules)
149 149 if store:
150 150 ip.db['rootmodules'] = modules
151 151 return modules
152 152
153 153
154 154 def is_importable(module, attr, only_modules):
155 155 if only_modules:
156 156 return inspect.ismodule(getattr(module, attr))
157 157 else:
158 158 return not(attr[:2] == '__' and attr[-2:] == '__')
159 159
160 160
161 161 def try_import(mod, only_modules=False):
162 162 try:
163 163 m = __import__(mod)
164 164 except:
165 165 return []
166 166 mods = mod.split('.')
167 167 for module in mods[1:]:
168 168 m = getattr(m, module)
169 169
170 170 m_is_init = hasattr(m, '__file__') and '__init__' in m.__file__
171 171
172 172 completions = []
173 173 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
174 174 completions.extend( [attr for attr in dir(m) if
175 175 is_importable(m, attr, only_modules)])
176 176
177 177 completions.extend(getattr(m, '__all__', []))
178 178 if m_is_init:
179 179 completions.extend(module_list(os.path.dirname(m.__file__)))
180 180 completions = set(completions)
181 181 if '__init__' in completions:
182 182 completions.remove('__init__')
183 183 return list(completions)
184 184
185 185
186 186 #-----------------------------------------------------------------------------
187 187 # Completion-related functions.
188 188 #-----------------------------------------------------------------------------
189 189
190 190 def quick_completer(cmd, completions):
191 191 """ Easily create a trivial completer for a command.
192 192
193 193 Takes either a list of completions, or all completions in string (that will
194 194 be split on whitespace).
195 195
196 196 Example::
197 197
198 198 [d:\ipython]|1> import ipy_completers
199 199 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
200 200 [d:\ipython]|3> foo b<TAB>
201 201 bar baz
202 202 [d:\ipython]|3> foo ba
203 203 """
204 204
205 205 if isinstance(completions, basestring):
206 206 completions = completions.split()
207 207
208 208 def do_complete(self, event):
209 209 return completions
210 210
211 211 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
212 212
213 213
214 214 def module_completion(line):
215 215 """
216 216 Returns a list containing the completion possibilities for an import line.
217 217
218 218 The line looks like this :
219 219 'import xml.d'
220 220 'from xml.dom import'
221 221 """
222 222
223 223 words = line.split(' ')
224 224 nwords = len(words)
225 225
226 226 # from whatever <tab> -> 'import '
227 227 if nwords == 3 and words[0] == 'from':
228 228 return ['import ']
229 229
230 230 # 'from xy<tab>' or 'import xy<tab>'
231 231 if nwords < 3 and (words[0] in ['import','from']) :
232 232 if nwords == 1:
233 233 return get_root_modules()
234 234 mod = words[1].split('.')
235 235 if len(mod) < 2:
236 236 return get_root_modules()
237 237 completion_list = try_import('.'.join(mod[:-1]), True)
238 238 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
239 239
240 240 # 'from xyz import abc<tab>'
241 241 if nwords >= 3 and words[0] == 'from':
242 242 mod = words[1]
243 243 return try_import(mod)
244 244
245 245 #-----------------------------------------------------------------------------
246 246 # Completers
247 247 #-----------------------------------------------------------------------------
248 248 # These all have the func(self, event) signature to be used as custom
249 249 # completers
250 250
251 251 def module_completer(self,event):
252 252 """Give completions after user has typed 'import ...' or 'from ...'"""
253 253
254 254 # This works in all versions of python. While 2.5 has
255 255 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
256 256 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
257 257 # of possibly problematic side effects.
258 258 # This search the folders in the sys.path for available modules.
259 259
260 260 return module_completion(event.line)
261 261
262 262 # FIXME: there's a lot of logic common to the run, cd and builtin file
263 263 # completers, that is currently reimplemented in each.
264 264
265 265 def magic_run_completer(self, event):
266 266 """Complete files that end in .py or .ipy for the %run command.
267 267 """
268 268 comps = shlex_split(event.line)
269 269 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
270 270
271 271 #print("\nev=", event) # dbg
272 272 #print("rp=", relpath) # dbg
273 273 #print('comps=', comps) # dbg
274 274
275 275 lglob = glob.glob
276 276 isdir = os.path.isdir
277 277 relpath, tilde_expand, tilde_val = expand_user(relpath)
278 278
279 279 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
280 280
281 281 # Find if the user has already typed the first filename, after which we
282 282 # should complete on all files, since after the first one other files may
283 283 # be arguments to the input script.
284 284
285 285 if filter(magic_run_re.match, comps):
286 286 pys = [f.replace('\\','/') for f in lglob('*')]
287 287 else:
288 288 pys = [f.replace('\\','/')
289 289 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
290 290 lglob(relpath + '*.pyw')]
291 291 #print('run comp:', dirs+pys) # dbg
292 292 return [compress_user(p, tilde_expand, tilde_val) for p in dirs+pys]
293 293
294 294
295 295 def cd_completer(self, event):
296 296 """Completer function for cd, which only returns directories."""
297 297 ip = get_ipython()
298 298 relpath = event.symbol
299 299
300 300 #print(event) # dbg
301 301 if event.line.endswith('-b') or ' -b ' in event.line:
302 302 # return only bookmark completions
303 303 bkms = self.db.get('bookmarks', None)
304 304 if bkms:
305 305 return bkms.keys()
306 306 else:
307 307 return []
308 308
309 309 if event.symbol == '-':
310 310 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
311 311 # jump in directory history by number
312 312 fmt = '-%0' + width_dh +'d [%s]'
313 313 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
314 314 if len(ents) > 1:
315 315 return ents
316 316 return []
317 317
318 318 if event.symbol.startswith('--'):
319 319 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
320 320
321 321 # Expand ~ in path and normalize directory separators.
322 322 relpath, tilde_expand, tilde_val = expand_user(relpath)
323 323 relpath = relpath.replace('\\','/')
324 324
325 325 found = []
326 326 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
327 327 if os.path.isdir(f)]:
328 328 if ' ' in d:
329 329 # we don't want to deal with any of that, complex code
330 330 # for this is elsewhere
331 331 raise TryNext
332 332
333 333 found.append(d)
334 334
335 335 if not found:
336 336 if os.path.isdir(relpath):
337 337 return [compress_user(relpath, tilde_expand, tilde_val)]
338 338
339 339 # if no completions so far, try bookmarks
340 340 bks = self.db.get('bookmarks',{}).iterkeys()
341 341 bkmatches = [s for s in bks if s.startswith(event.symbol)]
342 342 if bkmatches:
343 343 return bkmatches
344 344
345 345 raise TryNext
346 346
347 347 return [compress_user(p, tilde_expand, tilde_val) for p in found]
@@ -1,214 +1,214 b''
1 1 # encoding: utf-8
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian E. Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2008-2011 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 os
23 23 import sys
24 24 import traceback
25 25 from pprint import pformat
26 26
27 27 from IPython.core import ultratb
28 28 from IPython.core.release import author_email
29 29 from IPython.utils.sysinfo import sys_info
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Code
33 33 #-----------------------------------------------------------------------------
34 34
35 35 # Template for the user message.
36 36 _default_message_template = """\
37 37 Oops, {app_name} crashed. We do our best to make it stable, but...
38 38
39 39 A crash report was automatically generated with the following information:
40 40 - A verbatim copy of the crash traceback.
41 41 - A copy of your input history during this session.
42 42 - Data on your current {app_name} configuration.
43 43
44 44 It was left in the file named:
45 45 \t'{crash_report_fname}'
46 46 If you can email this file to the developers, the information in it will help
47 47 them in understanding and correcting the problem.
48 48
49 49 You can mail it to: {contact_name} at {contact_email}
50 50 with the subject '{app_name} Crash Report'.
51 51
52 52 If you want to do it now, the following command will work (under Unix):
53 53 mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname}
54 54
55 55 To ensure accurate tracking of this issue, please file a report about it at:
56 56 {bug_tracker}
57 57 """
58 58
59 59 _lite_message_template = """
60 60 If you suspect this is an IPython bug, please report it at:
61 61 https://github.com/ipython/ipython/issues
62 62 or send an email to the mailing list at {email}
63 63
64 64 You can print a more detailed traceback right now with "%tb", or use "%debug"
65 65 to interactively debug it.
66 66
67 67 Extra-detailed tracebacks for bug-reporting purposes can be enabled via:
68 68 {config}Application.verbose_crash=True
69 69 """
70 70
71 71
72 72 class CrashHandler(object):
73 73 """Customizable crash handlers for IPython applications.
74 74
75 75 Instances of this class provide a :meth:`__call__` method which can be
76 76 used as a ``sys.excepthook``. The :meth:`__call__` signature is::
77 77
78 78 def __call__(self, etype, evalue, etb)
79 79 """
80 80
81 81 message_template = _default_message_template
82 82 section_sep = '\n\n'+'*'*75+'\n\n'
83 83
84 84 def __init__(self, app, contact_name=None, contact_email=None,
85 85 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
86 86 """Create a new crash handler
87 87
88 88 Parameters
89 89 ----------
90 90 app : Application
91 91 A running :class:`Application` instance, which will be queried at
92 92 crash time for internal information.
93 93
94 94 contact_name : str
95 95 A string with the name of the person to contact.
96 96
97 97 contact_email : str
98 98 A string with the email address of the contact.
99 99
100 100 bug_tracker : str
101 101 A string with the URL for your project's bug tracker.
102 102
103 103 show_crash_traceback : bool
104 104 If false, don't print the crash traceback on stderr, only generate
105 105 the on-disk report
106 106
107 107 Non-argument instance attributes:
108 108
109 109 These instances contain some non-argument attributes which allow for
110 110 further customization of the crash handler's behavior. Please see the
111 111 source for further details.
112 112 """
113 113 self.crash_report_fname = "Crash_report_%s.txt" % app.name
114 114 self.app = app
115 115 self.call_pdb = call_pdb
116 116 #self.call_pdb = True # dbg
117 117 self.show_crash_traceback = show_crash_traceback
118 118 self.info = dict(app_name = app.name,
119 119 contact_name = contact_name,
120 120 contact_email = contact_email,
121 121 bug_tracker = bug_tracker,
122 122 crash_report_fname = self.crash_report_fname)
123 123
124 124
125 125 def __call__(self, etype, evalue, etb):
126 126 """Handle an exception, call for compatible with sys.excepthook"""
127 127
128 128 # do not allow the crash handler to be called twice without reinstalling it
129 129 # this prevents unlikely errors in the crash handling from entering an
130 130 # infinite loop.
131 131 sys.excepthook = sys.__excepthook__
132 132
133 133 # Report tracebacks shouldn't use color in general (safer for users)
134 134 color_scheme = 'NoColor'
135 135
136 136 # Use this ONLY for developer debugging (keep commented out for release)
137 137 #color_scheme = 'Linux' # dbg
138 138 try:
139 139 rptdir = self.app.ipython_dir
140 140 except:
141 141 rptdir = os.getcwdu()
142 142 if rptdir is None or not os.path.isdir(rptdir):
143 143 rptdir = os.getcwdu()
144 144 report_name = os.path.join(rptdir,self.crash_report_fname)
145 145 # write the report filename into the instance dict so it can get
146 146 # properly expanded out in the user message template
147 147 self.crash_report_fname = report_name
148 148 self.info['crash_report_fname'] = report_name
149 149 TBhandler = ultratb.VerboseTB(
150 150 color_scheme=color_scheme,
151 151 long_header=1,
152 152 call_pdb=self.call_pdb,
153 153 )
154 154 if self.call_pdb:
155 155 TBhandler(etype,evalue,etb)
156 156 return
157 157 else:
158 158 traceback = TBhandler.text(etype,evalue,etb,context=31)
159 159
160 160 # print traceback to screen
161 161 if self.show_crash_traceback:
162 162 print >> sys.stderr, traceback
163 163
164 164 # and generate a complete report on disk
165 165 try:
166 166 report = open(report_name,'w')
167 167 except:
168 168 print >> sys.stderr, 'Could not create crash report on disk.'
169 169 return
170 170
171 171 # Inform user on stderr of what happened
172 172 print >> sys.stderr, '\n'+'*'*70+'\n'
173 173 print >> sys.stderr, self.message_template.format(**self.info)
174 174
175 175 # Construct report on disk
176 176 report.write(self.make_report(traceback))
177 177 report.close()
178 178 raw_input("Hit <Enter> to quit (your terminal may close):")
179 179
180 180 def make_report(self,traceback):
181 181 """Return a string containing a crash report."""
182 182
183 183 sec_sep = self.section_sep
184 184
185 185 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
186 186 rpt_add = report.append
187 187 rpt_add(sys_info())
188 188
189 189 try:
190 190 config = pformat(self.app.config)
191 191 rpt_add(sec_sep)
192 192 rpt_add('Application name: %s\n\n' % self.app_name)
193 193 rpt_add('Current user configuration structure:\n\n')
194 194 rpt_add(config)
195 195 except:
196 196 pass
197 197 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
198 198
199 199 return ''.join(report)
200 200
201 201
202 202 def crash_handler_lite(etype, evalue, tb):
203 203 """a light excepthook, adding a small message to the usual traceback"""
204 204 traceback.print_exception(etype, evalue, tb)
205 205
206 206 from IPython.core.interactiveshell import InteractiveShell
207 207 if InteractiveShell.initialized():
208 208 # we are in a Shell environment, give %magic example
209 209 config = "%config "
210 210 else:
211 211 # we are not in a shell, show generic config
212 212 config = "c."
213 213 print >> sys.stderr, _lite_message_template.format(email=author_email, config=config)
214 214
@@ -1,407 +1,407 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2010 The IPython Development Team
10 # Copyright (C) 2008-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from .displaypub import (
21 21 publish_pretty, publish_html,
22 22 publish_latex, publish_svg,
23 23 publish_png, publish_json,
24 24 publish_javascript, publish_jpeg
25 25 )
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Main functions
29 29 #-----------------------------------------------------------------------------
30 30
31 31 def display(*objs, **kwargs):
32 32 """Display a Python object in all frontends.
33 33
34 34 By default all representations will be computed and sent to the frontends.
35 35 Frontends can decide which representation is used and how.
36 36
37 37 Parameters
38 38 ----------
39 39 objs : tuple of objects
40 40 The Python objects to display.
41 41 include : list or tuple, optional
42 42 A list of format type strings (MIME types) to include in the
43 43 format data dict. If this is set *only* the format types included
44 44 in this list will be computed.
45 45 exclude : list or tuple, optional
46 46 A list of format type string (MIME types) to exclue in the format
47 47 data dict. If this is set all format types will be computed,
48 48 except for those included in this argument.
49 49 """
50 50 include = kwargs.get('include')
51 51 exclude = kwargs.get('exclude')
52 52
53 53 from IPython.core.interactiveshell import InteractiveShell
54 54 inst = InteractiveShell.instance()
55 55 format = inst.display_formatter.format
56 56 publish = inst.display_pub.publish
57 57
58 58 for obj in objs:
59 59 format_dict = format(obj, include=include, exclude=exclude)
60 60 publish('IPython.core.display.display', format_dict)
61 61
62 62
63 63 def display_pretty(*objs, **kwargs):
64 64 """Display the pretty (default) representation of an object.
65 65
66 66 Parameters
67 67 ----------
68 68 objs : tuple of objects
69 69 The Python objects to display, or if raw=True raw text data to
70 70 display.
71 71 raw : bool
72 72 Are the data objects raw data or Python objects that need to be
73 73 formatted before display? [default: False]
74 74 """
75 75 raw = kwargs.pop('raw',False)
76 76 if raw:
77 77 for obj in objs:
78 78 publish_pretty(obj)
79 79 else:
80 80 display(*objs, include=['text/plain'])
81 81
82 82
83 83 def display_html(*objs, **kwargs):
84 84 """Display the HTML representation of an object.
85 85
86 86 Parameters
87 87 ----------
88 88 objs : tuple of objects
89 89 The Python objects to display, or if raw=True raw HTML data to
90 90 display.
91 91 raw : bool
92 92 Are the data objects raw data or Python objects that need to be
93 93 formatted before display? [default: False]
94 94 """
95 95 raw = kwargs.pop('raw',False)
96 96 if raw:
97 97 for obj in objs:
98 98 publish_html(obj)
99 99 else:
100 100 display(*objs, include=['text/plain','text/html'])
101 101
102 102
103 103 def display_svg(*objs, **kwargs):
104 104 """Display the SVG representation of an object.
105 105
106 106 Parameters
107 107 ----------
108 108 objs : tuple of objects
109 109 The Python objects to display, or if raw=True raw svg data to
110 110 display.
111 111 raw : bool
112 112 Are the data objects raw data or Python objects that need to be
113 113 formatted before display? [default: False]
114 114 """
115 115 raw = kwargs.pop('raw',False)
116 116 if raw:
117 117 for obj in objs:
118 118 publish_svg(obj)
119 119 else:
120 120 display(*objs, include=['text/plain','image/svg+xml'])
121 121
122 122
123 123 def display_png(*objs, **kwargs):
124 124 """Display the PNG representation of an object.
125 125
126 126 Parameters
127 127 ----------
128 128 objs : tuple of objects
129 129 The Python objects to display, or if raw=True raw png data to
130 130 display.
131 131 raw : bool
132 132 Are the data objects raw data or Python objects that need to be
133 133 formatted before display? [default: False]
134 134 """
135 135 raw = kwargs.pop('raw',False)
136 136 if raw:
137 137 for obj in objs:
138 138 publish_png(obj)
139 139 else:
140 140 display(*objs, include=['text/plain','image/png'])
141 141
142 142
143 143 def display_jpeg(*objs, **kwargs):
144 144 """Display the JPEG representation of an object.
145 145
146 146 Parameters
147 147 ----------
148 148 objs : tuple of objects
149 149 The Python objects to display, or if raw=True raw JPEG data to
150 150 display.
151 151 raw : bool
152 152 Are the data objects raw data or Python objects that need to be
153 153 formatted before display? [default: False]
154 154 """
155 155 raw = kwargs.pop('raw',False)
156 156 if raw:
157 157 for obj in objs:
158 158 publish_jpeg(obj)
159 159 else:
160 160 display(*objs, include=['text/plain','image/jpeg'])
161 161
162 162
163 163 def display_latex(*objs, **kwargs):
164 164 """Display the LaTeX representation of an object.
165 165
166 166 Parameters
167 167 ----------
168 168 objs : tuple of objects
169 169 The Python objects to display, or if raw=True raw latex data to
170 170 display.
171 171 raw : bool
172 172 Are the data objects raw data or Python objects that need to be
173 173 formatted before display? [default: False]
174 174 """
175 175 raw = kwargs.pop('raw',False)
176 176 if raw:
177 177 for obj in objs:
178 178 publish_latex(obj)
179 179 else:
180 180 display(*objs, include=['text/plain','text/latex'])
181 181
182 182
183 183 def display_json(*objs, **kwargs):
184 184 """Display the JSON representation of an object.
185 185
186 186 Parameters
187 187 ----------
188 188 objs : tuple of objects
189 189 The Python objects to display, or if raw=True raw json data to
190 190 display.
191 191 raw : bool
192 192 Are the data objects raw data or Python objects that need to be
193 193 formatted before display? [default: False]
194 194 """
195 195 raw = kwargs.pop('raw',False)
196 196 if raw:
197 197 for obj in objs:
198 198 publish_json(obj)
199 199 else:
200 200 display(*objs, include=['text/plain','application/json'])
201 201
202 202
203 203 def display_javascript(*objs, **kwargs):
204 204 """Display the Javascript representation of an object.
205 205
206 206 Parameters
207 207 ----------
208 208 objs : tuple of objects
209 209 The Python objects to display, or if raw=True raw javascript data to
210 210 display.
211 211 raw : bool
212 212 Are the data objects raw data or Python objects that need to be
213 213 formatted before display? [default: False]
214 214 """
215 215 raw = kwargs.pop('raw',False)
216 216 if raw:
217 217 for obj in objs:
218 218 publish_javascript(obj)
219 219 else:
220 220 display(*objs, include=['text/plain','application/javascript'])
221 221
222 222 #-----------------------------------------------------------------------------
223 223 # Smart classes
224 224 #-----------------------------------------------------------------------------
225 225
226 226
227 227 class DisplayObject(object):
228 228 """An object that wraps data to be displayed."""
229 229
230 230 _read_flags = 'r'
231 231
232 232 def __init__(self, data=None, url=None, filename=None):
233 233 """Create a display object given raw data.
234 234
235 235 When this object is returned by an expression or passed to the
236 236 display function, it will result in the data being displayed
237 237 in the frontend. The MIME type of the data should match the
238 238 subclasses used, so the Png subclass should be used for 'image/png'
239 239 data. If the data is a URL, the data will first be downloaded
240 240 and then displayed. If
241 241
242 242 Parameters
243 243 ----------
244 244 data : unicode, str or bytes
245 245 The raw data or a URL to download the data from.
246 246 url : unicode
247 247 A URL to download the data from.
248 248 filename : unicode
249 249 Path to a local file to load the data from.
250 250 """
251 251 if data is not None and data.startswith('http'):
252 252 self.url = data
253 253 self.filename = None
254 254 self.data = None
255 255 else:
256 256 self.data = data
257 257 self.url = url
258 258 self.filename = None if filename is None else unicode(filename)
259 259 self.reload()
260 260
261 261 def reload(self):
262 262 """Reload the raw data from file or URL."""
263 263 if self.filename is not None:
264 264 with open(self.filename, self._read_flags) as f:
265 265 self.data = f.read()
266 266 elif self.url is not None:
267 267 try:
268 268 import urllib2
269 269 response = urllib2.urlopen(self.url)
270 270 self.data = response.read()
271 271 # extract encoding from header, if there is one:
272 272 encoding = None
273 273 for sub in response.headers['content-type'].split(';'):
274 274 sub = sub.strip()
275 275 if sub.startswith('charset'):
276 276 encoding = sub.split('=')[-1].strip()
277 277 break
278 278 # decode data, if an encoding was specified
279 279 if encoding:
280 280 self.data = self.data.decode(encoding, 'replace')
281 281 except:
282 282 self.data = None
283 283
284 284 class Pretty(DisplayObject):
285 285
286 286 def _repr_pretty_(self):
287 287 return self.data
288 288
289 289
290 290 class HTML(DisplayObject):
291 291
292 292 def _repr_html_(self):
293 293 return self.data
294 294
295 295
296 296 class Math(DisplayObject):
297 297
298 298 def _repr_latex_(self):
299 299 return self.data
300 300
301 301
302 302 class SVG(DisplayObject):
303 303
304 304 def _repr_svg_(self):
305 305 return self.data
306 306
307 307
308 308 class JSON(DisplayObject):
309 309
310 310 def _repr_json_(self):
311 311 return self.data
312 312
313 313
314 314 class Javascript(DisplayObject):
315 315
316 316 def _repr_javascript_(self):
317 317 return self.data
318 318
319 319
320 320 class Image(DisplayObject):
321 321
322 322 _read_flags = 'rb'
323 323
324 324 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=False):
325 325 """Create a display an PNG/JPEG image given raw data.
326 326
327 327 When this object is returned by an expression or passed to the
328 328 display function, it will result in the image being displayed
329 329 in the frontend.
330 330
331 331 Parameters
332 332 ----------
333 333 data : unicode, str or bytes
334 334 The raw data or a URL to download the data from.
335 335 url : unicode
336 336 A URL to download the data from.
337 337 filename : unicode
338 338 Path to a local file to load the data from.
339 339 format : unicode
340 340 The format of the image data (png/jpeg/jpg). If a filename or URL is given
341 341 for format will be inferred from the filename extension.
342 342 embed : bool
343 343 Should the image data be embedded in the notebook using a data URI (True)
344 344 or be loaded using an <img> tag. Set this to True if you want the image
345 345 to be viewable later with no internet connection. If a filename is given
346 346 embed is always set to True.
347 347 """
348 348 if filename is not None:
349 349 ext = self._find_ext(filename)
350 350 elif url is not None:
351 351 ext = self._find_ext(url)
352 352 elif data.startswith('http'):
353 353 ext = self._find_ext(data)
354 354 else:
355 355 ext = None
356 356 if ext is not None:
357 357 if ext == u'jpg' or ext == u'jpeg':
358 358 format = u'jpeg'
359 359 if ext == u'png':
360 360 format = u'png'
361 361 self.format = unicode(format).lower()
362 362 self.embed = True if filename is not None else embed
363 363 super(Image, self).__init__(data=data, url=url, filename=filename)
364 364
365 365 def reload(self):
366 366 """Reload the raw data from file or URL."""
367 367 if self.embed:
368 368 super(Image,self).reload()
369 369
370 370 def _repr_html_(self):
371 371 if not self.embed:
372 372 return u'<img src="%s" />' % self.url
373 373
374 374 def _repr_png_(self):
375 375 if self.embed and self.format == u'png':
376 376 return self.data
377 377
378 378 def _repr_jpeg_(self):
379 379 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
380 380 return self.data
381 381
382 382 def _find_ext(self, s):
383 383 return unicode(s.split('.')[-1].lower())
384 384
385 385
386 386 def clear_output(stdout=True, stderr=True, other=True):
387 387 """Clear the output of the current cell receiving output.
388 388
389 389 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
390 390 produced by display()) can be excluded from the clear event.
391 391
392 392 By default, everything is cleared.
393 393
394 394 Parameters
395 395 ----------
396 396 stdout : bool [default: True]
397 397 Whether to clear stdout.
398 398 stderr : bool [default: True]
399 399 Whether to clear stderr.
400 400 other : bool [default: True]
401 401 Whether to clear everything else that is not stdout/stderr
402 402 (e.g. figures,images,HTML, any result of display()).
403 403 """
404 404 from IPython.core.interactiveshell import InteractiveShell
405 405 InteractiveShell.instance().display_pub.clear_output(
406 406 stdout=stdout, stderr=stderr, other=other,
407 407 )
@@ -1,70 +1,70 b''
1 1 # encoding: utf-8
2 2 """
3 3 A context manager for handling sys.displayhook.
4 4
5 5 Authors:
6 6
7 7 * Robert Kern
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2008-2011 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 sys
23 23
24 24 from IPython.config.configurable import Configurable
25 25 from IPython.utils.traitlets import Any
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Classes and functions
29 29 #-----------------------------------------------------------------------------
30 30
31 31
32 32 class DisplayTrap(Configurable):
33 33 """Object to manage sys.displayhook.
34 34
35 35 This came from IPython.core.kernel.display_hook, but is simplified
36 36 (no callbacks or formatters) until more of the core is refactored.
37 37 """
38 38
39 39 hook = Any
40 40
41 41 def __init__(self, hook=None):
42 42 super(DisplayTrap, self).__init__(hook=hook, config=None)
43 43 self.old_hook = None
44 44 # We define this to track if a single BuiltinTrap is nested.
45 45 # Only turn off the trap when the outermost call to __exit__ is made.
46 46 self._nested_level = 0
47 47
48 48 def __enter__(self):
49 49 if self._nested_level == 0:
50 50 self.set()
51 51 self._nested_level += 1
52 52 return self
53 53
54 54 def __exit__(self, type, value, traceback):
55 55 if self._nested_level == 1:
56 56 self.unset()
57 57 self._nested_level -= 1
58 58 # Returning False will cause exceptions to propagate
59 59 return False
60 60
61 61 def set(self):
62 62 """Set the hook."""
63 63 if sys.displayhook is not self.hook:
64 64 self.old_hook = sys.displayhook
65 65 sys.displayhook = self.hook
66 66
67 67 def unset(self):
68 68 """Unset the hook."""
69 69 sys.displayhook = self.old_hook
70 70
@@ -1,329 +1,329 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Displayhook for IPython.
3 3
4 4 This defines a callable class that IPython uses for `sys.displayhook`.
5 5
6 6 Authors:
7 7
8 8 * Fernando Perez
9 9 * Brian Granger
10 10 * Robert Kern
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2010 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
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 __builtin__
26 26
27 27 from IPython.config.configurable import Configurable
28 28 from IPython.core import prompts
29 29 from IPython.utils import io
30 30 from IPython.utils.traitlets import Instance, List
31 31 from IPython.utils.warn import warn
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Main displayhook class
35 35 #-----------------------------------------------------------------------------
36 36
37 37 # TODO: The DisplayHook class should be split into two classes, one that
38 38 # manages the prompts and their synchronization and another that just does the
39 39 # displayhook logic and calls into the prompt manager.
40 40
41 41 # TODO: Move the various attributes (cache_size, colors, input_sep,
42 42 # output_sep, output_sep2, ps1, ps2, ps_out, pad_left). Some of these are also
43 43 # attributes of InteractiveShell. They should be on ONE object only and the
44 44 # other objects should ask that one object for their values.
45 45
46 46 class DisplayHook(Configurable):
47 47 """The custom IPython displayhook to replace sys.displayhook.
48 48
49 49 This class does many things, but the basic idea is that it is a callable
50 50 that gets called anytime user code returns a value.
51 51
52 52 Currently this class does more than just the displayhook logic and that
53 53 extra logic should eventually be moved out of here.
54 54 """
55 55
56 56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57 57
58 58 def __init__(self, shell=None, cache_size=1000,
59 59 colors='NoColor', input_sep='\n',
60 60 output_sep='\n', output_sep2='',
61 61 ps1 = None, ps2 = None, ps_out = None, pad_left=True,
62 62 config=None):
63 63 super(DisplayHook, self).__init__(shell=shell, config=config)
64 64
65 65 cache_size_min = 3
66 66 if cache_size <= 0:
67 67 self.do_full_cache = 0
68 68 cache_size = 0
69 69 elif cache_size < cache_size_min:
70 70 self.do_full_cache = 0
71 71 cache_size = 0
72 72 warn('caching was disabled (min value for cache size is %s).' %
73 73 cache_size_min,level=3)
74 74 else:
75 75 self.do_full_cache = 1
76 76
77 77 self.cache_size = cache_size
78 78 self.input_sep = input_sep
79 79
80 80 # we need a reference to the user-level namespace
81 81 self.shell = shell
82 82
83 83 # Set input prompt strings and colors
84 84 if cache_size == 0:
85 85 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
86 86 or ps1.find(r'\N') > -1:
87 87 ps1 = '>>> '
88 88 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
89 89 or ps2.find(r'\N') > -1:
90 90 ps2 = '... '
91 91 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
92 92 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
93 93 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
94 94
95 95 self.color_table = prompts.PromptColors
96 96 self.prompt1 = prompts.Prompt1(self,sep=input_sep,prompt=self.ps1_str,
97 97 pad_left=pad_left)
98 98 self.prompt2 = prompts.Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
99 99 self.prompt_out = prompts.PromptOut(self,sep='',prompt=self.ps_out_str,
100 100 pad_left=pad_left)
101 101 self.set_colors(colors)
102 102
103 103 # Store the last prompt string each time, we need it for aligning
104 104 # continuation and auto-rewrite prompts
105 105 self.last_prompt = ''
106 106 self.output_sep = output_sep
107 107 self.output_sep2 = output_sep2
108 108 self._,self.__,self.___ = '','',''
109 109
110 110 # these are deliberately global:
111 111 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
112 112 self.shell.user_ns.update(to_user_ns)
113 113
114 114 @property
115 115 def prompt_count(self):
116 116 return self.shell.execution_count
117 117
118 118 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
119 119 if p_str is None:
120 120 if self.do_full_cache:
121 121 return cache_def
122 122 else:
123 123 return no_cache_def
124 124 else:
125 125 return p_str
126 126
127 127 def set_colors(self, colors):
128 128 """Set the active color scheme and configure colors for the three
129 129 prompt subsystems."""
130 130
131 131 # FIXME: This modifying of the global prompts.prompt_specials needs
132 132 # to be fixed. We need to refactor all of the prompts stuff to use
133 133 # proper configuration and traits notifications.
134 134 if colors.lower()=='nocolor':
135 135 prompts.prompt_specials = prompts.prompt_specials_nocolor
136 136 else:
137 137 prompts.prompt_specials = prompts.prompt_specials_color
138 138
139 139 self.color_table.set_active_scheme(colors)
140 140 self.prompt1.set_colors()
141 141 self.prompt2.set_colors()
142 142 self.prompt_out.set_colors()
143 143
144 144 #-------------------------------------------------------------------------
145 145 # Methods used in __call__. Override these methods to modify the behavior
146 146 # of the displayhook.
147 147 #-------------------------------------------------------------------------
148 148
149 149 def check_for_underscore(self):
150 150 """Check if the user has set the '_' variable by hand."""
151 151 # If something injected a '_' variable in __builtin__, delete
152 152 # ipython's automatic one so we don't clobber that. gettext() in
153 153 # particular uses _, so we need to stay away from it.
154 154 if '_' in __builtin__.__dict__:
155 155 try:
156 156 del self.shell.user_ns['_']
157 157 except KeyError:
158 158 pass
159 159
160 160 def quiet(self):
161 161 """Should we silence the display hook because of ';'?"""
162 162 # do not print output if input ends in ';'
163 163 try:
164 164 cell = self.shell.history_manager.input_hist_parsed[self.prompt_count]
165 165 if cell.rstrip().endswith(';'):
166 166 return True
167 167 except IndexError:
168 168 # some uses of ipshellembed may fail here
169 169 pass
170 170 return False
171 171
172 172 def start_displayhook(self):
173 173 """Start the displayhook, initializing resources."""
174 174 pass
175 175
176 176 def write_output_prompt(self):
177 177 """Write the output prompt.
178 178
179 179 The default implementation simply writes the prompt to
180 180 ``io.stdout``.
181 181 """
182 182 # Use write, not print which adds an extra space.
183 183 io.stdout.write(self.output_sep)
184 184 outprompt = str(self.prompt_out)
185 185 if self.do_full_cache:
186 186 io.stdout.write(outprompt)
187 187
188 188 def compute_format_data(self, result):
189 189 """Compute format data of the object to be displayed.
190 190
191 191 The format data is a generalization of the :func:`repr` of an object.
192 192 In the default implementation the format data is a :class:`dict` of
193 193 key value pair where the keys are valid MIME types and the values
194 194 are JSON'able data structure containing the raw data for that MIME
195 195 type. It is up to frontends to determine pick a MIME to to use and
196 196 display that data in an appropriate manner.
197 197
198 198 This method only computes the format data for the object and should
199 199 NOT actually print or write that to a stream.
200 200
201 201 Parameters
202 202 ----------
203 203 result : object
204 204 The Python object passed to the display hook, whose format will be
205 205 computed.
206 206
207 207 Returns
208 208 -------
209 209 format_data : dict
210 210 A :class:`dict` whose keys are valid MIME types and values are
211 211 JSON'able raw data for that MIME type. It is recommended that
212 212 all return values of this should always include the "text/plain"
213 213 MIME type representation of the object.
214 214 """
215 215 return self.shell.display_formatter.format(result)
216 216
217 217 def write_format_data(self, format_dict):
218 218 """Write the format data dict to the frontend.
219 219
220 220 This default version of this method simply writes the plain text
221 221 representation of the object to ``io.stdout``. Subclasses should
222 222 override this method to send the entire `format_dict` to the
223 223 frontends.
224 224
225 225 Parameters
226 226 ----------
227 227 format_dict : dict
228 228 The format dict for the object passed to `sys.displayhook`.
229 229 """
230 230 # We want to print because we want to always make sure we have a
231 231 # newline, even if all the prompt separators are ''. This is the
232 232 # standard IPython behavior.
233 233 result_repr = format_dict['text/plain']
234 234 if '\n' in result_repr:
235 235 # So that multi-line strings line up with the left column of
236 236 # the screen, instead of having the output prompt mess up
237 237 # their first line.
238 238 # We use the ps_out_str template instead of the expanded prompt
239 239 # because the expansion may add ANSI escapes that will interfere
240 240 # with our ability to determine whether or not we should add
241 241 # a newline.
242 242 if self.ps_out_str and not self.ps_out_str.endswith('\n'):
243 243 # But avoid extraneous empty lines.
244 244 result_repr = '\n' + result_repr
245 245
246 246 print >>io.stdout, result_repr
247 247
248 248 def update_user_ns(self, result):
249 249 """Update user_ns with various things like _, __, _1, etc."""
250 250
251 251 # Avoid recursive reference when displaying _oh/Out
252 252 if result is not self.shell.user_ns['_oh']:
253 253 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
254 254 warn('Output cache limit (currently '+
255 255 `self.cache_size`+' entries) hit.\n'
256 256 'Flushing cache and resetting history counter...\n'
257 257 'The only history variables available will be _,__,___ and _1\n'
258 258 'with the current result.')
259 259
260 260 self.flush()
261 261 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
262 262 # we cause buggy behavior for things like gettext).
263 263
264 264 if '_' not in __builtin__.__dict__:
265 265 self.___ = self.__
266 266 self.__ = self._
267 267 self._ = result
268 268 self.shell.user_ns.update({'_':self._,
269 269 '__':self.__,
270 270 '___':self.___})
271 271
272 272 # hackish access to top-level namespace to create _1,_2... dynamically
273 273 to_main = {}
274 274 if self.do_full_cache:
275 275 new_result = '_'+`self.prompt_count`
276 276 to_main[new_result] = result
277 277 self.shell.user_ns.update(to_main)
278 278 self.shell.user_ns['_oh'][self.prompt_count] = result
279 279
280 280 def log_output(self, format_dict):
281 281 """Log the output."""
282 282 if self.shell.logger.log_output:
283 283 self.shell.logger.log_write(format_dict['text/plain'], 'output')
284 284 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
285 285 format_dict['text/plain']
286 286
287 287 def finish_displayhook(self):
288 288 """Finish up all displayhook activities."""
289 289 io.stdout.write(self.output_sep2)
290 290 io.stdout.flush()
291 291
292 292 def __call__(self, result=None):
293 293 """Printing with history cache management.
294 294
295 295 This is invoked everytime the interpreter needs to print, and is
296 296 activated by setting the variable sys.displayhook to it.
297 297 """
298 298 self.check_for_underscore()
299 299 if result is not None and not self.quiet():
300 300 self.start_displayhook()
301 301 self.write_output_prompt()
302 302 format_dict = self.compute_format_data(result)
303 303 self.write_format_data(format_dict)
304 304 self.update_user_ns(result)
305 305 self.log_output(format_dict)
306 306 self.finish_displayhook()
307 307
308 308 def flush(self):
309 309 if not self.do_full_cache:
310 310 raise ValueError,"You shouldn't have reached the cache flush "\
311 311 "if full caching is not enabled!"
312 312 # delete auto-generated vars from global namespace
313 313
314 314 for n in range(1,self.prompt_count + 1):
315 315 key = '_'+`n`
316 316 try:
317 317 del self.shell.user_ns[key]
318 318 except: pass
319 319 self.shell.user_ns['_oh'].clear()
320 320
321 321 # Release our own references to objects:
322 322 self._, self.__, self.___ = '', '', ''
323 323
324 324 if '_' not in __builtin__.__dict__:
325 325 self.shell.user_ns.update({'_':None,'__':None, '___':None})
326 326 import gc
327 327 # TODO: Is this really needed?
328 328 gc.collect()
329 329
@@ -1,302 +1,302 b''
1 1 """An interface for publishing rich data to frontends.
2 2
3 3 There are two components of the display system:
4 4
5 5 * Display formatters, which take a Python object and compute the
6 6 representation of the object in various formats (text, HTML, SVg, etc.).
7 7 * The display publisher that is used to send the representation data to the
8 8 various frontends.
9 9
10 10 This module defines the logic display publishing. The display publisher uses
11 11 the ``display_data`` message type that is defined in the IPython messaging
12 12 spec.
13 13
14 14 Authors:
15 15
16 16 * Brian Granger
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2008-2010 The IPython Development Team
20 # Copyright (C) 2008-2011 The IPython Development Team
21 21 #
22 22 # Distributed under the terms of the BSD License. The full license is in
23 23 # the file COPYING, distributed as part of this software.
24 24 #-----------------------------------------------------------------------------
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Imports
28 28 #-----------------------------------------------------------------------------
29 29
30 30 from __future__ import print_function
31 31
32 32 from IPython.config.configurable import Configurable
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Main payload class
36 36 #-----------------------------------------------------------------------------
37 37
38 38 class DisplayPublisher(Configurable):
39 39 """A traited class that publishes display data to frontends.
40 40
41 41 Instances of this class are created by the main IPython object and should
42 42 be accessed there.
43 43 """
44 44
45 45 def _validate_data(self, source, data, metadata=None):
46 46 """Validate the display data.
47 47
48 48 Parameters
49 49 ----------
50 50 source : str
51 51 The fully dotted name of the callable that created the data, like
52 52 :func:`foo.bar.my_formatter`.
53 53 data : dict
54 54 The formata data dictionary.
55 55 metadata : dict
56 56 Any metadata for the data.
57 57 """
58 58
59 59 if not isinstance(source, basestring):
60 60 raise TypeError('source must be a str, got: %r' % source)
61 61 if not isinstance(data, dict):
62 62 raise TypeError('data must be a dict, got: %r' % data)
63 63 if metadata is not None:
64 64 if not isinstance(metadata, dict):
65 65 raise TypeError('metadata must be a dict, got: %r' % data)
66 66
67 67 def publish(self, source, data, metadata=None):
68 68 """Publish data and metadata to all frontends.
69 69
70 70 See the ``display_data`` message in the messaging documentation for
71 71 more details about this message type.
72 72
73 73 The following MIME types are currently implemented:
74 74
75 75 * text/plain
76 76 * text/html
77 77 * text/latex
78 78 * application/json
79 79 * application/javascript
80 80 * image/png
81 81 * image/jpeg
82 82 * image/svg+xml
83 83
84 84 Parameters
85 85 ----------
86 86 source : str
87 87 A string that give the function or method that created the data,
88 88 such as 'IPython.core.page'.
89 89 data : dict
90 90 A dictionary having keys that are valid MIME types (like
91 91 'text/plain' or 'image/svg+xml') and values that are the data for
92 92 that MIME type. The data itself must be a JSON'able data
93 93 structure. Minimally all data should have the 'text/plain' data,
94 94 which can be displayed by all frontends. If more than the plain
95 95 text is given, it is up to the frontend to decide which
96 96 representation to use.
97 97 metadata : dict
98 98 A dictionary for metadata related to the data. This can contain
99 99 arbitrary key, value pairs that frontends can use to interpret
100 100 the data.
101 101 """
102 102 from IPython.utils import io
103 103 # The default is to simply write the plain text data using io.stdout.
104 104 if data.has_key('text/plain'):
105 105 print(data['text/plain'], file=io.stdout)
106 106
107 107 def clear_output(self, stdout=True, stderr=True, other=True):
108 108 """Clear the output of the cell receiving output."""
109 109 pass
110 110
111 111
112 112 def publish_display_data(source, data, metadata=None):
113 113 """Publish data and metadata to all frontends.
114 114
115 115 See the ``display_data`` message in the messaging documentation for
116 116 more details about this message type.
117 117
118 118 The following MIME types are currently implemented:
119 119
120 120 * text/plain
121 121 * text/html
122 122 * text/latex
123 123 * application/json
124 124 * application/javascript
125 125 * image/png
126 126 * image/jpeg
127 127 * image/svg+xml
128 128
129 129 Parameters
130 130 ----------
131 131 source : str
132 132 A string that give the function or method that created the data,
133 133 such as 'IPython.core.page'.
134 134 data : dict
135 135 A dictionary having keys that are valid MIME types (like
136 136 'text/plain' or 'image/svg+xml') and values that are the data for
137 137 that MIME type. The data itself must be a JSON'able data
138 138 structure. Minimally all data should have the 'text/plain' data,
139 139 which can be displayed by all frontends. If more than the plain
140 140 text is given, it is up to the frontend to decide which
141 141 representation to use.
142 142 metadata : dict
143 143 A dictionary for metadata related to the data. This can contain
144 144 arbitrary key, value pairs that frontends can use to interpret
145 145 the data.
146 146 """
147 147 from IPython.core.interactiveshell import InteractiveShell
148 148 InteractiveShell.instance().display_pub.publish(
149 149 source,
150 150 data,
151 151 metadata
152 152 )
153 153
154 154
155 155 def publish_pretty(data, metadata=None):
156 156 """Publish raw text data to all frontends.
157 157
158 158 Parameters
159 159 ----------
160 160 data : unicode
161 161 The raw text data to publish.
162 162 metadata : dict
163 163 A dictionary for metadata related to the data. This can contain
164 164 arbitrary key, value pairs that frontends can use to interpret
165 165 the data.
166 166 """
167 167 publish_display_data(
168 168 u'IPython.core.displaypub.publish_pretty',
169 169 {'text/plain':data},
170 170 metadata=metadata
171 171 )
172 172
173 173
174 174 def publish_html(data, metadata=None):
175 175 """Publish raw HTML data to all frontends.
176 176
177 177 Parameters
178 178 ----------
179 179 data : unicode
180 180 The raw HTML data to publish.
181 181 metadata : dict
182 182 A dictionary for metadata related to the data. This can contain
183 183 arbitrary key, value pairs that frontends can use to interpret
184 184 the data.
185 185 """
186 186 publish_display_data(
187 187 u'IPython.core.displaypub.publish_html',
188 188 {'text/html':data},
189 189 metadata=metadata
190 190 )
191 191
192 192
193 193 def publish_latex(data, metadata=None):
194 194 """Publish raw LaTeX data to all frontends.
195 195
196 196 Parameters
197 197 ----------
198 198 data : unicode
199 199 The raw LaTeX data to publish.
200 200 metadata : dict
201 201 A dictionary for metadata related to the data. This can contain
202 202 arbitrary key, value pairs that frontends can use to interpret
203 203 the data.
204 204 """
205 205 publish_display_data(
206 206 u'IPython.core.displaypub.publish_latex',
207 207 {'text/latex':data},
208 208 metadata=metadata
209 209 )
210 210
211 211 def publish_png(data, metadata=None):
212 212 """Publish raw binary PNG data to all frontends.
213 213
214 214 Parameters
215 215 ----------
216 216 data : str/bytes
217 217 The raw binary PNG data to publish.
218 218 metadata : dict
219 219 A dictionary for metadata related to the data. This can contain
220 220 arbitrary key, value pairs that frontends can use to interpret
221 221 the data.
222 222 """
223 223 publish_display_data(
224 224 u'IPython.core.displaypub.publish_png',
225 225 {'image/png':data},
226 226 metadata=metadata
227 227 )
228 228
229 229
230 230 def publish_jpeg(data, metadata=None):
231 231 """Publish raw binary JPEG data to all frontends.
232 232
233 233 Parameters
234 234 ----------
235 235 data : str/bytes
236 236 The raw binary JPEG data to publish.
237 237 metadata : dict
238 238 A dictionary for metadata related to the data. This can contain
239 239 arbitrary key, value pairs that frontends can use to interpret
240 240 the data.
241 241 """
242 242 publish_display_data(
243 243 u'IPython.core.displaypub.publish_jpeg',
244 244 {'image/jpeg':data},
245 245 metadata=metadata
246 246 )
247 247
248 248
249 249 def publish_svg(data, metadata=None):
250 250 """Publish raw SVG data to all frontends.
251 251
252 252 Parameters
253 253 ----------
254 254 data : unicode
255 255 The raw SVG data to publish.
256 256 metadata : dict
257 257 A dictionary for metadata related to the data. This can contain
258 258 arbitrary key, value pairs that frontends can use to interpret
259 259 the data.
260 260 """
261 261 publish_display_data(
262 262 u'IPython.core.displaypub.publish_svg',
263 263 {'image/svg+xml':data},
264 264 metadata=metadata
265 265 )
266 266
267 267 def publish_json(data, metadata=None):
268 268 """Publish raw JSON data to all frontends.
269 269
270 270 Parameters
271 271 ----------
272 272 data : unicode
273 273 The raw JSON data to publish.
274 274 metadata : dict
275 275 A dictionary for metadata related to the data. This can contain
276 276 arbitrary key, value pairs that frontends can use to interpret
277 277 the data.
278 278 """
279 279 publish_display_data(
280 280 u'IPython.core.displaypub.publish_json',
281 281 {'application/json':data},
282 282 metadata=metadata
283 283 )
284 284
285 285 def publish_javascript(data, metadata=None):
286 286 """Publish raw Javascript data to all frontends.
287 287
288 288 Parameters
289 289 ----------
290 290 data : unicode
291 291 The raw Javascript data to publish.
292 292 metadata : dict
293 293 A dictionary for metadata related to the data. This can contain
294 294 arbitrary key, value pairs that frontends can use to interpret
295 295 the data.
296 296 """
297 297 publish_display_data(
298 298 u'IPython.core.displaypub.publish_javascript',
299 299 {'application/javascript':data},
300 300 metadata=metadata
301 301 )
302 302
@@ -1,59 +1,59 b''
1 1 # encoding: utf-8
2 2 """
3 3 Global exception classes for IPython.core.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Min Ragan-Kelley
10 10
11 11 Notes
12 12 -----
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
16 # Copyright (C) 2008-2011 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Exception classes
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class IPythonCoreError(Exception):
31 31 pass
32 32
33 33
34 34 class TryNext(IPythonCoreError):
35 35 """Try next hook exception.
36 36
37 37 Raise this in your hook function to indicate that the next hook handler
38 38 should be used to handle the operation. If you pass arguments to the
39 39 constructor those arguments will be used by the next hook instead of the
40 40 original ones.
41 41 """
42 42
43 43 def __init__(self, *args, **kwargs):
44 44 self.args = args
45 45 self.kwargs = kwargs
46 46
47 47 class UsageError(IPythonCoreError):
48 48 """Error in magic function arguments, etc.
49 49
50 50 Something that probably won't warrant a full traceback, but should
51 51 nevertheless interrupt a macro / batch file.
52 52 """
53 53
54 54 class StdinNotImplementedError(IPythonCoreError, NotImplementedError):
55 55 """raw_input was requested in a context where it is not supported
56 56
57 57 For use in IPython kernels, where only some frontends may support
58 58 stdin requests.
59 59 """
@@ -1,125 +1,125 b''
1 1 # encoding: utf-8
2 2 """A class for managing IPython extensions.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 import os
21 21 import sys
22 22
23 23 from IPython.config.configurable import Configurable
24 24 from IPython.utils.traitlets import Instance
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Main class
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class ExtensionManager(Configurable):
31 31 """A class to manage IPython extensions.
32 32
33 33 An IPython extension is an importable Python module that has
34 34 a function with the signature::
35 35
36 36 def load_ipython_extension(ipython):
37 37 # Do things with ipython
38 38
39 39 This function is called after your extension is imported and the
40 40 currently active :class:`InteractiveShell` instance is passed as
41 41 the only argument. You can do anything you want with IPython at
42 42 that point, including defining new magic and aliases, adding new
43 43 components, etc.
44 44
45 45 The :func:`load_ipython_extension` will be called again is you
46 46 load or reload the extension again. It is up to the extension
47 47 author to add code to manage that.
48 48
49 49 You can put your extension modules anywhere you want, as long as
50 50 they can be imported by Python's standard import mechanism. However,
51 51 to make it easy to write extensions, you can also put your extensions
52 52 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
53 53 is added to ``sys.path`` automatically.
54 54 """
55 55
56 56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57 57
58 58 def __init__(self, shell=None, config=None):
59 59 super(ExtensionManager, self).__init__(shell=shell, config=config)
60 60 self.shell.on_trait_change(
61 61 self._on_ipython_dir_changed, 'ipython_dir'
62 62 )
63 63
64 64 def __del__(self):
65 65 self.shell.on_trait_change(
66 66 self._on_ipython_dir_changed, 'ipython_dir', remove=True
67 67 )
68 68
69 69 @property
70 70 def ipython_extension_dir(self):
71 71 return os.path.join(self.shell.ipython_dir, u'extensions')
72 72
73 73 def _on_ipython_dir_changed(self):
74 74 if not os.path.isdir(self.ipython_extension_dir):
75 75 os.makedirs(self.ipython_extension_dir, mode = 0777)
76 76
77 77 def load_extension(self, module_str):
78 78 """Load an IPython extension by its module name.
79 79
80 80 If :func:`load_ipython_extension` returns anything, this function
81 81 will return that object.
82 82 """
83 83 from IPython.utils.syspathcontext import prepended_to_syspath
84 84
85 85 if module_str not in sys.modules:
86 86 with prepended_to_syspath(self.ipython_extension_dir):
87 87 __import__(module_str)
88 88 mod = sys.modules[module_str]
89 89 return self._call_load_ipython_extension(mod)
90 90
91 91 def unload_extension(self, module_str):
92 92 """Unload an IPython extension by its module name.
93 93
94 94 This function looks up the extension's name in ``sys.modules`` and
95 95 simply calls ``mod.unload_ipython_extension(self)``.
96 96 """
97 97 if module_str in sys.modules:
98 98 mod = sys.modules[module_str]
99 99 self._call_unload_ipython_extension(mod)
100 100
101 101 def reload_extension(self, module_str):
102 102 """Reload an IPython extension by calling reload.
103 103
104 104 If the module has not been loaded before,
105 105 :meth:`InteractiveShell.load_extension` is called. Otherwise
106 106 :func:`reload` is called and then the :func:`load_ipython_extension`
107 107 function of the module, if it exists is called.
108 108 """
109 109 from IPython.utils.syspathcontext import prepended_to_syspath
110 110
111 111 with prepended_to_syspath(self.ipython_extension_dir):
112 112 if module_str in sys.modules:
113 113 mod = sys.modules[module_str]
114 114 reload(mod)
115 115 self._call_load_ipython_extension(mod)
116 116 else:
117 117 self.load_extension(module_str)
118 118
119 119 def _call_load_ipython_extension(self, mod):
120 120 if hasattr(mod, 'load_ipython_extension'):
121 121 return mod.load_ipython_extension(self.shell)
122 122
123 123 def _call_unload_ipython_extension(self, mod):
124 124 if hasattr(mod, 'unload_ipython_extension'):
125 125 return mod.unload_ipython_extension(self.shell)
@@ -1,620 +1,620 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4
5 5 Authors:
6 6
7 7 * Robert Kern
8 8 * Brian Granger
9 9 """
10 10 #-----------------------------------------------------------------------------
11 # Copyright (c) 2010, IPython Development Team.
11 # Copyright (C) 2010-2011, IPython Development Team.
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # Stdlib imports
23 23 import abc
24 24 import sys
25 25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
26 26 from StringIO import StringIO
27 27
28 28 # Our own imports
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.lib import pretty
31 31 from IPython.utils.traitlets import Bool, Dict, Integer, Unicode, CUnicode, ObjectName
32 32 from IPython.utils.py3compat import unicode_to_str
33 33
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # The main DisplayFormatter class
37 37 #-----------------------------------------------------------------------------
38 38
39 39
40 40 class DisplayFormatter(Configurable):
41 41
42 42 # When set to true only the default plain text formatter will be used.
43 43 plain_text_only = Bool(False, config=True)
44 44
45 45 # A dict of formatter whose keys are format types (MIME types) and whose
46 46 # values are subclasses of BaseFormatter.
47 47 formatters = Dict()
48 48 def _formatters_default(self):
49 49 """Activate the default formatters."""
50 50 formatter_classes = [
51 51 PlainTextFormatter,
52 52 HTMLFormatter,
53 53 SVGFormatter,
54 54 PNGFormatter,
55 55 JPEGFormatter,
56 56 LatexFormatter,
57 57 JSONFormatter,
58 58 JavascriptFormatter
59 59 ]
60 60 d = {}
61 61 for cls in formatter_classes:
62 62 f = cls(config=self.config)
63 63 d[f.format_type] = f
64 64 return d
65 65
66 66 def format(self, obj, include=None, exclude=None):
67 67 """Return a format data dict for an object.
68 68
69 69 By default all format types will be computed.
70 70
71 71 The following MIME types are currently implemented:
72 72
73 73 * text/plain
74 74 * text/html
75 75 * text/latex
76 76 * application/json
77 77 * application/javascript
78 78 * image/png
79 79 * image/jpeg
80 80 * image/svg+xml
81 81
82 82 Parameters
83 83 ----------
84 84 obj : object
85 85 The Python object whose format data will be computed.
86 86 include : list or tuple, optional
87 87 A list of format type strings (MIME types) to include in the
88 88 format data dict. If this is set *only* the format types included
89 89 in this list will be computed.
90 90 exclude : list or tuple, optional
91 91 A list of format type string (MIME types) to exclue in the format
92 92 data dict. If this is set all format types will be computed,
93 93 except for those included in this argument.
94 94
95 95 Returns
96 96 -------
97 97 format_dict : dict
98 98 A dictionary of key/value pairs, one or each format that was
99 99 generated for the object. The keys are the format types, which
100 100 will usually be MIME type strings and the values and JSON'able
101 101 data structure containing the raw data for the representation in
102 102 that format.
103 103 """
104 104 format_dict = {}
105 105
106 106 # If plain text only is active
107 107 if self.plain_text_only:
108 108 formatter = self.formatters['text/plain']
109 109 try:
110 110 data = formatter(obj)
111 111 except:
112 112 # FIXME: log the exception
113 113 raise
114 114 if data is not None:
115 115 format_dict['text/plain'] = data
116 116 return format_dict
117 117
118 118 for format_type, formatter in self.formatters.items():
119 119 if include is not None:
120 120 if format_type not in include:
121 121 continue
122 122 if exclude is not None:
123 123 if format_type in exclude:
124 124 continue
125 125 try:
126 126 data = formatter(obj)
127 127 except:
128 128 # FIXME: log the exception
129 129 raise
130 130 if data is not None:
131 131 format_dict[format_type] = data
132 132 return format_dict
133 133
134 134 @property
135 135 def format_types(self):
136 136 """Return the format types (MIME types) of the active formatters."""
137 137 return self.formatters.keys()
138 138
139 139
140 140 #-----------------------------------------------------------------------------
141 141 # Formatters for specific format types (text, html, svg, etc.)
142 142 #-----------------------------------------------------------------------------
143 143
144 144
145 145 class FormatterABC(object):
146 146 """ Abstract base class for Formatters.
147 147
148 148 A formatter is a callable class that is responsible for computing the
149 149 raw format data for a particular format type (MIME type). For example,
150 150 an HTML formatter would have a format type of `text/html` and would return
151 151 the HTML representation of the object when called.
152 152 """
153 153 __metaclass__ = abc.ABCMeta
154 154
155 155 # The format type of the data returned, usually a MIME type.
156 156 format_type = 'text/plain'
157 157
158 158 # Is the formatter enabled...
159 159 enabled = True
160 160
161 161 @abc.abstractmethod
162 162 def __call__(self, obj):
163 163 """Return a JSON'able representation of the object.
164 164
165 165 If the object cannot be formatted by this formatter, then return None
166 166 """
167 167 try:
168 168 return repr(obj)
169 169 except TypeError:
170 170 return None
171 171
172 172
173 173 class BaseFormatter(Configurable):
174 174 """A base formatter class that is configurable.
175 175
176 176 This formatter should usually be used as the base class of all formatters.
177 177 It is a traited :class:`Configurable` class and includes an extensible
178 178 API for users to determine how their objects are formatted. The following
179 179 logic is used to find a function to format an given object.
180 180
181 181 1. The object is introspected to see if it has a method with the name
182 182 :attr:`print_method`. If is does, that object is passed to that method
183 183 for formatting.
184 184 2. If no print method is found, three internal dictionaries are consulted
185 185 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
186 186 and :attr:`deferred_printers`.
187 187
188 188 Users should use these dictionaries to register functions that will be
189 189 used to compute the format data for their objects (if those objects don't
190 190 have the special print methods). The easiest way of using these
191 191 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
192 192 methods.
193 193
194 194 If no function/callable is found to compute the format data, ``None`` is
195 195 returned and this format type is not used.
196 196 """
197 197
198 198 format_type = Unicode('text/plain')
199 199
200 200 enabled = Bool(True, config=True)
201 201
202 202 print_method = ObjectName('__repr__')
203 203
204 204 # The singleton printers.
205 205 # Maps the IDs of the builtin singleton objects to the format functions.
206 206 singleton_printers = Dict(config=True)
207 207 def _singleton_printers_default(self):
208 208 return {}
209 209
210 210 # The type-specific printers.
211 211 # Map type objects to the format functions.
212 212 type_printers = Dict(config=True)
213 213 def _type_printers_default(self):
214 214 return {}
215 215
216 216 # The deferred-import type-specific printers.
217 217 # Map (modulename, classname) pairs to the format functions.
218 218 deferred_printers = Dict(config=True)
219 219 def _deferred_printers_default(self):
220 220 return {}
221 221
222 222 def __call__(self, obj):
223 223 """Compute the format for an object."""
224 224 if self.enabled:
225 225 obj_id = id(obj)
226 226 try:
227 227 obj_class = getattr(obj, '__class__', None) or type(obj)
228 228 # First try to find registered singleton printers for the type.
229 229 try:
230 230 printer = self.singleton_printers[obj_id]
231 231 except (TypeError, KeyError):
232 232 pass
233 233 else:
234 234 return printer(obj)
235 235 # Next look for type_printers.
236 236 for cls in pretty._get_mro(obj_class):
237 237 if cls in self.type_printers:
238 238 return self.type_printers[cls](obj)
239 239 else:
240 240 printer = self._in_deferred_types(cls)
241 241 if printer is not None:
242 242 return printer(obj)
243 243 # Finally look for special method names.
244 244 if hasattr(obj_class, self.print_method):
245 245 printer = getattr(obj_class, self.print_method)
246 246 return printer(obj)
247 247 return None
248 248 except Exception:
249 249 pass
250 250 else:
251 251 return None
252 252
253 253 def for_type(self, typ, func):
254 254 """Add a format function for a given type.
255 255
256 256 Parameters
257 257 -----------
258 258 typ : class
259 259 The class of the object that will be formatted using `func`.
260 260 func : callable
261 261 The callable that will be called to compute the format data. The
262 262 call signature of this function is simple, it must take the
263 263 object to be formatted and return the raw data for the given
264 264 format. Subclasses may use a different call signature for the
265 265 `func` argument.
266 266 """
267 267 oldfunc = self.type_printers.get(typ, None)
268 268 if func is not None:
269 269 # To support easy restoration of old printers, we need to ignore
270 270 # Nones.
271 271 self.type_printers[typ] = func
272 272 return oldfunc
273 273
274 274 def for_type_by_name(self, type_module, type_name, func):
275 275 """Add a format function for a type specified by the full dotted
276 276 module and name of the type, rather than the type of the object.
277 277
278 278 Parameters
279 279 ----------
280 280 type_module : str
281 281 The full dotted name of the module the type is defined in, like
282 282 ``numpy``.
283 283 type_name : str
284 284 The name of the type (the class name), like ``dtype``
285 285 func : callable
286 286 The callable that will be called to compute the format data. The
287 287 call signature of this function is simple, it must take the
288 288 object to be formatted and return the raw data for the given
289 289 format. Subclasses may use a different call signature for the
290 290 `func` argument.
291 291 """
292 292 key = (type_module, type_name)
293 293 oldfunc = self.deferred_printers.get(key, None)
294 294 if func is not None:
295 295 # To support easy restoration of old printers, we need to ignore
296 296 # Nones.
297 297 self.deferred_printers[key] = func
298 298 return oldfunc
299 299
300 300 def _in_deferred_types(self, cls):
301 301 """
302 302 Check if the given class is specified in the deferred type registry.
303 303
304 304 Returns the printer from the registry if it exists, and None if the
305 305 class is not in the registry. Successful matches will be moved to the
306 306 regular type registry for future use.
307 307 """
308 308 mod = getattr(cls, '__module__', None)
309 309 name = getattr(cls, '__name__', None)
310 310 key = (mod, name)
311 311 printer = None
312 312 if key in self.deferred_printers:
313 313 # Move the printer over to the regular registry.
314 314 printer = self.deferred_printers.pop(key)
315 315 self.type_printers[cls] = printer
316 316 return printer
317 317
318 318
319 319 class PlainTextFormatter(BaseFormatter):
320 320 """The default pretty-printer.
321 321
322 322 This uses :mod:`IPython.external.pretty` to compute the format data of
323 323 the object. If the object cannot be pretty printed, :func:`repr` is used.
324 324 See the documentation of :mod:`IPython.external.pretty` for details on
325 325 how to write pretty printers. Here is a simple example::
326 326
327 327 def dtype_pprinter(obj, p, cycle):
328 328 if cycle:
329 329 return p.text('dtype(...)')
330 330 if hasattr(obj, 'fields'):
331 331 if obj.fields is None:
332 332 p.text(repr(obj))
333 333 else:
334 334 p.begin_group(7, 'dtype([')
335 335 for i, field in enumerate(obj.descr):
336 336 if i > 0:
337 337 p.text(',')
338 338 p.breakable()
339 339 p.pretty(field)
340 340 p.end_group(7, '])')
341 341 """
342 342
343 343 # The format type of data returned.
344 344 format_type = Unicode('text/plain')
345 345
346 346 # This subclass ignores this attribute as it always need to return
347 347 # something.
348 348 enabled = Bool(True, config=False)
349 349
350 350 # Look for a _repr_pretty_ methods to use for pretty printing.
351 351 print_method = ObjectName('_repr_pretty_')
352 352
353 353 # Whether to pretty-print or not.
354 354 pprint = Bool(True, config=True)
355 355
356 356 # Whether to be verbose or not.
357 357 verbose = Bool(False, config=True)
358 358
359 359 # The maximum width.
360 360 max_width = Integer(79, config=True)
361 361
362 362 # The newline character.
363 363 newline = Unicode('\n', config=True)
364 364
365 365 # format-string for pprinting floats
366 366 float_format = Unicode('%r')
367 367 # setter for float precision, either int or direct format-string
368 368 float_precision = CUnicode('', config=True)
369 369
370 370 def _float_precision_changed(self, name, old, new):
371 371 """float_precision changed, set float_format accordingly.
372 372
373 373 float_precision can be set by int or str.
374 374 This will set float_format, after interpreting input.
375 375 If numpy has been imported, numpy print precision will also be set.
376 376
377 377 integer `n` sets format to '%.nf', otherwise, format set directly.
378 378
379 379 An empty string returns to defaults (repr for float, 8 for numpy).
380 380
381 381 This parameter can be set via the '%precision' magic.
382 382 """
383 383
384 384 if '%' in new:
385 385 # got explicit format string
386 386 fmt = new
387 387 try:
388 388 fmt%3.14159
389 389 except Exception:
390 390 raise ValueError("Precision must be int or format string, not %r"%new)
391 391 elif new:
392 392 # otherwise, should be an int
393 393 try:
394 394 i = int(new)
395 395 assert i >= 0
396 396 except ValueError:
397 397 raise ValueError("Precision must be int or format string, not %r"%new)
398 398 except AssertionError:
399 399 raise ValueError("int precision must be non-negative, not %r"%i)
400 400
401 401 fmt = '%%.%if'%i
402 402 if 'numpy' in sys.modules:
403 403 # set numpy precision if it has been imported
404 404 import numpy
405 405 numpy.set_printoptions(precision=i)
406 406 else:
407 407 # default back to repr
408 408 fmt = '%r'
409 409 if 'numpy' in sys.modules:
410 410 import numpy
411 411 # numpy default is 8
412 412 numpy.set_printoptions(precision=8)
413 413 self.float_format = fmt
414 414
415 415 # Use the default pretty printers from IPython.external.pretty.
416 416 def _singleton_printers_default(self):
417 417 return pretty._singleton_pprinters.copy()
418 418
419 419 def _type_printers_default(self):
420 420 d = pretty._type_pprinters.copy()
421 421 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
422 422 return d
423 423
424 424 def _deferred_printers_default(self):
425 425 return pretty._deferred_type_pprinters.copy()
426 426
427 427 #### FormatterABC interface ####
428 428
429 429 def __call__(self, obj):
430 430 """Compute the pretty representation of the object."""
431 431 if not self.pprint:
432 432 try:
433 433 return repr(obj)
434 434 except TypeError:
435 435 return ''
436 436 else:
437 437 # This uses use StringIO, as cStringIO doesn't handle unicode.
438 438 stream = StringIO()
439 439 # self.newline.encode() is a quick fix for issue gh-597. We need to
440 440 # ensure that stream does not get a mix of unicode and bytestrings,
441 441 # or it will cause trouble.
442 442 printer = pretty.RepresentationPrinter(stream, self.verbose,
443 443 self.max_width, unicode_to_str(self.newline),
444 444 singleton_pprinters=self.singleton_printers,
445 445 type_pprinters=self.type_printers,
446 446 deferred_pprinters=self.deferred_printers)
447 447 printer.pretty(obj)
448 448 printer.flush()
449 449 return stream.getvalue()
450 450
451 451
452 452 class HTMLFormatter(BaseFormatter):
453 453 """An HTML formatter.
454 454
455 455 To define the callables that compute the HTML representation of your
456 456 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
457 457 or :meth:`for_type_by_name` methods to register functions that handle
458 458 this.
459 459
460 460 The return value of this formatter should be a valid HTML snippet that
461 461 could be injected into an existing DOM. It should *not* include the
462 462 ```<html>`` or ```<body>`` tags.
463 463 """
464 464 format_type = Unicode('text/html')
465 465
466 466 print_method = ObjectName('_repr_html_')
467 467
468 468
469 469 class SVGFormatter(BaseFormatter):
470 470 """An SVG formatter.
471 471
472 472 To define the callables that compute the SVG representation of your
473 473 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
474 474 or :meth:`for_type_by_name` methods to register functions that handle
475 475 this.
476 476
477 477 The return value of this formatter should be valid SVG enclosed in
478 478 ```<svg>``` tags, that could be injected into an existing DOM. It should
479 479 *not* include the ```<html>`` or ```<body>`` tags.
480 480 """
481 481 format_type = Unicode('image/svg+xml')
482 482
483 483 print_method = ObjectName('_repr_svg_')
484 484
485 485
486 486 class PNGFormatter(BaseFormatter):
487 487 """A PNG formatter.
488 488
489 489 To define the callables that compute the PNG representation of your
490 490 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
491 491 or :meth:`for_type_by_name` methods to register functions that handle
492 492 this.
493 493
494 494 The return value of this formatter should be raw PNG data, *not*
495 495 base64 encoded.
496 496 """
497 497 format_type = Unicode('image/png')
498 498
499 499 print_method = ObjectName('_repr_png_')
500 500
501 501
502 502 class JPEGFormatter(BaseFormatter):
503 503 """A JPEG formatter.
504 504
505 505 To define the callables that compute the JPEG representation of your
506 506 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
507 507 or :meth:`for_type_by_name` methods to register functions that handle
508 508 this.
509 509
510 510 The return value of this formatter should be raw JPEG data, *not*
511 511 base64 encoded.
512 512 """
513 513 format_type = Unicode('image/jpeg')
514 514
515 515 print_method = ObjectName('_repr_jpeg_')
516 516
517 517
518 518 class LatexFormatter(BaseFormatter):
519 519 """A LaTeX formatter.
520 520
521 521 To define the callables that compute the LaTeX representation of your
522 522 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
523 523 or :meth:`for_type_by_name` methods to register functions that handle
524 524 this.
525 525
526 526 The return value of this formatter should be a valid LaTeX equation,
527 527 enclosed in either ```$``` or ```$$```.
528 528 """
529 529 format_type = Unicode('text/latex')
530 530
531 531 print_method = ObjectName('_repr_latex_')
532 532
533 533
534 534 class JSONFormatter(BaseFormatter):
535 535 """A JSON string formatter.
536 536
537 537 To define the callables that compute the JSON string representation of
538 538 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
539 539 or :meth:`for_type_by_name` methods to register functions that handle
540 540 this.
541 541
542 542 The return value of this formatter should be a valid JSON string.
543 543 """
544 544 format_type = Unicode('application/json')
545 545
546 546 print_method = ObjectName('_repr_json_')
547 547
548 548
549 549 class JavascriptFormatter(BaseFormatter):
550 550 """A Javascript formatter.
551 551
552 552 To define the callables that compute the Javascript representation of
553 553 your objects, define a :meth:`_repr_javascript_` method or use the
554 554 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
555 555 that handle this.
556 556
557 557 The return value of this formatter should be valid Javascript code and
558 558 should *not* be enclosed in ```<script>``` tags.
559 559 """
560 560 format_type = Unicode('application/javascript')
561 561
562 562 print_method = ObjectName('_repr_javascript_')
563 563
564 564 FormatterABC.register(BaseFormatter)
565 565 FormatterABC.register(PlainTextFormatter)
566 566 FormatterABC.register(HTMLFormatter)
567 567 FormatterABC.register(SVGFormatter)
568 568 FormatterABC.register(PNGFormatter)
569 569 FormatterABC.register(JPEGFormatter)
570 570 FormatterABC.register(LatexFormatter)
571 571 FormatterABC.register(JSONFormatter)
572 572 FormatterABC.register(JavascriptFormatter)
573 573
574 574
575 575 def format_display_data(obj, include=None, exclude=None):
576 576 """Return a format data dict for an object.
577 577
578 578 By default all format types will be computed.
579 579
580 580 The following MIME types are currently implemented:
581 581
582 582 * text/plain
583 583 * text/html
584 584 * text/latex
585 585 * application/json
586 586 * application/javascript
587 587 * image/png
588 588 * image/jpeg
589 589 * image/svg+xml
590 590
591 591 Parameters
592 592 ----------
593 593 obj : object
594 594 The Python object whose format data will be computed.
595 595
596 596 Returns
597 597 -------
598 598 format_dict : dict
599 599 A dictionary of key/value pairs, one or each format that was
600 600 generated for the object. The keys are the format types, which
601 601 will usually be MIME type strings and the values and JSON'able
602 602 data structure containing the raw data for the representation in
603 603 that format.
604 604 include : list or tuple, optional
605 605 A list of format type strings (MIME types) to include in the
606 606 format data dict. If this is set *only* the format types included
607 607 in this list will be computed.
608 608 exclude : list or tuple, optional
609 609 A list of format type string (MIME types) to exclue in the format
610 610 data dict. If this is set all format types will be computed,
611 611 except for those included in this argument.
612 612 """
613 613 from IPython.core.interactiveshell import InteractiveShell
614 614
615 615 InteractiveShell.instance().display_formatter.format(
616 616 obj,
617 617 include,
618 618 exclude
619 619 )
620 620
@@ -1,967 +1,967 b''
1 1 """ History related magics and functionality """
2 2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2010 The IPython Development Team.
3 # Copyright (C) 2010-2011 The IPython Development Team.
4 4 #
5 5 # Distributed under the terms of the BSD License.
6 6 #
7 7 # The full license is in the file COPYING.txt, distributed with this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13 from __future__ import print_function
14 14
15 15 # Stdlib imports
16 16 import atexit
17 17 import datetime
18 18 import os
19 19 import re
20 20 try:
21 21 import sqlite3
22 22 except ImportError:
23 23 sqlite3 = None
24 24 import threading
25 25
26 26 # Our own packages
27 27 from IPython.config.configurable import Configurable
28 28 from IPython.external.decorator import decorator
29 29 from IPython.testing.skipdoctest import skip_doctest
30 30 from IPython.utils import io
31 31 from IPython.utils.path import locate_profile
32 32 from IPython.utils.traitlets import Bool, Dict, Instance, Integer, List, Unicode
33 33 from IPython.utils.warn import warn
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Classes and functions
37 37 #-----------------------------------------------------------------------------
38 38
39 39 class DummyDB(object):
40 40 """Dummy DB that will act as a black hole for history.
41 41
42 42 Only used in the absence of sqlite"""
43 43 def execute(*args, **kwargs):
44 44 return []
45 45
46 46 def commit(self, *args, **kwargs):
47 47 pass
48 48
49 49 def __enter__(self, *args, **kwargs):
50 50 pass
51 51
52 52 def __exit__(self, *args, **kwargs):
53 53 pass
54 54
55 55 @decorator
56 56 def needs_sqlite(f,*a,**kw):
57 57 """return an empty list in the absence of sqlite"""
58 58 if sqlite3 is None:
59 59 return []
60 60 else:
61 61 return f(*a,**kw)
62 62
63 63 class HistoryAccessor(Configurable):
64 64 """Access the history database without adding to it.
65 65
66 66 This is intended for use by standalone history tools. IPython shells use
67 67 HistoryManager, below, which is a subclass of this."""
68 68
69 69 # String holding the path to the history file
70 70 hist_file = Unicode(config=True,
71 71 help="""Path to file to use for SQLite history database.
72 72
73 73 By default, IPython will put the history database in the IPython profile
74 74 directory. If you would rather share one history among profiles,
75 75 you ca set this value in each, so that they are consistent.
76 76
77 77 Due to an issue with fcntl, SQLite is known to misbehave on some NFS mounts.
78 78 If you see IPython hanging, try setting this to something on a local disk,
79 79 e.g::
80 80
81 81 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
82 82
83 83 """)
84 84
85 85
86 86 # The SQLite database
87 87 if sqlite3:
88 88 db = Instance(sqlite3.Connection)
89 89 else:
90 90 db = Instance(DummyDB)
91 91
92 92 def __init__(self, profile='default', hist_file=u'', config=None, **traits):
93 93 """Create a new history accessor.
94 94
95 95 Parameters
96 96 ----------
97 97 profile : str
98 98 The name of the profile from which to open history.
99 99 hist_file : str
100 100 Path to an SQLite history database stored by IPython. If specified,
101 101 hist_file overrides profile.
102 102 config :
103 103 Config object. hist_file can also be set through this.
104 104 """
105 105 # We need a pointer back to the shell for various tasks.
106 106 super(HistoryAccessor, self).__init__(config=config, **traits)
107 107 # defer setting hist_file from kwarg until after init,
108 108 # otherwise the default kwarg value would clobber any value
109 109 # set by config
110 110 if hist_file:
111 111 self.hist_file = hist_file
112 112
113 113 if self.hist_file == u'':
114 114 # No one has set the hist_file, yet.
115 115 self.hist_file = self._get_hist_file_name(profile)
116 116
117 117 if sqlite3 is None:
118 118 warn("IPython History requires SQLite, your history will not be saved\n")
119 119 self.db = DummyDB()
120 120 return
121 121
122 122 try:
123 123 self.init_db()
124 124 except sqlite3.DatabaseError:
125 125 if os.path.isfile(self.hist_file):
126 126 # Try to move the file out of the way
127 127 base,ext = os.path.splitext(self.hist_file)
128 128 newpath = base + '-corrupt' + ext
129 129 os.rename(self.hist_file, newpath)
130 130 print("ERROR! History file wasn't a valid SQLite database.",
131 131 "It was moved to %s" % newpath, "and a new file created.")
132 132 self.init_db()
133 133 else:
134 134 # The hist_file is probably :memory: or something else.
135 135 raise
136 136
137 137 def _get_hist_file_name(self, profile='default'):
138 138 """Find the history file for the given profile name.
139 139
140 140 This is overridden by the HistoryManager subclass, to use the shell's
141 141 active profile.
142 142
143 143 Parameters
144 144 ----------
145 145 profile : str
146 146 The name of a profile which has a history file.
147 147 """
148 148 return os.path.join(locate_profile(profile), 'history.sqlite')
149 149
150 150 def init_db(self):
151 151 """Connect to the database, and create tables if necessary."""
152 152 # use detect_types so that timestamps return datetime objects
153 153 self.db = sqlite3.connect(self.hist_file, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
154 154 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
155 155 primary key autoincrement, start timestamp,
156 156 end timestamp, num_cmds integer, remark text)""")
157 157 self.db.execute("""CREATE TABLE IF NOT EXISTS history
158 158 (session integer, line integer, source text, source_raw text,
159 159 PRIMARY KEY (session, line))""")
160 160 # Output history is optional, but ensure the table's there so it can be
161 161 # enabled later.
162 162 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
163 163 (session integer, line integer, output text,
164 164 PRIMARY KEY (session, line))""")
165 165 self.db.commit()
166 166
167 167 def writeout_cache(self):
168 168 """Overridden by HistoryManager to dump the cache before certain
169 169 database lookups."""
170 170 pass
171 171
172 172 ## -------------------------------
173 173 ## Methods for retrieving history:
174 174 ## -------------------------------
175 175 def _run_sql(self, sql, params, raw=True, output=False):
176 176 """Prepares and runs an SQL query for the history database.
177 177
178 178 Parameters
179 179 ----------
180 180 sql : str
181 181 Any filtering expressions to go after SELECT ... FROM ...
182 182 params : tuple
183 183 Parameters passed to the SQL query (to replace "?")
184 184 raw, output : bool
185 185 See :meth:`get_range`
186 186
187 187 Returns
188 188 -------
189 189 Tuples as :meth:`get_range`
190 190 """
191 191 toget = 'source_raw' if raw else 'source'
192 192 sqlfrom = "history"
193 193 if output:
194 194 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
195 195 toget = "history.%s, output_history.output" % toget
196 196 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
197 197 (toget, sqlfrom) + sql, params)
198 198 if output: # Regroup into 3-tuples, and parse JSON
199 199 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
200 200 return cur
201 201
202 202 @needs_sqlite
203 203 def get_session_info(self, session=0):
204 204 """get info about a session
205 205
206 206 Parameters
207 207 ----------
208 208
209 209 session : int
210 210 Session number to retrieve. The current session is 0, and negative
211 211 numbers count back from current session, so -1 is previous session.
212 212
213 213 Returns
214 214 -------
215 215
216 216 (session_id [int], start [datetime], end [datetime], num_cmds [int], remark [unicode])
217 217
218 218 Sessions that are running or did not exit cleanly will have `end=None`
219 219 and `num_cmds=None`.
220 220
221 221 """
222 222
223 223 if session <= 0:
224 224 session += self.session_number
225 225
226 226 query = "SELECT * from sessions where session == ?"
227 227 return self.db.execute(query, (session,)).fetchone()
228 228
229 229 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
230 230 """Get the last n lines from the history database.
231 231
232 232 Parameters
233 233 ----------
234 234 n : int
235 235 The number of lines to get
236 236 raw, output : bool
237 237 See :meth:`get_range`
238 238 include_latest : bool
239 239 If False (default), n+1 lines are fetched, and the latest one
240 240 is discarded. This is intended to be used where the function
241 241 is called by a user command, which it should not return.
242 242
243 243 Returns
244 244 -------
245 245 Tuples as :meth:`get_range`
246 246 """
247 247 self.writeout_cache()
248 248 if not include_latest:
249 249 n += 1
250 250 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
251 251 (n,), raw=raw, output=output)
252 252 if not include_latest:
253 253 return reversed(list(cur)[1:])
254 254 return reversed(list(cur))
255 255
256 256 def search(self, pattern="*", raw=True, search_raw=True,
257 257 output=False):
258 258 """Search the database using unix glob-style matching (wildcards
259 259 * and ?).
260 260
261 261 Parameters
262 262 ----------
263 263 pattern : str
264 264 The wildcarded pattern to match when searching
265 265 search_raw : bool
266 266 If True, search the raw input, otherwise, the parsed input
267 267 raw, output : bool
268 268 See :meth:`get_range`
269 269
270 270 Returns
271 271 -------
272 272 Tuples as :meth:`get_range`
273 273 """
274 274 tosearch = "source_raw" if search_raw else "source"
275 275 if output:
276 276 tosearch = "history." + tosearch
277 277 self.writeout_cache()
278 278 return self._run_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
279 279 raw=raw, output=output)
280 280
281 281 def get_range(self, session, start=1, stop=None, raw=True,output=False):
282 282 """Retrieve input by session.
283 283
284 284 Parameters
285 285 ----------
286 286 session : int
287 287 Session number to retrieve.
288 288 start : int
289 289 First line to retrieve.
290 290 stop : int
291 291 End of line range (excluded from output itself). If None, retrieve
292 292 to the end of the session.
293 293 raw : bool
294 294 If True, return untranslated input
295 295 output : bool
296 296 If True, attempt to include output. This will be 'real' Python
297 297 objects for the current session, or text reprs from previous
298 298 sessions if db_log_output was enabled at the time. Where no output
299 299 is found, None is used.
300 300
301 301 Returns
302 302 -------
303 303 An iterator over the desired lines. Each line is a 3-tuple, either
304 304 (session, line, input) if output is False, or
305 305 (session, line, (input, output)) if output is True.
306 306 """
307 307 if stop:
308 308 lineclause = "line >= ? AND line < ?"
309 309 params = (session, start, stop)
310 310 else:
311 311 lineclause = "line>=?"
312 312 params = (session, start)
313 313
314 314 return self._run_sql("WHERE session==? AND %s""" % lineclause,
315 315 params, raw=raw, output=output)
316 316
317 317 def get_range_by_str(self, rangestr, raw=True, output=False):
318 318 """Get lines of history from a string of ranges, as used by magic
319 319 commands %hist, %save, %macro, etc.
320 320
321 321 Parameters
322 322 ----------
323 323 rangestr : str
324 324 A string specifying ranges, e.g. "5 ~2/1-4". See
325 325 :func:`magic_history` for full details.
326 326 raw, output : bool
327 327 As :meth:`get_range`
328 328
329 329 Returns
330 330 -------
331 331 Tuples as :meth:`get_range`
332 332 """
333 333 for sess, s, e in extract_hist_ranges(rangestr):
334 334 for line in self.get_range(sess, s, e, raw=raw, output=output):
335 335 yield line
336 336
337 337
338 338 class HistoryManager(HistoryAccessor):
339 339 """A class to organize all history-related functionality in one place.
340 340 """
341 341 # Public interface
342 342
343 343 # An instance of the IPython shell we are attached to
344 344 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
345 345 # Lists to hold processed and raw history. These start with a blank entry
346 346 # so that we can index them starting from 1
347 347 input_hist_parsed = List([""])
348 348 input_hist_raw = List([""])
349 349 # A list of directories visited during session
350 350 dir_hist = List()
351 351 def _dir_hist_default(self):
352 352 try:
353 353 return [os.getcwdu()]
354 354 except OSError:
355 355 return []
356 356
357 357 # A dict of output history, keyed with ints from the shell's
358 358 # execution count.
359 359 output_hist = Dict()
360 360 # The text/plain repr of outputs.
361 361 output_hist_reprs = Dict()
362 362
363 363 # The number of the current session in the history database
364 364 session_number = Integer()
365 365 # Should we log output to the database? (default no)
366 366 db_log_output = Bool(False, config=True)
367 367 # Write to database every x commands (higher values save disk access & power)
368 368 # Values of 1 or less effectively disable caching.
369 369 db_cache_size = Integer(0, config=True)
370 370 # The input and output caches
371 371 db_input_cache = List()
372 372 db_output_cache = List()
373 373
374 374 # History saving in separate thread
375 375 save_thread = Instance('IPython.core.history.HistorySavingThread')
376 376 try: # Event is a function returning an instance of _Event...
377 377 save_flag = Instance(threading._Event)
378 378 except AttributeError: # ...until Python 3.3, when it's a class.
379 379 save_flag = Instance(threading.Event)
380 380
381 381 # Private interface
382 382 # Variables used to store the three last inputs from the user. On each new
383 383 # history update, we populate the user's namespace with these, shifted as
384 384 # necessary.
385 385 _i00 = Unicode(u'')
386 386 _i = Unicode(u'')
387 387 _ii = Unicode(u'')
388 388 _iii = Unicode(u'')
389 389
390 390 # A regex matching all forms of the exit command, so that we don't store
391 391 # them in the history (it's annoying to rewind the first entry and land on
392 392 # an exit call).
393 393 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
394 394
395 395 def __init__(self, shell=None, config=None, **traits):
396 396 """Create a new history manager associated with a shell instance.
397 397 """
398 398 # We need a pointer back to the shell for various tasks.
399 399 super(HistoryManager, self).__init__(shell=shell, config=config,
400 400 **traits)
401 401 self.save_flag = threading.Event()
402 402 self.db_input_cache_lock = threading.Lock()
403 403 self.db_output_cache_lock = threading.Lock()
404 404 self.save_thread = HistorySavingThread(self)
405 405 self.save_thread.start()
406 406
407 407 self.new_session()
408 408
409 409 def _get_hist_file_name(self, profile=None):
410 410 """Get default history file name based on the Shell's profile.
411 411
412 412 The profile parameter is ignored, but must exist for compatibility with
413 413 the parent class."""
414 414 profile_dir = self.shell.profile_dir.location
415 415 return os.path.join(profile_dir, 'history.sqlite')
416 416
417 417 @needs_sqlite
418 418 def new_session(self, conn=None):
419 419 """Get a new session number."""
420 420 if conn is None:
421 421 conn = self.db
422 422
423 423 with conn:
424 424 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
425 425 NULL, "") """, (datetime.datetime.now(),))
426 426 self.session_number = cur.lastrowid
427 427
428 428 def end_session(self):
429 429 """Close the database session, filling in the end time and line count."""
430 430 self.writeout_cache()
431 431 with self.db:
432 432 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
433 433 session==?""", (datetime.datetime.now(),
434 434 len(self.input_hist_parsed)-1, self.session_number))
435 435 self.session_number = 0
436 436
437 437 def name_session(self, name):
438 438 """Give the current session a name in the history database."""
439 439 with self.db:
440 440 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
441 441 (name, self.session_number))
442 442
443 443 def reset(self, new_session=True):
444 444 """Clear the session history, releasing all object references, and
445 445 optionally open a new session."""
446 446 self.output_hist.clear()
447 447 # The directory history can't be completely empty
448 448 self.dir_hist[:] = [os.getcwdu()]
449 449
450 450 if new_session:
451 451 if self.session_number:
452 452 self.end_session()
453 453 self.input_hist_parsed[:] = [""]
454 454 self.input_hist_raw[:] = [""]
455 455 self.new_session()
456 456
457 457 # ------------------------------
458 458 # Methods for retrieving history
459 459 # ------------------------------
460 460 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
461 461 """Get input and output history from the current session. Called by
462 462 get_range, and takes similar parameters."""
463 463 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
464 464
465 465 n = len(input_hist)
466 466 if start < 0:
467 467 start += n
468 468 if not stop or (stop > n):
469 469 stop = n
470 470 elif stop < 0:
471 471 stop += n
472 472
473 473 for i in range(start, stop):
474 474 if output:
475 475 line = (input_hist[i], self.output_hist_reprs.get(i))
476 476 else:
477 477 line = input_hist[i]
478 478 yield (0, i, line)
479 479
480 480 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
481 481 """Retrieve input by session.
482 482
483 483 Parameters
484 484 ----------
485 485 session : int
486 486 Session number to retrieve. The current session is 0, and negative
487 487 numbers count back from current session, so -1 is previous session.
488 488 start : int
489 489 First line to retrieve.
490 490 stop : int
491 491 End of line range (excluded from output itself). If None, retrieve
492 492 to the end of the session.
493 493 raw : bool
494 494 If True, return untranslated input
495 495 output : bool
496 496 If True, attempt to include output. This will be 'real' Python
497 497 objects for the current session, or text reprs from previous
498 498 sessions if db_log_output was enabled at the time. Where no output
499 499 is found, None is used.
500 500
501 501 Returns
502 502 -------
503 503 An iterator over the desired lines. Each line is a 3-tuple, either
504 504 (session, line, input) if output is False, or
505 505 (session, line, (input, output)) if output is True.
506 506 """
507 507 if session <= 0:
508 508 session += self.session_number
509 509 if session==self.session_number: # Current session
510 510 return self._get_range_session(start, stop, raw, output)
511 511 return super(HistoryManager, self).get_range(session, start, stop, raw, output)
512 512
513 513 ## ----------------------------
514 514 ## Methods for storing history:
515 515 ## ----------------------------
516 516 def store_inputs(self, line_num, source, source_raw=None):
517 517 """Store source and raw input in history and create input cache
518 518 variables _i*.
519 519
520 520 Parameters
521 521 ----------
522 522 line_num : int
523 523 The prompt number of this input.
524 524
525 525 source : str
526 526 Python input.
527 527
528 528 source_raw : str, optional
529 529 If given, this is the raw input without any IPython transformations
530 530 applied to it. If not given, ``source`` is used.
531 531 """
532 532 if source_raw is None:
533 533 source_raw = source
534 534 source = source.rstrip('\n')
535 535 source_raw = source_raw.rstrip('\n')
536 536
537 537 # do not store exit/quit commands
538 538 if self._exit_re.match(source_raw.strip()):
539 539 return
540 540
541 541 self.input_hist_parsed.append(source)
542 542 self.input_hist_raw.append(source_raw)
543 543
544 544 with self.db_input_cache_lock:
545 545 self.db_input_cache.append((line_num, source, source_raw))
546 546 # Trigger to flush cache and write to DB.
547 547 if len(self.db_input_cache) >= self.db_cache_size:
548 548 self.save_flag.set()
549 549
550 550 # update the auto _i variables
551 551 self._iii = self._ii
552 552 self._ii = self._i
553 553 self._i = self._i00
554 554 self._i00 = source_raw
555 555
556 556 # hackish access to user namespace to create _i1,_i2... dynamically
557 557 new_i = '_i%s' % line_num
558 558 to_main = {'_i': self._i,
559 559 '_ii': self._ii,
560 560 '_iii': self._iii,
561 561 new_i : self._i00 }
562 562 self.shell.user_ns.update(to_main)
563 563
564 564 def store_output(self, line_num):
565 565 """If database output logging is enabled, this saves all the
566 566 outputs from the indicated prompt number to the database. It's
567 567 called by run_cell after code has been executed.
568 568
569 569 Parameters
570 570 ----------
571 571 line_num : int
572 572 The line number from which to save outputs
573 573 """
574 574 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
575 575 return
576 576 output = self.output_hist_reprs[line_num]
577 577
578 578 with self.db_output_cache_lock:
579 579 self.db_output_cache.append((line_num, output))
580 580 if self.db_cache_size <= 1:
581 581 self.save_flag.set()
582 582
583 583 def _writeout_input_cache(self, conn):
584 584 with conn:
585 585 for line in self.db_input_cache:
586 586 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
587 587 (self.session_number,)+line)
588 588
589 589 def _writeout_output_cache(self, conn):
590 590 with conn:
591 591 for line in self.db_output_cache:
592 592 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
593 593 (self.session_number,)+line)
594 594
595 595 @needs_sqlite
596 596 def writeout_cache(self, conn=None):
597 597 """Write any entries in the cache to the database."""
598 598 if conn is None:
599 599 conn = self.db
600 600
601 601 with self.db_input_cache_lock:
602 602 try:
603 603 self._writeout_input_cache(conn)
604 604 except sqlite3.IntegrityError:
605 605 self.new_session(conn)
606 606 print("ERROR! Session/line number was not unique in",
607 607 "database. History logging moved to new session",
608 608 self.session_number)
609 609 try: # Try writing to the new session. If this fails, don't recurse
610 610 self._writeout_input_cache(conn)
611 611 except sqlite3.IntegrityError:
612 612 pass
613 613 finally:
614 614 self.db_input_cache = []
615 615
616 616 with self.db_output_cache_lock:
617 617 try:
618 618 self._writeout_output_cache(conn)
619 619 except sqlite3.IntegrityError:
620 620 print("!! Session/line number for output was not unique",
621 621 "in database. Output will not be stored.")
622 622 finally:
623 623 self.db_output_cache = []
624 624
625 625
626 626 class HistorySavingThread(threading.Thread):
627 627 """This thread takes care of writing history to the database, so that
628 628 the UI isn't held up while that happens.
629 629
630 630 It waits for the HistoryManager's save_flag to be set, then writes out
631 631 the history cache. The main thread is responsible for setting the flag when
632 632 the cache size reaches a defined threshold."""
633 633 daemon = True
634 634 stop_now = False
635 635 def __init__(self, history_manager):
636 636 super(HistorySavingThread, self).__init__()
637 637 self.history_manager = history_manager
638 638 atexit.register(self.stop)
639 639
640 640 @needs_sqlite
641 641 def run(self):
642 642 # We need a separate db connection per thread:
643 643 try:
644 644 self.db = sqlite3.connect(self.history_manager.hist_file)
645 645 while True:
646 646 self.history_manager.save_flag.wait()
647 647 if self.stop_now:
648 648 return
649 649 self.history_manager.save_flag.clear()
650 650 self.history_manager.writeout_cache(self.db)
651 651 except Exception as e:
652 652 print(("The history saving thread hit an unexpected error (%s)."
653 653 "History will not be written to the database.") % repr(e))
654 654
655 655 def stop(self):
656 656 """This can be called from the main thread to safely stop this thread.
657 657
658 658 Note that it does not attempt to write out remaining history before
659 659 exiting. That should be done by calling the HistoryManager's
660 660 end_session method."""
661 661 self.stop_now = True
662 662 self.history_manager.save_flag.set()
663 663 self.join()
664 664
665 665
666 666 # To match, e.g. ~5/8-~2/3
667 667 range_re = re.compile(r"""
668 668 ((?P<startsess>~?\d+)/)?
669 669 (?P<start>\d+) # Only the start line num is compulsory
670 670 ((?P<sep>[\-:])
671 671 ((?P<endsess>~?\d+)/)?
672 672 (?P<end>\d+))?
673 673 $""", re.VERBOSE)
674 674
675 675 def extract_hist_ranges(ranges_str):
676 676 """Turn a string of history ranges into 3-tuples of (session, start, stop).
677 677
678 678 Examples
679 679 --------
680 680 list(extract_input_ranges("~8/5-~7/4 2"))
681 681 [(-8, 5, None), (-7, 1, 4), (0, 2, 3)]
682 682 """
683 683 for range_str in ranges_str.split():
684 684 rmatch = range_re.match(range_str)
685 685 if not rmatch:
686 686 continue
687 687 start = int(rmatch.group("start"))
688 688 end = rmatch.group("end")
689 689 end = int(end) if end else start+1 # If no end specified, get (a, a+1)
690 690 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
691 691 end += 1
692 692 startsess = rmatch.group("startsess") or "0"
693 693 endsess = rmatch.group("endsess") or startsess
694 694 startsess = int(startsess.replace("~","-"))
695 695 endsess = int(endsess.replace("~","-"))
696 696 assert endsess >= startsess
697 697
698 698 if endsess == startsess:
699 699 yield (startsess, start, end)
700 700 continue
701 701 # Multiple sessions in one range:
702 702 yield (startsess, start, None)
703 703 for sess in range(startsess+1, endsess):
704 704 yield (sess, 1, None)
705 705 yield (endsess, 1, end)
706 706
707 707 def _format_lineno(session, line):
708 708 """Helper function to format line numbers properly."""
709 709 if session == 0:
710 710 return str(line)
711 711 return "%s#%s" % (session, line)
712 712
713 713 @skip_doctest
714 714 def magic_history(self, parameter_s = ''):
715 715 """Print input history (_i<n> variables), with most recent last.
716 716
717 717 %history -> print at most 40 inputs (some may be multi-line)\\
718 718 %history n -> print at most n inputs\\
719 719 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
720 720
721 721 By default, input history is printed without line numbers so it can be
722 722 directly pasted into an editor. Use -n to show them.
723 723
724 724 Ranges of history can be indicated using the syntax:
725 725 4 : Line 4, current session
726 726 4-6 : Lines 4-6, current session
727 727 243/1-5: Lines 1-5, session 243
728 728 ~2/7 : Line 7, session 2 before current
729 729 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
730 730 of 6 sessions ago.
731 731 Multiple ranges can be entered, separated by spaces
732 732
733 733 The same syntax is used by %macro, %save, %edit, %rerun
734 734
735 735 Options:
736 736
737 737 -n: print line numbers for each input.
738 738 This feature is only available if numbered prompts are in use.
739 739
740 740 -o: also print outputs for each input.
741 741
742 742 -p: print classic '>>>' python prompts before each input. This is useful
743 743 for making documentation, and in conjunction with -o, for producing
744 744 doctest-ready output.
745 745
746 746 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
747 747
748 748 -t: print the 'translated' history, as IPython understands it. IPython
749 749 filters your input and converts it all into valid Python source before
750 750 executing it (things like magics or aliases are turned into function
751 751 calls, for example). With this option, you'll see the native history
752 752 instead of the user-entered version: '%cd /' will be seen as
753 753 'get_ipython().magic("%cd /")' instead of '%cd /'.
754 754
755 755 -g: treat the arg as a pattern to grep for in (full) history.
756 756 This includes the saved history (almost all commands ever written).
757 757 Use '%hist -g' to show full saved history (may be very long).
758 758
759 759 -l: get the last n lines from all sessions. Specify n as a single arg, or
760 760 the default is the last 10 lines.
761 761
762 762 -f FILENAME: instead of printing the output to the screen, redirect it to
763 763 the given file. The file is always overwritten, though IPython asks for
764 764 confirmation first if it already exists.
765 765
766 766 Examples
767 767 --------
768 768 ::
769 769
770 770 In [6]: %hist -n 4 6
771 771 4:a = 12
772 772 5:print a**2
773 773
774 774 """
775 775
776 776 if not self.shell.displayhook.do_full_cache:
777 777 print('This feature is only available if numbered prompts are in use.')
778 778 return
779 779 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
780 780
781 781 # For brevity
782 782 history_manager = self.shell.history_manager
783 783
784 784 def _format_lineno(session, line):
785 785 """Helper function to format line numbers properly."""
786 786 if session in (0, history_manager.session_number):
787 787 return str(line)
788 788 return "%s/%s" % (session, line)
789 789
790 790 # Check if output to specific file was requested.
791 791 try:
792 792 outfname = opts['f']
793 793 except KeyError:
794 794 outfile = io.stdout # default
795 795 # We don't want to close stdout at the end!
796 796 close_at_end = False
797 797 else:
798 798 if os.path.exists(outfname):
799 799 if not io.ask_yes_no("File %r exists. Overwrite?" % outfname):
800 800 print('Aborting.')
801 801 return
802 802
803 803 outfile = open(outfname,'w')
804 804 close_at_end = True
805 805
806 806 print_nums = 'n' in opts
807 807 get_output = 'o' in opts
808 808 pyprompts = 'p' in opts
809 809 # Raw history is the default
810 810 raw = not('t' in opts)
811 811
812 812 default_length = 40
813 813 pattern = None
814 814
815 815 if 'g' in opts: # Glob search
816 816 pattern = "*" + args + "*" if args else "*"
817 817 hist = history_manager.search(pattern, raw=raw, output=get_output)
818 818 print_nums = True
819 819 elif 'l' in opts: # Get 'tail'
820 820 try:
821 821 n = int(args)
822 822 except ValueError, IndexError:
823 823 n = 10
824 824 hist = history_manager.get_tail(n, raw=raw, output=get_output)
825 825 else:
826 826 if args: # Get history by ranges
827 827 hist = history_manager.get_range_by_str(args, raw, get_output)
828 828 else: # Just get history for the current session
829 829 hist = history_manager.get_range(raw=raw, output=get_output)
830 830
831 831 # We could be displaying the entire history, so let's not try to pull it
832 832 # into a list in memory. Anything that needs more space will just misalign.
833 833 width = 4
834 834
835 835 for session, lineno, inline in hist:
836 836 # Print user history with tabs expanded to 4 spaces. The GUI clients
837 837 # use hard tabs for easier usability in auto-indented code, but we want
838 838 # to produce PEP-8 compliant history for safe pasting into an editor.
839 839 if get_output:
840 840 inline, output = inline
841 841 inline = inline.expandtabs(4).rstrip()
842 842
843 843 multiline = "\n" in inline
844 844 line_sep = '\n' if multiline else ' '
845 845 if print_nums:
846 846 print('%s:%s' % (_format_lineno(session, lineno).rjust(width),
847 847 line_sep), file=outfile, end='')
848 848 if pyprompts:
849 849 print(">>> ", end="", file=outfile)
850 850 if multiline:
851 851 inline = "\n... ".join(inline.splitlines()) + "\n..."
852 852 print(inline, file=outfile)
853 853 if get_output and output:
854 854 print(output, file=outfile)
855 855
856 856 if close_at_end:
857 857 outfile.close()
858 858
859 859
860 860 def magic_rep(self, arg):
861 861 r"""Repeat a command, or get command to input line for editing.
862 862
863 863 %recall and %rep are equivalent.
864 864
865 865 - %recall (no arguments):
866 866
867 867 Place a string version of last computation result (stored in the special '_'
868 868 variable) to the next input prompt. Allows you to create elaborate command
869 869 lines without using copy-paste::
870 870
871 871 In[1]: l = ["hei", "vaan"]
872 872 In[2]: "".join(l)
873 873 Out[2]: heivaan
874 874 In[3]: %rep
875 875 In[4]: heivaan_ <== cursor blinking
876 876
877 877 %recall 45
878 878
879 879 Place history line 45 on the next input prompt. Use %hist to find
880 880 out the number.
881 881
882 882 %recall 1-4
883 883
884 884 Combine the specified lines into one cell, and place it on the next
885 885 input prompt. See %history for the slice syntax.
886 886
887 887 %recall foo+bar
888 888
889 889 If foo+bar can be evaluated in the user namespace, the result is
890 890 placed at the next input prompt. Otherwise, the history is searched
891 891 for lines which contain that substring, and the most recent one is
892 892 placed at the next input prompt.
893 893 """
894 894 if not arg: # Last output
895 895 self.set_next_input(str(self.shell.user_ns["_"]))
896 896 return
897 897 # Get history range
898 898 histlines = self.history_manager.get_range_by_str(arg)
899 899 cmd = "\n".join(x[2] for x in histlines)
900 900 if cmd:
901 901 self.set_next_input(cmd.rstrip())
902 902 return
903 903
904 904 try: # Variable in user namespace
905 905 cmd = str(eval(arg, self.shell.user_ns))
906 906 except Exception: # Search for term in history
907 907 histlines = self.history_manager.search("*"+arg+"*")
908 908 for h in reversed([x[2] for x in histlines]):
909 909 if 'rep' in h:
910 910 continue
911 911 self.set_next_input(h.rstrip())
912 912 return
913 913 else:
914 914 self.set_next_input(cmd.rstrip())
915 915 print("Couldn't evaluate or find in history:", arg)
916 916
917 917 def magic_rerun(self, parameter_s=''):
918 918 """Re-run previous input
919 919
920 920 By default, you can specify ranges of input history to be repeated
921 921 (as with %history). With no arguments, it will repeat the last line.
922 922
923 923 Options:
924 924
925 925 -l <n> : Repeat the last n lines of input, not including the
926 926 current command.
927 927
928 928 -g foo : Repeat the most recent line which contains foo
929 929 """
930 930 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
931 931 if "l" in opts: # Last n lines
932 932 n = int(opts['l'])
933 933 hist = self.history_manager.get_tail(n)
934 934 elif "g" in opts: # Search
935 935 p = "*"+opts['g']+"*"
936 936 hist = list(self.history_manager.search(p))
937 937 for l in reversed(hist):
938 938 if "rerun" not in l[2]:
939 939 hist = [l] # The last match which isn't a %rerun
940 940 break
941 941 else:
942 942 hist = [] # No matches except %rerun
943 943 elif args: # Specify history ranges
944 944 hist = self.history_manager.get_range_by_str(args)
945 945 else: # Last line
946 946 hist = self.history_manager.get_tail(1)
947 947 hist = [x[2] for x in hist]
948 948 if not hist:
949 949 print("No lines in history match specification")
950 950 return
951 951 histlines = "\n".join(hist)
952 952 print("=== Executing: ===")
953 953 print(histlines)
954 954 print("=== Output: ===")
955 955 self.run_cell("\n".join(hist), store_history=False)
956 956
957 957
958 958 def init_ipython(ip):
959 959 ip.define_magic("rep", magic_rep)
960 960 ip.define_magic("recall", magic_rep)
961 961 ip.define_magic("rerun", magic_rerun)
962 962 ip.define_magic("hist",magic_history) # Alternative name
963 963 ip.define_magic("history",magic_history)
964 964
965 965 # XXX - ipy_completers are in quarantine, need to be updated to new apis
966 966 #import ipy_completers
967 967 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,767 +1,767 b''
1 1 """Analysis of text input into executable blocks.
2 2
3 3 The main class in this module, :class:`InputSplitter`, is designed to break
4 4 input from either interactive, line-by-line environments or block-based ones,
5 5 into standalone blocks that can be executed by Python as 'single' statements
6 6 (thus triggering sys.displayhook).
7 7
8 8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
9 9 with full support for the extended IPython syntax (magics, system calls, etc).
10 10
11 11 For more details, see the class docstring below.
12 12
13 13 Syntax Transformations
14 14 ----------------------
15 15
16 16 One of the main jobs of the code in this file is to apply all syntax
17 17 transformations that make up 'the IPython language', i.e. magics, shell
18 18 escapes, etc. All transformations should be implemented as *fully stateless*
19 19 entities, that simply take one line as their input and return a line.
20 20 Internally for implementation purposes they may be a normal function or a
21 21 callable object, but the only input they receive will be a single line and they
22 22 should only return a line, without holding any data-dependent state between
23 23 calls.
24 24
25 25 As an example, the EscapedTransformer is a class so we can more clearly group
26 26 together the functionality of dispatching to individual functions based on the
27 27 starting escape character, but the only method for public use is its call
28 28 method.
29 29
30 30
31 31 ToDo
32 32 ----
33 33
34 34 - Should we make push() actually raise an exception once push_accepts_more()
35 35 returns False?
36 36
37 37 - Naming cleanups. The tr_* names aren't the most elegant, though now they are
38 38 at least just attributes of a class so not really very exposed.
39 39
40 40 - Think about the best way to support dynamic things: automagic, autocall,
41 41 macros, etc.
42 42
43 43 - Think of a better heuristic for the application of the transforms in
44 44 IPythonInputSplitter.push() than looking at the buffer ending in ':'. Idea:
45 45 track indentation change events (indent, dedent, nothing) and apply them only
46 46 if the indentation went up, but not otherwise.
47 47
48 48 - Think of the cleanest way for supporting user-specified transformations (the
49 49 user prefilters we had before).
50 50
51 51 Authors
52 52 -------
53 53
54 54 * Fernando Perez
55 55 * Brian Granger
56 56 """
57 57 #-----------------------------------------------------------------------------
58 # Copyright (C) 2010 The IPython Development Team
58 # Copyright (C) 2010-2011 The IPython Development Team
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
62 62 #-----------------------------------------------------------------------------
63 63 from __future__ import print_function
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Imports
67 67 #-----------------------------------------------------------------------------
68 68 # stdlib
69 69 import ast
70 70 import codeop
71 71 import re
72 72 import sys
73 73 import tokenize
74 74 from StringIO import StringIO
75 75
76 76 # IPython modules
77 77 from IPython.core.splitinput import split_user_input, LineInfo
78 78 from IPython.utils.py3compat import cast_unicode
79 79
80 80 #-----------------------------------------------------------------------------
81 81 # Globals
82 82 #-----------------------------------------------------------------------------
83 83
84 84 # The escape sequences that define the syntax transformations IPython will
85 85 # apply to user input. These can NOT be just changed here: many regular
86 86 # expressions and other parts of the code may use their hardcoded values, and
87 87 # for all intents and purposes they constitute the 'IPython syntax', so they
88 88 # should be considered fixed.
89 89
90 90 ESC_SHELL = '!' # Send line to underlying system shell
91 91 ESC_SH_CAP = '!!' # Send line to system shell and capture output
92 92 ESC_HELP = '?' # Find information about object
93 93 ESC_HELP2 = '??' # Find extra-detailed information about object
94 94 ESC_MAGIC = '%' # Call magic function
95 95 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
96 96 ESC_QUOTE2 = ';' # Quote all args as a single string, call
97 97 ESC_PAREN = '/' # Call first argument with rest of line as arguments
98 98
99 99 #-----------------------------------------------------------------------------
100 100 # Utilities
101 101 #-----------------------------------------------------------------------------
102 102
103 103 # FIXME: These are general-purpose utilities that later can be moved to the
104 104 # general ward. Kept here for now because we're being very strict about test
105 105 # coverage with this code, and this lets us ensure that we keep 100% coverage
106 106 # while developing.
107 107
108 108 # compiled regexps for autoindent management
109 109 dedent_re = re.compile('|'.join([
110 110 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
111 111 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
112 112 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
113 113 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
114 114 r'^\s+pass\s*$' # pass (optionally followed by trailing spaces)
115 115 ]))
116 116 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
117 117
118 118 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
119 119 # before pure comments
120 120 comment_line_re = re.compile('^\s*\#')
121 121
122 122
123 123 def num_ini_spaces(s):
124 124 """Return the number of initial spaces in a string.
125 125
126 126 Note that tabs are counted as a single space. For now, we do *not* support
127 127 mixing of tabs and spaces in the user's input.
128 128
129 129 Parameters
130 130 ----------
131 131 s : string
132 132
133 133 Returns
134 134 -------
135 135 n : int
136 136 """
137 137
138 138 ini_spaces = ini_spaces_re.match(s)
139 139 if ini_spaces:
140 140 return ini_spaces.end()
141 141 else:
142 142 return 0
143 143
144 144
145 145 def remove_comments(src):
146 146 """Remove all comments from input source.
147 147
148 148 Note: comments are NOT recognized inside of strings!
149 149
150 150 Parameters
151 151 ----------
152 152 src : string
153 153 A single or multiline input string.
154 154
155 155 Returns
156 156 -------
157 157 String with all Python comments removed.
158 158 """
159 159
160 160 return re.sub('#.*', '', src)
161 161
162 162 def has_comment(src):
163 163 """Indicate whether an input line has (i.e. ends in, or is) a comment.
164 164
165 165 This uses tokenize, so it can distinguish comments from # inside strings.
166 166
167 167 Parameters
168 168 ----------
169 169 src : string
170 170 A single line input string.
171 171
172 172 Returns
173 173 -------
174 174 Boolean: True if source has a comment.
175 175 """
176 176 readline = StringIO(src).readline
177 177 toktypes = set()
178 178 try:
179 179 for t in tokenize.generate_tokens(readline):
180 180 toktypes.add(t[0])
181 181 except tokenize.TokenError:
182 182 pass
183 183 return(tokenize.COMMENT in toktypes)
184 184
185 185
186 186 def get_input_encoding():
187 187 """Return the default standard input encoding.
188 188
189 189 If sys.stdin has no encoding, 'ascii' is returned."""
190 190 # There are strange environments for which sys.stdin.encoding is None. We
191 191 # ensure that a valid encoding is returned.
192 192 encoding = getattr(sys.stdin, 'encoding', None)
193 193 if encoding is None:
194 194 encoding = 'ascii'
195 195 return encoding
196 196
197 197 #-----------------------------------------------------------------------------
198 198 # Classes and functions for normal Python syntax handling
199 199 #-----------------------------------------------------------------------------
200 200
201 201 class InputSplitter(object):
202 202 """An object that can accumulate lines of Python source before execution.
203 203
204 204 This object is designed to be fed python source line-by-line, using
205 205 :meth:`push`. It will return on each push whether the currently pushed
206 206 code could be executed already. In addition, it provides a method called
207 207 :meth:`push_accepts_more` that can be used to query whether more input
208 208 can be pushed into a single interactive block.
209 209
210 210 This is a simple example of how an interactive terminal-based client can use
211 211 this tool::
212 212
213 213 isp = InputSplitter()
214 214 while isp.push_accepts_more():
215 215 indent = ' '*isp.indent_spaces
216 216 prompt = '>>> ' + indent
217 217 line = indent + raw_input(prompt)
218 218 isp.push(line)
219 219 print 'Input source was:\n', isp.source_reset(),
220 220 """
221 221 # Number of spaces of indentation computed from input that has been pushed
222 222 # so far. This is the attributes callers should query to get the current
223 223 # indentation level, in order to provide auto-indent facilities.
224 224 indent_spaces = 0
225 225 # String, indicating the default input encoding. It is computed by default
226 226 # at initialization time via get_input_encoding(), but it can be reset by a
227 227 # client with specific knowledge of the encoding.
228 228 encoding = ''
229 229 # String where the current full source input is stored, properly encoded.
230 230 # Reading this attribute is the normal way of querying the currently pushed
231 231 # source code, that has been properly encoded.
232 232 source = ''
233 233 # Code object corresponding to the current source. It is automatically
234 234 # synced to the source, so it can be queried at any time to obtain the code
235 235 # object; it will be None if the source doesn't compile to valid Python.
236 236 code = None
237 237 # Input mode
238 238 input_mode = 'line'
239 239
240 240 # Private attributes
241 241
242 242 # List with lines of input accumulated so far
243 243 _buffer = None
244 244 # Command compiler
245 245 _compile = None
246 246 # Mark when input has changed indentation all the way back to flush-left
247 247 _full_dedent = False
248 248 # Boolean indicating whether the current block is complete
249 249 _is_complete = None
250 250
251 251 def __init__(self, input_mode=None):
252 252 """Create a new InputSplitter instance.
253 253
254 254 Parameters
255 255 ----------
256 256 input_mode : str
257 257
258 258 One of ['line', 'cell']; default is 'line'.
259 259
260 260 The input_mode parameter controls how new inputs are used when fed via
261 261 the :meth:`push` method:
262 262
263 263 - 'line': meant for line-oriented clients, inputs are appended one at a
264 264 time to the internal buffer and the whole buffer is compiled.
265 265
266 266 - 'cell': meant for clients that can edit multi-line 'cells' of text at
267 267 a time. A cell can contain one or more blocks that can be compile in
268 268 'single' mode by Python. In this mode, each new input new input
269 269 completely replaces all prior inputs. Cell mode is thus equivalent
270 270 to prepending a full reset() to every push() call.
271 271 """
272 272 self._buffer = []
273 273 self._compile = codeop.CommandCompiler()
274 274 self.encoding = get_input_encoding()
275 275 self.input_mode = InputSplitter.input_mode if input_mode is None \
276 276 else input_mode
277 277
278 278 def reset(self):
279 279 """Reset the input buffer and associated state."""
280 280 self.indent_spaces = 0
281 281 self._buffer[:] = []
282 282 self.source = ''
283 283 self.code = None
284 284 self._is_complete = False
285 285 self._full_dedent = False
286 286
287 287 def source_reset(self):
288 288 """Return the input source and perform a full reset.
289 289 """
290 290 out = self.source
291 291 self.reset()
292 292 return out
293 293
294 294 def push(self, lines):
295 295 """Push one or more lines of input.
296 296
297 297 This stores the given lines and returns a status code indicating
298 298 whether the code forms a complete Python block or not.
299 299
300 300 Any exceptions generated in compilation are swallowed, but if an
301 301 exception was produced, the method returns True.
302 302
303 303 Parameters
304 304 ----------
305 305 lines : string
306 306 One or more lines of Python input.
307 307
308 308 Returns
309 309 -------
310 310 is_complete : boolean
311 311 True if the current input source (the result of the current input
312 312 plus prior inputs) forms a complete Python execution block. Note that
313 313 this value is also stored as a private attribute (_is_complete), so it
314 314 can be queried at any time.
315 315 """
316 316 if self.input_mode == 'cell':
317 317 self.reset()
318 318
319 319 self._store(lines)
320 320 source = self.source
321 321
322 322 # Before calling _compile(), reset the code object to None so that if an
323 323 # exception is raised in compilation, we don't mislead by having
324 324 # inconsistent code/source attributes.
325 325 self.code, self._is_complete = None, None
326 326
327 327 # Honor termination lines properly
328 328 if source.rstrip().endswith('\\'):
329 329 return False
330 330
331 331 self._update_indent(lines)
332 332 try:
333 333 self.code = self._compile(source, symbol="exec")
334 334 # Invalid syntax can produce any of a number of different errors from
335 335 # inside the compiler, so we have to catch them all. Syntax errors
336 336 # immediately produce a 'ready' block, so the invalid Python can be
337 337 # sent to the kernel for evaluation with possible ipython
338 338 # special-syntax conversion.
339 339 except (SyntaxError, OverflowError, ValueError, TypeError,
340 340 MemoryError):
341 341 self._is_complete = True
342 342 else:
343 343 # Compilation didn't produce any exceptions (though it may not have
344 344 # given a complete code object)
345 345 self._is_complete = self.code is not None
346 346
347 347 return self._is_complete
348 348
349 349 def push_accepts_more(self):
350 350 """Return whether a block of interactive input can accept more input.
351 351
352 352 This method is meant to be used by line-oriented frontends, who need to
353 353 guess whether a block is complete or not based solely on prior and
354 354 current input lines. The InputSplitter considers it has a complete
355 355 interactive block and will not accept more input only when either a
356 356 SyntaxError is raised, or *all* of the following are true:
357 357
358 358 1. The input compiles to a complete statement.
359 359
360 360 2. The indentation level is flush-left (because if we are indented,
361 361 like inside a function definition or for loop, we need to keep
362 362 reading new input).
363 363
364 364 3. There is one extra line consisting only of whitespace.
365 365
366 366 Because of condition #3, this method should be used only by
367 367 *line-oriented* frontends, since it means that intermediate blank lines
368 368 are not allowed in function definitions (or any other indented block).
369 369
370 370 If the current input produces a syntax error, this method immediately
371 371 returns False but does *not* raise the syntax error exception, as
372 372 typically clients will want to send invalid syntax to an execution
373 373 backend which might convert the invalid syntax into valid Python via
374 374 one of the dynamic IPython mechanisms.
375 375 """
376 376
377 377 # With incomplete input, unconditionally accept more
378 378 if not self._is_complete:
379 379 return True
380 380
381 381 # If we already have complete input and we're flush left, the answer
382 382 # depends. In line mode, if there hasn't been any indentation,
383 383 # that's it. If we've come back from some indentation, we need
384 384 # the blank final line to finish.
385 385 # In cell mode, we need to check how many blocks the input so far
386 386 # compiles into, because if there's already more than one full
387 387 # independent block of input, then the client has entered full
388 388 # 'cell' mode and is feeding lines that each is complete. In this
389 389 # case we should then keep accepting. The Qt terminal-like console
390 390 # does precisely this, to provide the convenience of terminal-like
391 391 # input of single expressions, but allowing the user (with a
392 392 # separate keystroke) to switch to 'cell' mode and type multiple
393 393 # expressions in one shot.
394 394 if self.indent_spaces==0:
395 395 if self.input_mode=='line':
396 396 if not self._full_dedent:
397 397 return False
398 398 else:
399 399 try:
400 400 code_ast = ast.parse(u''.join(self._buffer))
401 401 except Exception:
402 402 return False
403 403 else:
404 404 if len(code_ast.body) == 1:
405 405 return False
406 406
407 407 # When input is complete, then termination is marked by an extra blank
408 408 # line at the end.
409 409 last_line = self.source.splitlines()[-1]
410 410 return bool(last_line and not last_line.isspace())
411 411
412 412 #------------------------------------------------------------------------
413 413 # Private interface
414 414 #------------------------------------------------------------------------
415 415
416 416 def _find_indent(self, line):
417 417 """Compute the new indentation level for a single line.
418 418
419 419 Parameters
420 420 ----------
421 421 line : str
422 422 A single new line of non-whitespace, non-comment Python input.
423 423
424 424 Returns
425 425 -------
426 426 indent_spaces : int
427 427 New value for the indent level (it may be equal to self.indent_spaces
428 428 if indentation doesn't change.
429 429
430 430 full_dedent : boolean
431 431 Whether the new line causes a full flush-left dedent.
432 432 """
433 433 indent_spaces = self.indent_spaces
434 434 full_dedent = self._full_dedent
435 435
436 436 inisp = num_ini_spaces(line)
437 437 if inisp < indent_spaces:
438 438 indent_spaces = inisp
439 439 if indent_spaces <= 0:
440 440 #print 'Full dedent in text',self.source # dbg
441 441 full_dedent = True
442 442
443 443 if line.rstrip()[-1] == ':':
444 444 indent_spaces += 4
445 445 elif dedent_re.match(line):
446 446 indent_spaces -= 4
447 447 if indent_spaces <= 0:
448 448 full_dedent = True
449 449
450 450 # Safety
451 451 if indent_spaces < 0:
452 452 indent_spaces = 0
453 453 #print 'safety' # dbg
454 454
455 455 return indent_spaces, full_dedent
456 456
457 457 def _update_indent(self, lines):
458 458 for line in remove_comments(lines).splitlines():
459 459 if line and not line.isspace():
460 460 self.indent_spaces, self._full_dedent = self._find_indent(line)
461 461
462 462 def _store(self, lines, buffer=None, store='source'):
463 463 """Store one or more lines of input.
464 464
465 465 If input lines are not newline-terminated, a newline is automatically
466 466 appended."""
467 467
468 468 if buffer is None:
469 469 buffer = self._buffer
470 470
471 471 if lines.endswith('\n'):
472 472 buffer.append(lines)
473 473 else:
474 474 buffer.append(lines+'\n')
475 475 setattr(self, store, self._set_source(buffer))
476 476
477 477 def _set_source(self, buffer):
478 478 return u''.join(buffer)
479 479
480 480
481 481 #-----------------------------------------------------------------------------
482 482 # Functions and classes for IPython-specific syntactic support
483 483 #-----------------------------------------------------------------------------
484 484
485 485 # The escaped translators ALL receive a line where their own escape has been
486 486 # stripped. Only '?' is valid at the end of the line, all others can only be
487 487 # placed at the start.
488 488
489 489 # Transformations of the special syntaxes that don't rely on an explicit escape
490 490 # character but instead on patterns on the input line
491 491
492 492 # The core transformations are implemented as standalone functions that can be
493 493 # tested and validated in isolation. Each of these uses a regexp, we
494 494 # pre-compile these and keep them close to each function definition for clarity
495 495
496 496 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
497 497 r'\s*=\s*!\s*(?P<cmd>.*)')
498 498
499 499 def transform_assign_system(line):
500 500 """Handle the `files = !ls` syntax."""
501 501 m = _assign_system_re.match(line)
502 502 if m is not None:
503 503 cmd = m.group('cmd')
504 504 lhs = m.group('lhs')
505 505 new_line = '%s = get_ipython().getoutput(%r)' % (lhs, cmd)
506 506 return new_line
507 507 return line
508 508
509 509
510 510 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
511 511 r'\s*=\s*%\s*(?P<cmd>.*)')
512 512
513 513 def transform_assign_magic(line):
514 514 """Handle the `a = %who` syntax."""
515 515 m = _assign_magic_re.match(line)
516 516 if m is not None:
517 517 cmd = m.group('cmd')
518 518 lhs = m.group('lhs')
519 519 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
520 520 return new_line
521 521 return line
522 522
523 523
524 524 _classic_prompt_re = re.compile(r'^([ \t]*>>> |^[ \t]*\.\.\. )')
525 525
526 526 def transform_classic_prompt(line):
527 527 """Handle inputs that start with '>>> ' syntax."""
528 528
529 529 if not line or line.isspace():
530 530 return line
531 531 m = _classic_prompt_re.match(line)
532 532 if m:
533 533 return line[len(m.group(0)):]
534 534 else:
535 535 return line
536 536
537 537
538 538 _ipy_prompt_re = re.compile(r'^([ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
539 539
540 540 def transform_ipy_prompt(line):
541 541 """Handle inputs that start classic IPython prompt syntax."""
542 542
543 543 if not line or line.isspace():
544 544 return line
545 545 #print 'LINE: %r' % line # dbg
546 546 m = _ipy_prompt_re.match(line)
547 547 if m:
548 548 #print 'MATCH! %r -> %r' % (line, line[len(m.group(0)):]) # dbg
549 549 return line[len(m.group(0)):]
550 550 else:
551 551 return line
552 552
553 553
554 554 def _make_help_call(target, esc, lspace, next_input=None):
555 555 """Prepares a pinfo(2)/psearch call from a target name and the escape
556 556 (i.e. ? or ??)"""
557 557 method = 'pinfo2' if esc == '??' \
558 558 else 'psearch' if '*' in target \
559 559 else 'pinfo'
560 560 arg = " ".join([method, target])
561 561
562 562 if next_input:
563 563 tpl = '%sget_ipython().magic(%r, next_input=%r)'
564 564 return tpl % (lspace, arg, next_input)
565 565 else:
566 566 return '%sget_ipython().magic(%r)' % (lspace, arg)
567 567
568 568 _initial_space_re = re.compile(r'\s*')
569 569 _help_end_re = re.compile(r"""(%?
570 570 [a-zA-Z_*][\w*]* # Variable name
571 571 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
572 572 )
573 573 (\?\??)$ # ? or ??""",
574 574 re.VERBOSE)
575 575 def transform_help_end(line):
576 576 """Translate lines with ?/?? at the end"""
577 577 m = _help_end_re.search(line)
578 578 if m is None or has_comment(line):
579 579 return line
580 580 target = m.group(1)
581 581 esc = m.group(3)
582 582 lspace = _initial_space_re.match(line).group(0)
583 583
584 584 # If we're mid-command, put it back on the next prompt for the user.
585 585 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
586 586
587 587 return _make_help_call(target, esc, lspace, next_input)
588 588
589 589
590 590 class EscapedTransformer(object):
591 591 """Class to transform lines that are explicitly escaped out."""
592 592
593 593 def __init__(self):
594 594 tr = { ESC_SHELL : self._tr_system,
595 595 ESC_SH_CAP : self._tr_system2,
596 596 ESC_HELP : self._tr_help,
597 597 ESC_HELP2 : self._tr_help,
598 598 ESC_MAGIC : self._tr_magic,
599 599 ESC_QUOTE : self._tr_quote,
600 600 ESC_QUOTE2 : self._tr_quote2,
601 601 ESC_PAREN : self._tr_paren }
602 602 self.tr = tr
603 603
604 604 # Support for syntax transformations that use explicit escapes typed by the
605 605 # user at the beginning of a line
606 606 @staticmethod
607 607 def _tr_system(line_info):
608 608 "Translate lines escaped with: !"
609 609 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
610 610 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
611 611
612 612 @staticmethod
613 613 def _tr_system2(line_info):
614 614 "Translate lines escaped with: !!"
615 615 cmd = line_info.line.lstrip()[2:]
616 616 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
617 617
618 618 @staticmethod
619 619 def _tr_help(line_info):
620 620 "Translate lines escaped with: ?/??"
621 621 # A naked help line should just fire the intro help screen
622 622 if not line_info.line[1:]:
623 623 return 'get_ipython().show_usage()'
624 624
625 625 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
626 626
627 627 @staticmethod
628 628 def _tr_magic(line_info):
629 629 "Translate lines escaped with: %"
630 630 tpl = '%sget_ipython().magic(%r)'
631 631 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
632 632 return tpl % (line_info.pre, cmd)
633 633
634 634 @staticmethod
635 635 def _tr_quote(line_info):
636 636 "Translate lines escaped with: ,"
637 637 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
638 638 '", "'.join(line_info.the_rest.split()) )
639 639
640 640 @staticmethod
641 641 def _tr_quote2(line_info):
642 642 "Translate lines escaped with: ;"
643 643 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
644 644 line_info.the_rest)
645 645
646 646 @staticmethod
647 647 def _tr_paren(line_info):
648 648 "Translate lines escaped with: /"
649 649 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
650 650 ", ".join(line_info.the_rest.split()))
651 651
652 652 def __call__(self, line):
653 653 """Class to transform lines that are explicitly escaped out.
654 654
655 655 This calls the above _tr_* static methods for the actual line
656 656 translations."""
657 657
658 658 # Empty lines just get returned unmodified
659 659 if not line or line.isspace():
660 660 return line
661 661
662 662 # Get line endpoints, where the escapes can be
663 663 line_info = LineInfo(line)
664 664
665 665 if not line_info.esc in self.tr:
666 666 # If we don't recognize the escape, don't modify the line
667 667 return line
668 668
669 669 return self.tr[line_info.esc](line_info)
670 670
671 671
672 672 # A function-looking object to be used by the rest of the code. The purpose of
673 673 # the class in this case is to organize related functionality, more than to
674 674 # manage state.
675 675 transform_escaped = EscapedTransformer()
676 676
677 677
678 678 class IPythonInputSplitter(InputSplitter):
679 679 """An input splitter that recognizes all of IPython's special syntax."""
680 680
681 681 # String with raw, untransformed input.
682 682 source_raw = ''
683 683
684 684 # Private attributes
685 685
686 686 # List with lines of raw input accumulated so far.
687 687 _buffer_raw = None
688 688
689 689 def __init__(self, input_mode=None):
690 690 InputSplitter.__init__(self, input_mode)
691 691 self._buffer_raw = []
692 692
693 693 def reset(self):
694 694 """Reset the input buffer and associated state."""
695 695 InputSplitter.reset(self)
696 696 self._buffer_raw[:] = []
697 697 self.source_raw = ''
698 698
699 699 def source_raw_reset(self):
700 700 """Return input and raw source and perform a full reset.
701 701 """
702 702 out = self.source
703 703 out_r = self.source_raw
704 704 self.reset()
705 705 return out, out_r
706 706
707 707 def push(self, lines):
708 708 """Push one or more lines of IPython input.
709 709 """
710 710 if not lines:
711 711 return super(IPythonInputSplitter, self).push(lines)
712 712
713 713 # We must ensure all input is pure unicode
714 714 lines = cast_unicode(lines, self.encoding)
715 715
716 716 lines_list = lines.splitlines()
717 717
718 718 transforms = [transform_ipy_prompt, transform_classic_prompt,
719 719 transform_help_end, transform_escaped,
720 720 transform_assign_system, transform_assign_magic]
721 721
722 722 # Transform logic
723 723 #
724 724 # We only apply the line transformers to the input if we have either no
725 725 # input yet, or complete input, or if the last line of the buffer ends
726 726 # with ':' (opening an indented block). This prevents the accidental
727 727 # transformation of escapes inside multiline expressions like
728 728 # triple-quoted strings or parenthesized expressions.
729 729 #
730 730 # The last heuristic, while ugly, ensures that the first line of an
731 731 # indented block is correctly transformed.
732 732 #
733 733 # FIXME: try to find a cleaner approach for this last bit.
734 734
735 735 # If we were in 'block' mode, since we're going to pump the parent
736 736 # class by hand line by line, we need to temporarily switch out to
737 737 # 'line' mode, do a single manual reset and then feed the lines one
738 738 # by one. Note that this only matters if the input has more than one
739 739 # line.
740 740 changed_input_mode = False
741 741
742 742 if self.input_mode == 'cell':
743 743 self.reset()
744 744 changed_input_mode = True
745 745 saved_input_mode = 'cell'
746 746 self.input_mode = 'line'
747 747
748 748 # Store raw source before applying any transformations to it. Note
749 749 # that this must be done *after* the reset() call that would otherwise
750 750 # flush the buffer.
751 751 self._store(lines, self._buffer_raw, 'source_raw')
752 752
753 753 try:
754 754 push = super(IPythonInputSplitter, self).push
755 755 buf = self._buffer
756 756 for line in lines_list:
757 757 if self._is_complete or not buf or \
758 758 (buf and (buf[-1].rstrip().endswith(':') or
759 759 buf[-1].rstrip().endswith(',')) ):
760 760 for f in transforms:
761 761 line = f(line)
762 762
763 763 out = push(line)
764 764 finally:
765 765 if changed_input_mode:
766 766 self.input_mode = saved_input_mode
767 767 return out
@@ -1,29 +1,29 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module is *completely* deprecated and should no longer be used for
4 4 any purpose. Currently, we have a few parts of the core that have
5 5 not been componentized and thus, still rely on this module. When everything
6 6 has been made into a component, this module will be sent to deathrow.
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2009 The IPython Development Team
10 # Copyright (C) 2008-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Classes and functions
22 22 #-----------------------------------------------------------------------------
23 23
24 24
25 25 def get():
26 26 """Get the global InteractiveShell instance."""
27 27 from IPython.core.interactiveshell import InteractiveShell
28 28 return InteractiveShell.instance()
29 29
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,217 +1,217 b''
1 1 ''' A decorator-based method of constructing IPython magics with `argparse`
2 2 option handling.
3 3
4 4 New magic functions can be defined like so::
5 5
6 6 from IPython.core.magic_arguments import (argument, magic_arguments,
7 7 parse_argstring)
8 8
9 9 @magic_arguments()
10 10 @argument('-o', '--option', help='An optional argument.')
11 11 @argument('arg', type=int, help='An integer positional argument.')
12 12 def magic_cool(self, arg):
13 13 """ A really cool magic command.
14 14
15 15 """
16 16 args = parse_argstring(magic_cool, arg)
17 17 ...
18 18
19 19 The `@magic_arguments` decorator marks the function as having argparse arguments.
20 20 The `@argument` decorator adds an argument using the same syntax as argparse's
21 21 `add_argument()` method. More sophisticated uses may also require the
22 22 `@argument_group` or `@kwds` decorator to customize the formatting and the
23 23 parsing.
24 24
25 25 Help text for the magic is automatically generated from the docstring and the
26 26 arguments::
27 27
28 28 In[1]: %cool?
29 29 %cool [-o OPTION] arg
30 30
31 31 A really cool magic command.
32 32
33 33 positional arguments:
34 34 arg An integer positional argument.
35 35
36 36 optional arguments:
37 37 -o OPTION, --option OPTION
38 38 An optional argument.
39 39
40 40 '''
41 41 #-----------------------------------------------------------------------------
42 # Copyright (c) 2010, IPython Development Team.
42 # Copyright (C) 2010-2011, IPython Development Team.
43 43 #
44 44 # Distributed under the terms of the Modified BSD License.
45 45 #
46 46 # The full license is in the file COPYING.txt, distributed with this software.
47 47 #-----------------------------------------------------------------------------
48 48
49 49 # Our own imports
50 50 from IPython.external import argparse
51 51 from IPython.core.error import UsageError
52 52 from IPython.utils.process import arg_split
53 53
54 54
55 55 class MagicArgumentParser(argparse.ArgumentParser):
56 56 """ An ArgumentParser tweaked for use by IPython magics.
57 57 """
58 58 def __init__(self,
59 59 prog=None,
60 60 usage=None,
61 61 description=None,
62 62 epilog=None,
63 63 version=None,
64 64 parents=None,
65 65 formatter_class=argparse.HelpFormatter,
66 66 prefix_chars='-',
67 67 argument_default=None,
68 68 conflict_handler='error',
69 69 add_help=False):
70 70 if parents is None:
71 71 parents = []
72 72 super(MagicArgumentParser, self).__init__(prog=prog, usage=usage,
73 73 description=description, epilog=epilog, version=version,
74 74 parents=parents, formatter_class=formatter_class,
75 75 prefix_chars=prefix_chars, argument_default=argument_default,
76 76 conflict_handler=conflict_handler, add_help=add_help)
77 77
78 78 def error(self, message):
79 79 """ Raise a catchable error instead of exiting.
80 80 """
81 81 raise UsageError(message)
82 82
83 83 def parse_argstring(self, argstring):
84 84 """ Split a string into an argument list and parse that argument list.
85 85 """
86 86 argv = arg_split(argstring)
87 87 return self.parse_args(argv)
88 88
89 89
90 90 def construct_parser(magic_func):
91 91 """ Construct an argument parser using the function decorations.
92 92 """
93 93 kwds = getattr(magic_func, 'argcmd_kwds', {})
94 94 if 'description' not in kwds:
95 95 kwds['description'] = getattr(magic_func, '__doc__', None)
96 96 arg_name = real_name(magic_func)
97 97 parser = MagicArgumentParser(arg_name, **kwds)
98 98 # Reverse the list of decorators in order to apply them in the
99 99 # order in which they appear in the source.
100 100 group = None
101 101 for deco in magic_func.decorators[::-1]:
102 102 result = deco.add_to_parser(parser, group)
103 103 if result is not None:
104 104 group = result
105 105
106 106 # Replace the starting 'usage: ' with IPython's %.
107 107 help_text = parser.format_help()
108 108 if help_text.startswith('usage: '):
109 109 help_text = help_text.replace('usage: ', '%', 1)
110 110 else:
111 111 help_text = '%' + help_text
112 112
113 113 # Replace the magic function's docstring with the full help text.
114 114 magic_func.__doc__ = help_text
115 115
116 116 return parser
117 117
118 118
119 119 def parse_argstring(magic_func, argstring):
120 120 """ Parse the string of arguments for the given magic function.
121 121 """
122 122 return magic_func.parser.parse_argstring(argstring)
123 123
124 124
125 125 def real_name(magic_func):
126 126 """ Find the real name of the magic.
127 127 """
128 128 magic_name = magic_func.__name__
129 129 if magic_name.startswith('magic_'):
130 130 magic_name = magic_name[len('magic_'):]
131 131 return getattr(magic_func, 'argcmd_name', magic_name)
132 132
133 133
134 134 class ArgDecorator(object):
135 135 """ Base class for decorators to add ArgumentParser information to a method.
136 136 """
137 137
138 138 def __call__(self, func):
139 139 if not getattr(func, 'has_arguments', False):
140 140 func.has_arguments = True
141 141 func.decorators = []
142 142 func.decorators.append(self)
143 143 return func
144 144
145 145 def add_to_parser(self, parser, group):
146 146 """ Add this object's information to the parser, if necessary.
147 147 """
148 148 pass
149 149
150 150
151 151 class magic_arguments(ArgDecorator):
152 152 """ Mark the magic as having argparse arguments and possibly adjust the
153 153 name.
154 154 """
155 155
156 156 def __init__(self, name=None):
157 157 self.name = name
158 158
159 159 def __call__(self, func):
160 160 if not getattr(func, 'has_arguments', False):
161 161 func.has_arguments = True
162 162 func.decorators = []
163 163 if self.name is not None:
164 164 func.argcmd_name = self.name
165 165 # This should be the first decorator in the list of decorators, thus the
166 166 # last to execute. Build the parser.
167 167 func.parser = construct_parser(func)
168 168 return func
169 169
170 170
171 171 class argument(ArgDecorator):
172 172 """ Store arguments and keywords to pass to add_argument().
173 173
174 174 Instances also serve to decorate command methods.
175 175 """
176 176 def __init__(self, *args, **kwds):
177 177 self.args = args
178 178 self.kwds = kwds
179 179
180 180 def add_to_parser(self, parser, group):
181 181 """ Add this object's information to the parser.
182 182 """
183 183 if group is not None:
184 184 parser = group
185 185 parser.add_argument(*self.args, **self.kwds)
186 186 return None
187 187
188 188
189 189 class argument_group(ArgDecorator):
190 190 """ Store arguments and keywords to pass to add_argument_group().
191 191
192 192 Instances also serve to decorate command methods.
193 193 """
194 194 def __init__(self, *args, **kwds):
195 195 self.args = args
196 196 self.kwds = kwds
197 197
198 198 def add_to_parser(self, parser, group):
199 199 """ Add this object's information to the parser.
200 200 """
201 201 return parser.add_argument_group(*self.args, **self.kwds)
202 202
203 203
204 204 class kwds(ArgDecorator):
205 205 """ Provide other keywords to the sub-parser constructor.
206 206 """
207 207 def __init__(self, **kwds):
208 208 self.kwds = kwds
209 209
210 210 def __call__(self, func):
211 211 func = super(kwds, self).__call__(func)
212 212 func.argcmd_kwds = self.kwds
213 213 return func
214 214
215 215
216 216 __all__ = ['magic_arguments', 'argument', 'argument_group', 'kwds',
217 217 'parse_argstring']
@@ -1,340 +1,340 b''
1 1 # encoding: utf-8
2 2 """
3 3 Paging capabilities for IPython.core
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9
10 10 Notes
11 11 -----
12 12
13 13 For now this uses ipapi, so it can't be in IPython.utils. If we can get
14 14 rid of that dependency, we could move it there.
15 15 -----
16 16 """
17 17
18 18 #-----------------------------------------------------------------------------
19 # Copyright (C) 2008-2009 The IPython Development Team
19 # Copyright (C) 2008-2011 The IPython Development Team
20 20 #
21 21 # Distributed under the terms of the BSD License. The full license is in
22 22 # the file COPYING, distributed as part of this software.
23 23 #-----------------------------------------------------------------------------
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Imports
27 27 #-----------------------------------------------------------------------------
28 28
29 29 import os
30 30 import re
31 31 import sys
32 32 import tempfile
33 33
34 34 from io import UnsupportedOperation
35 35
36 36 from IPython.core import ipapi
37 37 from IPython.core.error import TryNext
38 38 from IPython.utils.cursesimport import use_curses
39 39 from IPython.utils.data import chop
40 40 from IPython.utils import io
41 41 from IPython.utils.process import system
42 42 from IPython.utils.terminal import get_terminal_size
43 43
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Classes and functions
47 47 #-----------------------------------------------------------------------------
48 48
49 49 esc_re = re.compile(r"(\x1b[^m]+m)")
50 50
51 51 def page_dumb(strng, start=0, screen_lines=25):
52 52 """Very dumb 'pager' in Python, for when nothing else works.
53 53
54 54 Only moves forward, same interface as page(), except for pager_cmd and
55 55 mode."""
56 56
57 57 out_ln = strng.splitlines()[start:]
58 58 screens = chop(out_ln,screen_lines-1)
59 59 if len(screens) == 1:
60 60 print >>io.stdout, os.linesep.join(screens[0])
61 61 else:
62 62 last_escape = ""
63 63 for scr in screens[0:-1]:
64 64 hunk = os.linesep.join(scr)
65 65 print >>io.stdout, last_escape + hunk
66 66 if not page_more():
67 67 return
68 68 esc_list = esc_re.findall(hunk)
69 69 if len(esc_list) > 0:
70 70 last_escape = esc_list[-1]
71 71 print >>io.stdout, last_escape + os.linesep.join(screens[-1])
72 72
73 73 def _detect_screen_size(use_curses, screen_lines_def):
74 74 """Attempt to work out the number of lines on the screen.
75 75
76 76 This is called by page(). It can raise an error (e.g. when run in the
77 77 test suite), so it's separated out so it can easily be called in a try block.
78 78 """
79 79 TERM = os.environ.get('TERM',None)
80 80 if (TERM=='xterm' or TERM=='xterm-color') and sys.platform != 'sunos5':
81 81 local_use_curses = use_curses
82 82 else:
83 83 # curses causes problems on many terminals other than xterm, and
84 84 # some termios calls lock up on Sun OS5.
85 85 local_use_curses = False
86 86 if local_use_curses:
87 87 import termios
88 88 import curses
89 89 # There is a bug in curses, where *sometimes* it fails to properly
90 90 # initialize, and then after the endwin() call is made, the
91 91 # terminal is left in an unusable state. Rather than trying to
92 92 # check everytime for this (by requesting and comparing termios
93 93 # flags each time), we just save the initial terminal state and
94 94 # unconditionally reset it every time. It's cheaper than making
95 95 # the checks.
96 96 term_flags = termios.tcgetattr(sys.stdout)
97 97
98 98 # Curses modifies the stdout buffer size by default, which messes
99 99 # up Python's normal stdout buffering. This would manifest itself
100 100 # to IPython users as delayed printing on stdout after having used
101 101 # the pager.
102 102 #
103 103 # We can prevent this by manually setting the NCURSES_NO_SETBUF
104 104 # environment variable. For more details, see:
105 105 # http://bugs.python.org/issue10144
106 106 NCURSES_NO_SETBUF = os.environ.get('NCURSES_NO_SETBUF', None)
107 107 os.environ['NCURSES_NO_SETBUF'] = ''
108 108
109 109 # Proceed with curses initialization
110 110 scr = curses.initscr()
111 111 screen_lines_real,screen_cols = scr.getmaxyx()
112 112 curses.endwin()
113 113
114 114 # Restore environment
115 115 if NCURSES_NO_SETBUF is None:
116 116 del os.environ['NCURSES_NO_SETBUF']
117 117 else:
118 118 os.environ['NCURSES_NO_SETBUF'] = NCURSES_NO_SETBUF
119 119
120 120 # Restore terminal state in case endwin() didn't.
121 121 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
122 122 # Now we have what we needed: the screen size in rows/columns
123 123 return screen_lines_real
124 124 #print '***Screen size:',screen_lines_real,'lines x',\
125 125 #screen_cols,'columns.' # dbg
126 126 else:
127 127 return screen_lines_def
128 128
129 129 def page(strng, start=0, screen_lines=0, pager_cmd=None):
130 130 """Print a string, piping through a pager after a certain length.
131 131
132 132 The screen_lines parameter specifies the number of *usable* lines of your
133 133 terminal screen (total lines minus lines you need to reserve to show other
134 134 information).
135 135
136 136 If you set screen_lines to a number <=0, page() will try to auto-determine
137 137 your screen size and will only use up to (screen_size+screen_lines) for
138 138 printing, paging after that. That is, if you want auto-detection but need
139 139 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
140 140 auto-detection without any lines reserved simply use screen_lines = 0.
141 141
142 142 If a string won't fit in the allowed lines, it is sent through the
143 143 specified pager command. If none given, look for PAGER in the environment,
144 144 and ultimately default to less.
145 145
146 146 If no system pager works, the string is sent through a 'dumb pager'
147 147 written in python, very simplistic.
148 148 """
149 149
150 150 # Some routines may auto-compute start offsets incorrectly and pass a
151 151 # negative value. Offset to 0 for robustness.
152 152 start = max(0, start)
153 153
154 154 # first, try the hook
155 155 ip = ipapi.get()
156 156 if ip:
157 157 try:
158 158 ip.hooks.show_in_pager(strng)
159 159 return
160 160 except TryNext:
161 161 pass
162 162
163 163 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
164 164 TERM = os.environ.get('TERM','dumb')
165 165 if TERM in ['dumb','emacs'] and os.name != 'nt':
166 166 print strng
167 167 return
168 168 # chop off the topmost part of the string we don't want to see
169 169 str_lines = strng.splitlines()[start:]
170 170 str_toprint = os.linesep.join(str_lines)
171 171 num_newlines = len(str_lines)
172 172 len_str = len(str_toprint)
173 173
174 174 # Dumb heuristics to guesstimate number of on-screen lines the string
175 175 # takes. Very basic, but good enough for docstrings in reasonable
176 176 # terminals. If someone later feels like refining it, it's not hard.
177 177 numlines = max(num_newlines,int(len_str/80)+1)
178 178
179 179 screen_lines_def = get_terminal_size()[1]
180 180
181 181 # auto-determine screen size
182 182 if screen_lines <= 0:
183 183 try:
184 184 screen_lines += _detect_screen_size(use_curses, screen_lines_def)
185 185 except (TypeError, UnsupportedOperation):
186 186 print >>io.stdout, str_toprint
187 187 return
188 188
189 189 #print 'numlines',numlines,'screenlines',screen_lines # dbg
190 190 if numlines <= screen_lines :
191 191 #print '*** normal print' # dbg
192 192 print >>io.stdout, str_toprint
193 193 else:
194 194 # Try to open pager and default to internal one if that fails.
195 195 # All failure modes are tagged as 'retval=1', to match the return
196 196 # value of a failed system command. If any intermediate attempt
197 197 # sets retval to 1, at the end we resort to our own page_dumb() pager.
198 198 pager_cmd = get_pager_cmd(pager_cmd)
199 199 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
200 200 if os.name == 'nt':
201 201 if pager_cmd.startswith('type'):
202 202 # The default WinXP 'type' command is failing on complex strings.
203 203 retval = 1
204 204 else:
205 205 tmpname = tempfile.mktemp('.txt')
206 206 tmpfile = file(tmpname,'wt')
207 207 tmpfile.write(strng)
208 208 tmpfile.close()
209 209 cmd = "%s < %s" % (pager_cmd,tmpname)
210 210 if os.system(cmd):
211 211 retval = 1
212 212 else:
213 213 retval = None
214 214 os.remove(tmpname)
215 215 else:
216 216 try:
217 217 retval = None
218 218 # if I use popen4, things hang. No idea why.
219 219 #pager,shell_out = os.popen4(pager_cmd)
220 220 pager = os.popen(pager_cmd,'w')
221 221 pager.write(strng)
222 222 pager.close()
223 223 retval = pager.close() # success returns None
224 224 except IOError,msg: # broken pipe when user quits
225 225 if msg.args == (32,'Broken pipe'):
226 226 retval = None
227 227 else:
228 228 retval = 1
229 229 except OSError:
230 230 # Other strange problems, sometimes seen in Win2k/cygwin
231 231 retval = 1
232 232 if retval is not None:
233 233 page_dumb(strng,screen_lines=screen_lines)
234 234
235 235
236 236 def page_file(fname, start=0, pager_cmd=None):
237 237 """Page a file, using an optional pager command and starting line.
238 238 """
239 239
240 240 pager_cmd = get_pager_cmd(pager_cmd)
241 241 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
242 242
243 243 try:
244 244 if os.environ['TERM'] in ['emacs','dumb']:
245 245 raise EnvironmentError
246 246 system(pager_cmd + ' ' + fname)
247 247 except:
248 248 try:
249 249 if start > 0:
250 250 start -= 1
251 251 page(open(fname).read(),start)
252 252 except:
253 253 print 'Unable to show file',`fname`
254 254
255 255
256 256 def get_pager_cmd(pager_cmd=None):
257 257 """Return a pager command.
258 258
259 259 Makes some attempts at finding an OS-correct one.
260 260 """
261 261 if os.name == 'posix':
262 262 default_pager_cmd = 'less -r' # -r for color control sequences
263 263 elif os.name in ['nt','dos']:
264 264 default_pager_cmd = 'type'
265 265
266 266 if pager_cmd is None:
267 267 try:
268 268 pager_cmd = os.environ['PAGER']
269 269 except:
270 270 pager_cmd = default_pager_cmd
271 271 return pager_cmd
272 272
273 273
274 274 def get_pager_start(pager, start):
275 275 """Return the string for paging files with an offset.
276 276
277 277 This is the '+N' argument which less and more (under Unix) accept.
278 278 """
279 279
280 280 if pager in ['less','more']:
281 281 if start:
282 282 start_string = '+' + str(start)
283 283 else:
284 284 start_string = ''
285 285 else:
286 286 start_string = ''
287 287 return start_string
288 288
289 289
290 290 # (X)emacs on win32 doesn't like to be bypassed with msvcrt.getch()
291 291 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
292 292 import msvcrt
293 293 def page_more():
294 294 """ Smart pausing between pages
295 295
296 296 @return: True if need print more lines, False if quit
297 297 """
298 298 io.stdout.write('---Return to continue, q to quit--- ')
299 299 ans = msvcrt.getch()
300 300 if ans in ("q", "Q"):
301 301 result = False
302 302 else:
303 303 result = True
304 304 io.stdout.write("\b"*37 + " "*37 + "\b"*37)
305 305 return result
306 306 else:
307 307 def page_more():
308 308 ans = raw_input('---Return to continue, q to quit--- ')
309 309 if ans.lower().startswith('q'):
310 310 return False
311 311 else:
312 312 return True
313 313
314 314
315 315 def snip_print(str,width = 75,print_full = 0,header = ''):
316 316 """Print a string snipping the midsection to fit in width.
317 317
318 318 print_full: mode control:
319 319 - 0: only snip long strings
320 320 - 1: send to page() directly.
321 321 - 2: snip long strings and ask for full length viewing with page()
322 322 Return 1 if snipping was necessary, 0 otherwise."""
323 323
324 324 if print_full == 1:
325 325 page(header+str)
326 326 return 0
327 327
328 328 print header,
329 329 if len(str) < width:
330 330 print str
331 331 snip = 0
332 332 else:
333 333 whalf = int((width -5)/2)
334 334 print str[:whalf] + ' <...> ' + str[-whalf:]
335 335 snip = 1
336 336 if snip and print_full == 2:
337 337 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
338 338 page(str)
339 339 return snip
340 340
@@ -1,41 +1,41 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Payload system for IPython.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2010 The IPython Development Team
11 # Copyright (C) 2008-2011 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 from IPython.config.configurable import Configurable
22 22 from IPython.utils.traitlets import List
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Main payload class
26 26 #-----------------------------------------------------------------------------
27 27
28 28 class PayloadManager(Configurable):
29 29
30 30 _payload = List([])
31 31
32 32 def write_payload(self, data):
33 33 if not isinstance(data, dict):
34 34 raise TypeError('Each payload write must be a dict, got: %r' % data)
35 35 self._payload.append(data)
36 36
37 37 def read_payload(self):
38 38 return self._payload
39 39
40 40 def clear_payload(self):
41 41 self._payload = []
@@ -1,96 +1,96 b''
1 1 # encoding: utf-8
2 2 """
3 3 A payload based version of page.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2008-2011 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 # Third-party
23 23 try:
24 24 from docutils.core import publish_string
25 25 except ImportError:
26 26 # html paging won't be available, but we don't raise any errors. It's a
27 27 # purely optional feature.
28 28 pass
29 29
30 30 # Our own
31 31 from IPython.core.interactiveshell import InteractiveShell
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Classes and functions
35 35 #-----------------------------------------------------------------------------
36 36
37 37 def page(strng, start=0, screen_lines=0, pager_cmd=None,
38 38 html=None, auto_html=False):
39 39 """Print a string, piping through a pager.
40 40
41 41 This version ignores the screen_lines and pager_cmd arguments and uses
42 42 IPython's payload system instead.
43 43
44 44 Parameters
45 45 ----------
46 46 strng : str
47 47 Text to page.
48 48
49 49 start : int
50 50 Starting line at which to place the display.
51 51
52 52 html : str, optional
53 53 If given, an html string to send as well.
54 54
55 55 auto_html : bool, optional
56 56 If true, the input string is assumed to be valid reStructuredText and is
57 57 converted to HTML with docutils. Note that if docutils is not found,
58 58 this option is silently ignored.
59 59
60 60 Note
61 61 ----
62 62
63 63 Only one of the ``html`` and ``auto_html`` options can be given, not
64 64 both.
65 65 """
66 66
67 67 # Some routines may auto-compute start offsets incorrectly and pass a
68 68 # negative value. Offset to 0 for robustness.
69 69 start = max(0, start)
70 70 shell = InteractiveShell.instance()
71 71
72 72 if auto_html:
73 73 try:
74 74 # These defaults ensure user configuration variables for docutils
75 75 # are not loaded, only our config is used here.
76 76 defaults = {'file_insertion_enabled': 0,
77 77 'raw_enabled': 0,
78 78 '_disable_config': 1}
79 79 html = publish_string(strng, writer_name='html',
80 80 settings_overrides=defaults)
81 81 except:
82 82 pass
83 83
84 84 payload = dict(
85 85 source='IPython.zmq.page.page',
86 86 text=strng,
87 87 html=html,
88 88 start_line_number=start
89 89 )
90 90 shell.payload_manager.write_payload(payload)
91 91
92 92
93 93 def install_payload_page():
94 94 """Install this version of page as IPython.core.page.page."""
95 95 from IPython.core import page as corepage
96 96 corepage.page = page
@@ -1,51 +1,51 b''
1 1 # encoding: utf-8
2 2 """IPython plugins.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from IPython.config.configurable import Configurable
21 21 from IPython.utils.traitlets import Dict
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Main class
25 25 #-----------------------------------------------------------------------------
26 26
27 27 class PluginManager(Configurable):
28 28 """A manager for IPython plugins."""
29 29
30 30 plugins = Dict({})
31 31
32 32 def __init__(self, config=None):
33 33 super(PluginManager, self).__init__(config=config)
34 34
35 35 def register_plugin(self, name, plugin):
36 36 if not isinstance(plugin, Plugin):
37 37 raise TypeError('Expected Plugin, got: %r' % plugin)
38 38 if self.plugins.has_key(name):
39 39 raise KeyError('Plugin with name already exists: %r' % name)
40 40 self.plugins[name] = plugin
41 41
42 42 def unregister_plugin(self, name):
43 43 del self.plugins[name]
44 44
45 45 def get_plugin(self, name, default=None):
46 46 return self.plugins.get(name, default)
47 47
48 48
49 49 class Plugin(Configurable):
50 50 """Base class for IPython plugins."""
51 51 pass
@@ -1,946 +1,946 b''
1 1 # encoding: utf-8
2 2 """
3 3 Prefiltering components.
4 4
5 5 Prefilters transform user input before it is exec'd by Python. These
6 6 transforms are used to implement additional syntax such as !ls and %magic.
7 7
8 8 Authors:
9 9
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Dan Milstein
13 13 * Ville Vainio
14 14 """
15 15
16 16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2009 The IPython Development Team
17 # Copyright (C) 2008-2011 The IPython Development Team
18 18 #
19 19 # Distributed under the terms of the BSD License. The full license is in
20 20 # the file COPYING, distributed as part of this software.
21 21 #-----------------------------------------------------------------------------
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Imports
25 25 #-----------------------------------------------------------------------------
26 26
27 27 import __builtin__
28 28 import codeop
29 29 import re
30 30
31 31 from IPython.core.alias import AliasManager
32 32 from IPython.core.autocall import IPyAutocall
33 33 from IPython.config.configurable import Configurable
34 34 from IPython.core.macro import Macro
35 35 from IPython.core.splitinput import split_user_input, LineInfo
36 36 from IPython.core import page
37 37
38 38 from IPython.utils.traitlets import List, Integer, Any, Unicode, CBool, Bool, Instance
39 39 from IPython.utils.autoattr import auto_attr
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Global utilities, errors and constants
43 43 #-----------------------------------------------------------------------------
44 44
45 45 # Warning, these cannot be changed unless various regular expressions
46 46 # are updated in a number of places. Not great, but at least we told you.
47 47 ESC_SHELL = '!'
48 48 ESC_SH_CAP = '!!'
49 49 ESC_HELP = '?'
50 50 ESC_MAGIC = '%'
51 51 ESC_QUOTE = ','
52 52 ESC_QUOTE2 = ';'
53 53 ESC_PAREN = '/'
54 54
55 55
56 56 class PrefilterError(Exception):
57 57 pass
58 58
59 59
60 60 # RegExp to identify potential function names
61 61 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
62 62
63 63 # RegExp to exclude strings with this start from autocalling. In
64 64 # particular, all binary operators should be excluded, so that if foo is
65 65 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
66 66 # characters '!=()' don't need to be checked for, as the checkPythonChars
67 67 # routine explicitely does so, to catch direct calls and rebindings of
68 68 # existing names.
69 69
70 70 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
71 71 # it affects the rest of the group in square brackets.
72 72 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
73 73 r'|^is |^not |^in |^and |^or ')
74 74
75 75 # try to catch also methods for stuff in lists/tuples/dicts: off
76 76 # (experimental). For this to work, the line_split regexp would need
77 77 # to be modified so it wouldn't break things at '['. That line is
78 78 # nasty enough that I shouldn't change it until I can test it _well_.
79 79 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
80 80
81 81
82 82 # Handler Check Utilities
83 83 def is_shadowed(identifier, ip):
84 84 """Is the given identifier defined in one of the namespaces which shadow
85 85 the alias and magic namespaces? Note that an identifier is different
86 86 than ifun, because it can not contain a '.' character."""
87 87 # This is much safer than calling ofind, which can change state
88 88 return (identifier in ip.user_ns \
89 89 or identifier in ip.internal_ns \
90 90 or identifier in ip.ns_table['builtin'])
91 91
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Main Prefilter manager
95 95 #-----------------------------------------------------------------------------
96 96
97 97
98 98 class PrefilterManager(Configurable):
99 99 """Main prefilter component.
100 100
101 101 The IPython prefilter is run on all user input before it is run. The
102 102 prefilter consumes lines of input and produces transformed lines of
103 103 input.
104 104
105 105 The iplementation consists of two phases:
106 106
107 107 1. Transformers
108 108 2. Checkers and handlers
109 109
110 110 Over time, we plan on deprecating the checkers and handlers and doing
111 111 everything in the transformers.
112 112
113 113 The transformers are instances of :class:`PrefilterTransformer` and have
114 114 a single method :meth:`transform` that takes a line and returns a
115 115 transformed line. The transformation can be accomplished using any
116 116 tool, but our current ones use regular expressions for speed. We also
117 117 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
118 118
119 119 After all the transformers have been run, the line is fed to the checkers,
120 120 which are instances of :class:`PrefilterChecker`. The line is passed to
121 121 the :meth:`check` method, which either returns `None` or a
122 122 :class:`PrefilterHandler` instance. If `None` is returned, the other
123 123 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
124 124 the line is passed to the :meth:`handle` method of the returned
125 125 handler and no further checkers are tried.
126 126
127 127 Both transformers and checkers have a `priority` attribute, that determines
128 128 the order in which they are called. Smaller priorities are tried first.
129 129
130 130 Both transformers and checkers also have `enabled` attribute, which is
131 131 a boolean that determines if the instance is used.
132 132
133 133 Users or developers can change the priority or enabled attribute of
134 134 transformers or checkers, but they must call the :meth:`sort_checkers`
135 135 or :meth:`sort_transformers` method after changing the priority.
136 136 """
137 137
138 138 multi_line_specials = CBool(True, config=True)
139 139 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
140 140
141 141 def __init__(self, shell=None, config=None):
142 142 super(PrefilterManager, self).__init__(shell=shell, config=config)
143 143 self.shell = shell
144 144 self.init_transformers()
145 145 self.init_handlers()
146 146 self.init_checkers()
147 147
148 148 #-------------------------------------------------------------------------
149 149 # API for managing transformers
150 150 #-------------------------------------------------------------------------
151 151
152 152 def init_transformers(self):
153 153 """Create the default transformers."""
154 154 self._transformers = []
155 155 for transformer_cls in _default_transformers:
156 156 transformer_cls(
157 157 shell=self.shell, prefilter_manager=self, config=self.config
158 158 )
159 159
160 160 def sort_transformers(self):
161 161 """Sort the transformers by priority.
162 162
163 163 This must be called after the priority of a transformer is changed.
164 164 The :meth:`register_transformer` method calls this automatically.
165 165 """
166 166 self._transformers.sort(key=lambda x: x.priority)
167 167
168 168 @property
169 169 def transformers(self):
170 170 """Return a list of checkers, sorted by priority."""
171 171 return self._transformers
172 172
173 173 def register_transformer(self, transformer):
174 174 """Register a transformer instance."""
175 175 if transformer not in self._transformers:
176 176 self._transformers.append(transformer)
177 177 self.sort_transformers()
178 178
179 179 def unregister_transformer(self, transformer):
180 180 """Unregister a transformer instance."""
181 181 if transformer in self._transformers:
182 182 self._transformers.remove(transformer)
183 183
184 184 #-------------------------------------------------------------------------
185 185 # API for managing checkers
186 186 #-------------------------------------------------------------------------
187 187
188 188 def init_checkers(self):
189 189 """Create the default checkers."""
190 190 self._checkers = []
191 191 for checker in _default_checkers:
192 192 checker(
193 193 shell=self.shell, prefilter_manager=self, config=self.config
194 194 )
195 195
196 196 def sort_checkers(self):
197 197 """Sort the checkers by priority.
198 198
199 199 This must be called after the priority of a checker is changed.
200 200 The :meth:`register_checker` method calls this automatically.
201 201 """
202 202 self._checkers.sort(key=lambda x: x.priority)
203 203
204 204 @property
205 205 def checkers(self):
206 206 """Return a list of checkers, sorted by priority."""
207 207 return self._checkers
208 208
209 209 def register_checker(self, checker):
210 210 """Register a checker instance."""
211 211 if checker not in self._checkers:
212 212 self._checkers.append(checker)
213 213 self.sort_checkers()
214 214
215 215 def unregister_checker(self, checker):
216 216 """Unregister a checker instance."""
217 217 if checker in self._checkers:
218 218 self._checkers.remove(checker)
219 219
220 220 #-------------------------------------------------------------------------
221 221 # API for managing checkers
222 222 #-------------------------------------------------------------------------
223 223
224 224 def init_handlers(self):
225 225 """Create the default handlers."""
226 226 self._handlers = {}
227 227 self._esc_handlers = {}
228 228 for handler in _default_handlers:
229 229 handler(
230 230 shell=self.shell, prefilter_manager=self, config=self.config
231 231 )
232 232
233 233 @property
234 234 def handlers(self):
235 235 """Return a dict of all the handlers."""
236 236 return self._handlers
237 237
238 238 def register_handler(self, name, handler, esc_strings):
239 239 """Register a handler instance by name with esc_strings."""
240 240 self._handlers[name] = handler
241 241 for esc_str in esc_strings:
242 242 self._esc_handlers[esc_str] = handler
243 243
244 244 def unregister_handler(self, name, handler, esc_strings):
245 245 """Unregister a handler instance by name with esc_strings."""
246 246 try:
247 247 del self._handlers[name]
248 248 except KeyError:
249 249 pass
250 250 for esc_str in esc_strings:
251 251 h = self._esc_handlers.get(esc_str)
252 252 if h is handler:
253 253 del self._esc_handlers[esc_str]
254 254
255 255 def get_handler_by_name(self, name):
256 256 """Get a handler by its name."""
257 257 return self._handlers.get(name)
258 258
259 259 def get_handler_by_esc(self, esc_str):
260 260 """Get a handler by its escape string."""
261 261 return self._esc_handlers.get(esc_str)
262 262
263 263 #-------------------------------------------------------------------------
264 264 # Main prefiltering API
265 265 #-------------------------------------------------------------------------
266 266
267 267 def prefilter_line_info(self, line_info):
268 268 """Prefilter a line that has been converted to a LineInfo object.
269 269
270 270 This implements the checker/handler part of the prefilter pipe.
271 271 """
272 272 # print "prefilter_line_info: ", line_info
273 273 handler = self.find_handler(line_info)
274 274 return handler.handle(line_info)
275 275
276 276 def find_handler(self, line_info):
277 277 """Find a handler for the line_info by trying checkers."""
278 278 for checker in self.checkers:
279 279 if checker.enabled:
280 280 handler = checker.check(line_info)
281 281 if handler:
282 282 return handler
283 283 return self.get_handler_by_name('normal')
284 284
285 285 def transform_line(self, line, continue_prompt):
286 286 """Calls the enabled transformers in order of increasing priority."""
287 287 for transformer in self.transformers:
288 288 if transformer.enabled:
289 289 line = transformer.transform(line, continue_prompt)
290 290 return line
291 291
292 292 def prefilter_line(self, line, continue_prompt=False):
293 293 """Prefilter a single input line as text.
294 294
295 295 This method prefilters a single line of text by calling the
296 296 transformers and then the checkers/handlers.
297 297 """
298 298
299 299 # print "prefilter_line: ", line, continue_prompt
300 300 # All handlers *must* return a value, even if it's blank ('').
301 301
302 302 # save the line away in case we crash, so the post-mortem handler can
303 303 # record it
304 304 self.shell._last_input_line = line
305 305
306 306 if not line:
307 307 # Return immediately on purely empty lines, so that if the user
308 308 # previously typed some whitespace that started a continuation
309 309 # prompt, he can break out of that loop with just an empty line.
310 310 # This is how the default python prompt works.
311 311 return ''
312 312
313 313 # At this point, we invoke our transformers.
314 314 if not continue_prompt or (continue_prompt and self.multi_line_specials):
315 315 line = self.transform_line(line, continue_prompt)
316 316
317 317 # Now we compute line_info for the checkers and handlers
318 318 line_info = LineInfo(line, continue_prompt)
319 319
320 320 # the input history needs to track even empty lines
321 321 stripped = line.strip()
322 322
323 323 normal_handler = self.get_handler_by_name('normal')
324 324 if not stripped:
325 325 if not continue_prompt:
326 326 self.shell.displayhook.prompt_count -= 1
327 327
328 328 return normal_handler.handle(line_info)
329 329
330 330 # special handlers are only allowed for single line statements
331 331 if continue_prompt and not self.multi_line_specials:
332 332 return normal_handler.handle(line_info)
333 333
334 334 prefiltered = self.prefilter_line_info(line_info)
335 335 # print "prefiltered line: %r" % prefiltered
336 336 return prefiltered
337 337
338 338 def prefilter_lines(self, lines, continue_prompt=False):
339 339 """Prefilter multiple input lines of text.
340 340
341 341 This is the main entry point for prefiltering multiple lines of
342 342 input. This simply calls :meth:`prefilter_line` for each line of
343 343 input.
344 344
345 345 This covers cases where there are multiple lines in the user entry,
346 346 which is the case when the user goes back to a multiline history
347 347 entry and presses enter.
348 348 """
349 349 llines = lines.rstrip('\n').split('\n')
350 350 # We can get multiple lines in one shot, where multiline input 'blends'
351 351 # into one line, in cases like recalling from the readline history
352 352 # buffer. We need to make sure that in such cases, we correctly
353 353 # communicate downstream which line is first and which are continuation
354 354 # ones.
355 355 if len(llines) > 1:
356 356 out = '\n'.join([self.prefilter_line(line, lnum>0)
357 357 for lnum, line in enumerate(llines) ])
358 358 else:
359 359 out = self.prefilter_line(llines[0], continue_prompt)
360 360
361 361 return out
362 362
363 363 #-----------------------------------------------------------------------------
364 364 # Prefilter transformers
365 365 #-----------------------------------------------------------------------------
366 366
367 367
368 368 class PrefilterTransformer(Configurable):
369 369 """Transform a line of user input."""
370 370
371 371 priority = Integer(100, config=True)
372 372 # Transformers don't currently use shell or prefilter_manager, but as we
373 373 # move away from checkers and handlers, they will need them.
374 374 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
375 375 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
376 376 enabled = Bool(True, config=True)
377 377
378 378 def __init__(self, shell=None, prefilter_manager=None, config=None):
379 379 super(PrefilterTransformer, self).__init__(
380 380 shell=shell, prefilter_manager=prefilter_manager, config=config
381 381 )
382 382 self.prefilter_manager.register_transformer(self)
383 383
384 384 def transform(self, line, continue_prompt):
385 385 """Transform a line, returning the new one."""
386 386 return None
387 387
388 388 def __repr__(self):
389 389 return "<%s(priority=%r, enabled=%r)>" % (
390 390 self.__class__.__name__, self.priority, self.enabled)
391 391
392 392
393 393 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
394 394 r'\s*=\s*!(?P<cmd>.*)')
395 395
396 396
397 397 class AssignSystemTransformer(PrefilterTransformer):
398 398 """Handle the `files = !ls` syntax."""
399 399
400 400 priority = Integer(100, config=True)
401 401
402 402 def transform(self, line, continue_prompt):
403 403 m = _assign_system_re.match(line)
404 404 if m is not None:
405 405 cmd = m.group('cmd')
406 406 lhs = m.group('lhs')
407 407 expr = "sc =%s" % cmd
408 408 new_line = '%s = get_ipython().magic(%r)' % (lhs, expr)
409 409 return new_line
410 410 return line
411 411
412 412
413 413 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
414 414 r'\s*=\s*%(?P<cmd>.*)')
415 415
416 416 class AssignMagicTransformer(PrefilterTransformer):
417 417 """Handle the `a = %who` syntax."""
418 418
419 419 priority = Integer(200, config=True)
420 420
421 421 def transform(self, line, continue_prompt):
422 422 m = _assign_magic_re.match(line)
423 423 if m is not None:
424 424 cmd = m.group('cmd')
425 425 lhs = m.group('lhs')
426 426 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
427 427 return new_line
428 428 return line
429 429
430 430
431 431 _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
432 432
433 433 class PyPromptTransformer(PrefilterTransformer):
434 434 """Handle inputs that start with '>>> ' syntax."""
435 435
436 436 priority = Integer(50, config=True)
437 437
438 438 def transform(self, line, continue_prompt):
439 439
440 440 if not line or line.isspace() or line.strip() == '...':
441 441 # This allows us to recognize multiple input prompts separated by
442 442 # blank lines and pasted in a single chunk, very common when
443 443 # pasting doctests or long tutorial passages.
444 444 return ''
445 445 m = _classic_prompt_re.match(line)
446 446 if m:
447 447 return line[len(m.group(0)):]
448 448 else:
449 449 return line
450 450
451 451
452 452 _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )')
453 453
454 454 class IPyPromptTransformer(PrefilterTransformer):
455 455 """Handle inputs that start classic IPython prompt syntax."""
456 456
457 457 priority = Integer(50, config=True)
458 458
459 459 def transform(self, line, continue_prompt):
460 460
461 461 if not line or line.isspace() or line.strip() == '...':
462 462 # This allows us to recognize multiple input prompts separated by
463 463 # blank lines and pasted in a single chunk, very common when
464 464 # pasting doctests or long tutorial passages.
465 465 return ''
466 466 m = _ipy_prompt_re.match(line)
467 467 if m:
468 468 return line[len(m.group(0)):]
469 469 else:
470 470 return line
471 471
472 472 #-----------------------------------------------------------------------------
473 473 # Prefilter checkers
474 474 #-----------------------------------------------------------------------------
475 475
476 476
477 477 class PrefilterChecker(Configurable):
478 478 """Inspect an input line and return a handler for that line."""
479 479
480 480 priority = Integer(100, config=True)
481 481 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
482 482 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
483 483 enabled = Bool(True, config=True)
484 484
485 485 def __init__(self, shell=None, prefilter_manager=None, config=None):
486 486 super(PrefilterChecker, self).__init__(
487 487 shell=shell, prefilter_manager=prefilter_manager, config=config
488 488 )
489 489 self.prefilter_manager.register_checker(self)
490 490
491 491 def check(self, line_info):
492 492 """Inspect line_info and return a handler instance or None."""
493 493 return None
494 494
495 495 def __repr__(self):
496 496 return "<%s(priority=%r, enabled=%r)>" % (
497 497 self.__class__.__name__, self.priority, self.enabled)
498 498
499 499
500 500 class EmacsChecker(PrefilterChecker):
501 501
502 502 priority = Integer(100, config=True)
503 503 enabled = Bool(False, config=True)
504 504
505 505 def check(self, line_info):
506 506 "Emacs ipython-mode tags certain input lines."
507 507 if line_info.line.endswith('# PYTHON-MODE'):
508 508 return self.prefilter_manager.get_handler_by_name('emacs')
509 509 else:
510 510 return None
511 511
512 512
513 513 class ShellEscapeChecker(PrefilterChecker):
514 514
515 515 priority = Integer(200, config=True)
516 516
517 517 def check(self, line_info):
518 518 if line_info.line.lstrip().startswith(ESC_SHELL):
519 519 return self.prefilter_manager.get_handler_by_name('shell')
520 520
521 521
522 522 class MacroChecker(PrefilterChecker):
523 523
524 524 priority = Integer(250, config=True)
525 525
526 526 def check(self, line_info):
527 527 obj = self.shell.user_ns.get(line_info.ifun)
528 528 if isinstance(obj, Macro):
529 529 return self.prefilter_manager.get_handler_by_name('macro')
530 530 else:
531 531 return None
532 532
533 533
534 534 class IPyAutocallChecker(PrefilterChecker):
535 535
536 536 priority = Integer(300, config=True)
537 537
538 538 def check(self, line_info):
539 539 "Instances of IPyAutocall in user_ns get autocalled immediately"
540 540 obj = self.shell.user_ns.get(line_info.ifun, None)
541 541 if isinstance(obj, IPyAutocall):
542 542 obj.set_ip(self.shell)
543 543 return self.prefilter_manager.get_handler_by_name('auto')
544 544 else:
545 545 return None
546 546
547 547
548 548 class MultiLineMagicChecker(PrefilterChecker):
549 549
550 550 priority = Integer(400, config=True)
551 551
552 552 def check(self, line_info):
553 553 "Allow ! and !! in multi-line statements if multi_line_specials is on"
554 554 # Note that this one of the only places we check the first character of
555 555 # ifun and *not* the pre_char. Also note that the below test matches
556 556 # both ! and !!.
557 557 if line_info.continue_prompt \
558 558 and self.prefilter_manager.multi_line_specials:
559 559 if line_info.esc == ESC_MAGIC:
560 560 return self.prefilter_manager.get_handler_by_name('magic')
561 561 else:
562 562 return None
563 563
564 564
565 565 class EscCharsChecker(PrefilterChecker):
566 566
567 567 priority = Integer(500, config=True)
568 568
569 569 def check(self, line_info):
570 570 """Check for escape character and return either a handler to handle it,
571 571 or None if there is no escape char."""
572 572 if line_info.line[-1] == ESC_HELP \
573 573 and line_info.esc != ESC_SHELL \
574 574 and line_info.esc != ESC_SH_CAP:
575 575 # the ? can be at the end, but *not* for either kind of shell escape,
576 576 # because a ? can be a vaild final char in a shell cmd
577 577 return self.prefilter_manager.get_handler_by_name('help')
578 578 else:
579 579 if line_info.pre:
580 580 return None
581 581 # This returns None like it should if no handler exists
582 582 return self.prefilter_manager.get_handler_by_esc(line_info.esc)
583 583
584 584
585 585 class AssignmentChecker(PrefilterChecker):
586 586
587 587 priority = Integer(600, config=True)
588 588
589 589 def check(self, line_info):
590 590 """Check to see if user is assigning to a var for the first time, in
591 591 which case we want to avoid any sort of automagic / autocall games.
592 592
593 593 This allows users to assign to either alias or magic names true python
594 594 variables (the magic/alias systems always take second seat to true
595 595 python code). E.g. ls='hi', or ls,that=1,2"""
596 596 if line_info.the_rest:
597 597 if line_info.the_rest[0] in '=,':
598 598 return self.prefilter_manager.get_handler_by_name('normal')
599 599 else:
600 600 return None
601 601
602 602
603 603 class AutoMagicChecker(PrefilterChecker):
604 604
605 605 priority = Integer(700, config=True)
606 606
607 607 def check(self, line_info):
608 608 """If the ifun is magic, and automagic is on, run it. Note: normal,
609 609 non-auto magic would already have been triggered via '%' in
610 610 check_esc_chars. This just checks for automagic. Also, before
611 611 triggering the magic handler, make sure that there is nothing in the
612 612 user namespace which could shadow it."""
613 613 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
614 614 return None
615 615
616 616 # We have a likely magic method. Make sure we should actually call it.
617 617 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
618 618 return None
619 619
620 620 head = line_info.ifun.split('.',1)[0]
621 621 if is_shadowed(head, self.shell):
622 622 return None
623 623
624 624 return self.prefilter_manager.get_handler_by_name('magic')
625 625
626 626
627 627 class AliasChecker(PrefilterChecker):
628 628
629 629 priority = Integer(800, config=True)
630 630
631 631 def check(self, line_info):
632 632 "Check if the initital identifier on the line is an alias."
633 633 # Note: aliases can not contain '.'
634 634 head = line_info.ifun.split('.',1)[0]
635 635 if line_info.ifun not in self.shell.alias_manager \
636 636 or head not in self.shell.alias_manager \
637 637 or is_shadowed(head, self.shell):
638 638 return None
639 639
640 640 return self.prefilter_manager.get_handler_by_name('alias')
641 641
642 642
643 643 class PythonOpsChecker(PrefilterChecker):
644 644
645 645 priority = Integer(900, config=True)
646 646
647 647 def check(self, line_info):
648 648 """If the 'rest' of the line begins with a function call or pretty much
649 649 any python operator, we should simply execute the line (regardless of
650 650 whether or not there's a possible autocall expansion). This avoids
651 651 spurious (and very confusing) geattr() accesses."""
652 652 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
653 653 return self.prefilter_manager.get_handler_by_name('normal')
654 654 else:
655 655 return None
656 656
657 657
658 658 class AutocallChecker(PrefilterChecker):
659 659
660 660 priority = Integer(1000, config=True)
661 661
662 662 def check(self, line_info):
663 663 "Check if the initial word/function is callable and autocall is on."
664 664 if not self.shell.autocall:
665 665 return None
666 666
667 667 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
668 668 if not oinfo['found']:
669 669 return None
670 670
671 671 if callable(oinfo['obj']) \
672 672 and (not re_exclude_auto.match(line_info.the_rest)) \
673 673 and re_fun_name.match(line_info.ifun):
674 674 return self.prefilter_manager.get_handler_by_name('auto')
675 675 else:
676 676 return None
677 677
678 678
679 679 #-----------------------------------------------------------------------------
680 680 # Prefilter handlers
681 681 #-----------------------------------------------------------------------------
682 682
683 683
684 684 class PrefilterHandler(Configurable):
685 685
686 686 handler_name = Unicode('normal')
687 687 esc_strings = List([])
688 688 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
689 689 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
690 690
691 691 def __init__(self, shell=None, prefilter_manager=None, config=None):
692 692 super(PrefilterHandler, self).__init__(
693 693 shell=shell, prefilter_manager=prefilter_manager, config=config
694 694 )
695 695 self.prefilter_manager.register_handler(
696 696 self.handler_name,
697 697 self,
698 698 self.esc_strings
699 699 )
700 700
701 701 def handle(self, line_info):
702 702 # print "normal: ", line_info
703 703 """Handle normal input lines. Use as a template for handlers."""
704 704
705 705 # With autoindent on, we need some way to exit the input loop, and I
706 706 # don't want to force the user to have to backspace all the way to
707 707 # clear the line. The rule will be in this case, that either two
708 708 # lines of pure whitespace in a row, or a line of pure whitespace but
709 709 # of a size different to the indent level, will exit the input loop.
710 710 line = line_info.line
711 711 continue_prompt = line_info.continue_prompt
712 712
713 713 if (continue_prompt and
714 714 self.shell.autoindent and
715 715 line.isspace() and
716 716 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
717 717 line = ''
718 718
719 719 return line
720 720
721 721 def __str__(self):
722 722 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
723 723
724 724
725 725 class AliasHandler(PrefilterHandler):
726 726
727 727 handler_name = Unicode('alias')
728 728
729 729 def handle(self, line_info):
730 730 """Handle alias input lines. """
731 731 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
732 732 # pre is needed, because it carries the leading whitespace. Otherwise
733 733 # aliases won't work in indented sections.
734 734 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, transformed)
735 735
736 736 return line_out
737 737
738 738
739 739 class ShellEscapeHandler(PrefilterHandler):
740 740
741 741 handler_name = Unicode('shell')
742 742 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
743 743
744 744 def handle(self, line_info):
745 745 """Execute the line in a shell, empty return value"""
746 746 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
747 747
748 748 line = line_info.line
749 749 if line.lstrip().startswith(ESC_SH_CAP):
750 750 # rewrite LineInfo's line, ifun and the_rest to properly hold the
751 751 # call to %sx and the actual command to be executed, so
752 752 # handle_magic can work correctly. Note that this works even if
753 753 # the line is indented, so it handles multi_line_specials
754 754 # properly.
755 755 new_rest = line.lstrip()[2:]
756 756 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
757 757 line_info.ifun = 'sx'
758 758 line_info.the_rest = new_rest
759 759 return magic_handler.handle(line_info)
760 760 else:
761 761 cmd = line.lstrip().lstrip(ESC_SHELL)
762 762 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, cmd)
763 763 return line_out
764 764
765 765
766 766 class MacroHandler(PrefilterHandler):
767 767 handler_name = Unicode("macro")
768 768
769 769 def handle(self, line_info):
770 770 obj = self.shell.user_ns.get(line_info.ifun)
771 771 pre_space = line_info.pre_whitespace
772 772 line_sep = "\n" + pre_space
773 773 return pre_space + line_sep.join(obj.value.splitlines())
774 774
775 775
776 776 class MagicHandler(PrefilterHandler):
777 777
778 778 handler_name = Unicode('magic')
779 779 esc_strings = List([ESC_MAGIC])
780 780
781 781 def handle(self, line_info):
782 782 """Execute magic functions."""
783 783 ifun = line_info.ifun
784 784 the_rest = line_info.the_rest
785 785 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
786 786 (ifun + " " + the_rest))
787 787 return cmd
788 788
789 789
790 790 class AutoHandler(PrefilterHandler):
791 791
792 792 handler_name = Unicode('auto')
793 793 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
794 794
795 795 def handle(self, line_info):
796 796 """Handle lines which can be auto-executed, quoting if requested."""
797 797 line = line_info.line
798 798 ifun = line_info.ifun
799 799 the_rest = line_info.the_rest
800 800 pre = line_info.pre
801 801 esc = line_info.esc
802 802 continue_prompt = line_info.continue_prompt
803 803 obj = line_info.ofind(self)['obj']
804 804 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
805 805
806 806 # This should only be active for single-line input!
807 807 if continue_prompt:
808 808 return line
809 809
810 810 force_auto = isinstance(obj, IPyAutocall)
811 811
812 812 # User objects sometimes raise exceptions on attribute access other
813 813 # than AttributeError (we've seen it in the past), so it's safest to be
814 814 # ultra-conservative here and catch all.
815 815 try:
816 816 auto_rewrite = obj.rewrite
817 817 except Exception:
818 818 auto_rewrite = True
819 819
820 820 if esc == ESC_QUOTE:
821 821 # Auto-quote splitting on whitespace
822 822 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
823 823 elif esc == ESC_QUOTE2:
824 824 # Auto-quote whole string
825 825 newcmd = '%s("%s")' % (ifun,the_rest)
826 826 elif esc == ESC_PAREN:
827 827 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
828 828 else:
829 829 # Auto-paren.
830 830 # We only apply it to argument-less calls if the autocall
831 831 # parameter is set to 2. We only need to check that autocall is <
832 832 # 2, since this function isn't called unless it's at least 1.
833 833 if not the_rest and (self.shell.autocall < 2) and not force_auto:
834 834 newcmd = '%s %s' % (ifun,the_rest)
835 835 auto_rewrite = False
836 836 else:
837 837 if not force_auto and the_rest.startswith('['):
838 838 if hasattr(obj,'__getitem__'):
839 839 # Don't autocall in this case: item access for an object
840 840 # which is BOTH callable and implements __getitem__.
841 841 newcmd = '%s %s' % (ifun,the_rest)
842 842 auto_rewrite = False
843 843 else:
844 844 # if the object doesn't support [] access, go ahead and
845 845 # autocall
846 846 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
847 847 elif the_rest.endswith(';'):
848 848 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
849 849 else:
850 850 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
851 851
852 852 if auto_rewrite:
853 853 self.shell.auto_rewrite_input(newcmd)
854 854
855 855 return newcmd
856 856
857 857
858 858 class HelpHandler(PrefilterHandler):
859 859
860 860 handler_name = Unicode('help')
861 861 esc_strings = List([ESC_HELP])
862 862
863 863 def handle(self, line_info):
864 864 """Try to get some help for the object.
865 865
866 866 obj? or ?obj -> basic information.
867 867 obj?? or ??obj -> more details.
868 868 """
869 869 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
870 870 line = line_info.line
871 871 # We need to make sure that we don't process lines which would be
872 872 # otherwise valid python, such as "x=1 # what?"
873 873 try:
874 874 codeop.compile_command(line)
875 875 except SyntaxError:
876 876 # We should only handle as help stuff which is NOT valid syntax
877 877 if line[0]==ESC_HELP:
878 878 line = line[1:]
879 879 elif line[-1]==ESC_HELP:
880 880 line = line[:-1]
881 881 if line:
882 882 #print 'line:<%r>' % line # dbg
883 883 self.shell.magic_pinfo(line_info.ifun)
884 884 else:
885 885 self.shell.show_usage()
886 886 return '' # Empty string is needed here!
887 887 except:
888 888 raise
889 889 # Pass any other exceptions through to the normal handler
890 890 return normal_handler.handle(line_info)
891 891 else:
892 892 # If the code compiles ok, we should handle it normally
893 893 return normal_handler.handle(line_info)
894 894
895 895
896 896 class EmacsHandler(PrefilterHandler):
897 897
898 898 handler_name = Unicode('emacs')
899 899 esc_strings = List([])
900 900
901 901 def handle(self, line_info):
902 902 """Handle input lines marked by python-mode."""
903 903
904 904 # Currently, nothing is done. Later more functionality can be added
905 905 # here if needed.
906 906
907 907 # The input cache shouldn't be updated
908 908 return line_info.line
909 909
910 910
911 911 #-----------------------------------------------------------------------------
912 912 # Defaults
913 913 #-----------------------------------------------------------------------------
914 914
915 915
916 916 _default_transformers = [
917 917 AssignSystemTransformer,
918 918 AssignMagicTransformer,
919 919 PyPromptTransformer,
920 920 IPyPromptTransformer,
921 921 ]
922 922
923 923 _default_checkers = [
924 924 EmacsChecker,
925 925 ShellEscapeChecker,
926 926 MacroChecker,
927 927 IPyAutocallChecker,
928 928 MultiLineMagicChecker,
929 929 EscCharsChecker,
930 930 AssignmentChecker,
931 931 AutoMagicChecker,
932 932 AliasChecker,
933 933 PythonOpsChecker,
934 934 AutocallChecker
935 935 ]
936 936
937 937 _default_handlers = [
938 938 PrefilterHandler,
939 939 AliasHandler,
940 940 ShellEscapeHandler,
941 941 MacroHandler,
942 942 MagicHandler,
943 943 AutoHandler,
944 944 HelpHandler,
945 945 EmacsHandler
946 946 ]
@@ -1,436 +1,436 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Classes for handling input/output prompts.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2010 The IPython Development Team
11 # Copyright (C) 2008-2011 The IPython Development Team
12 12 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
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 os
23 23 import re
24 24 import socket
25 25 import sys
26 26
27 27 from IPython.core import release
28 28 from IPython.external.Itpl import ItplNS
29 29 from IPython.utils import coloransi
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Color schemes for prompts
33 33 #-----------------------------------------------------------------------------
34 34
35 35 PromptColors = coloransi.ColorSchemeTable()
36 36 InputColors = coloransi.InputTermColors # just a shorthand
37 37 Colors = coloransi.TermColors # just a shorthand
38 38
39 39 PromptColors.add_scheme(coloransi.ColorScheme(
40 40 'NoColor',
41 41 in_prompt = InputColors.NoColor, # Input prompt
42 42 in_number = InputColors.NoColor, # Input prompt number
43 43 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45 45
46 46 out_prompt = Colors.NoColor, # Output prompt
47 47 out_number = Colors.NoColor, # Output prompt number
48 48
49 49 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 50 ))
51 51
52 52 # make some schemes as instances so we can copy them for modification easily:
53 53 __PColLinux = coloransi.ColorScheme(
54 54 'Linux',
55 55 in_prompt = InputColors.Green,
56 56 in_number = InputColors.LightGreen,
57 57 in_prompt2 = InputColors.Green,
58 58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59 59
60 60 out_prompt = Colors.Red,
61 61 out_number = Colors.LightRed,
62 62
63 63 normal = Colors.Normal
64 64 )
65 65 # Don't forget to enter it into the table!
66 66 PromptColors.add_scheme(__PColLinux)
67 67
68 68 # Slightly modified Linux for light backgrounds
69 69 __PColLightBG = __PColLinux.copy('LightBG')
70 70
71 71 __PColLightBG.colors.update(
72 72 in_prompt = InputColors.Blue,
73 73 in_number = InputColors.LightBlue,
74 74 in_prompt2 = InputColors.Blue
75 75 )
76 76 PromptColors.add_scheme(__PColLightBG)
77 77
78 78 del Colors,InputColors
79 79
80 80 #-----------------------------------------------------------------------------
81 81 # Utilities
82 82 #-----------------------------------------------------------------------------
83 83
84 84 def multiple_replace(dict, text):
85 85 """ Replace in 'text' all occurences of any key in the given
86 86 dictionary by its corresponding value. Returns the new string."""
87 87
88 88 # Function by Xavier Defrang, originally found at:
89 89 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
90 90
91 91 # Create a regular expression from the dictionary keys
92 92 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
93 93 # For each match, look-up corresponding value in dictionary
94 94 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
95 95
96 96 #-----------------------------------------------------------------------------
97 97 # Special characters that can be used in prompt templates, mainly bash-like
98 98 #-----------------------------------------------------------------------------
99 99
100 100 # If $HOME isn't defined (Windows), make it an absurd string so that it can
101 101 # never be expanded out into '~'. Basically anything which can never be a
102 102 # reasonable directory name will do, we just want the $HOME -> '~' operation
103 103 # to become a no-op. We pre-compute $HOME here so it's not done on every
104 104 # prompt call.
105 105
106 106 # FIXME:
107 107
108 108 # - This should be turned into a class which does proper namespace management,
109 109 # since the prompt specials need to be evaluated in a certain namespace.
110 110 # Currently it's just globals, which need to be managed manually by code
111 111 # below.
112 112
113 113 # - I also need to split up the color schemes from the prompt specials
114 114 # somehow. I don't have a clean design for that quite yet.
115 115
116 116 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
117 117
118 118 # We precompute a few more strings here for the prompt_specials, which are
119 119 # fixed once ipython starts. This reduces the runtime overhead of computing
120 120 # prompt strings.
121 121 USER = os.environ.get("USER")
122 122 HOSTNAME = socket.gethostname()
123 123 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
124 124 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
125 125
126 126 prompt_specials_color = {
127 127 # Prompt/history count
128 128 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
129 129 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
130 130 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
131 131 # can get numbers displayed in whatever color they want.
132 132 r'\N': '${self.cache.prompt_count}',
133 133
134 134 # Prompt/history count, with the actual digits replaced by dots. Used
135 135 # mainly in continuation prompts (prompt_in2)
136 136 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
137 137
138 138 # More robust form of the above expression, that uses the __builtin__
139 139 # module. Note that we can NOT use __builtins__ (note the 's'), because
140 140 # that can either be a dict or a module, and can even mutate at runtime,
141 141 # depending on the context (Python makes no guarantees on it). In
142 142 # contrast, __builtin__ is always a module object, though it must be
143 143 # explicitly imported.
144 144 r'\D': '${"."*__builtin__.len(__builtin__.str(self.cache.prompt_count))}',
145 145
146 146 # Current working directory
147 147 r'\w': '${os.getcwd()}',
148 148 # Current time
149 149 r'\t' : '${time.strftime("%H:%M:%S")}',
150 150 # Basename of current working directory.
151 151 # (use os.sep to make this portable across OSes)
152 152 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
153 153 # These X<N> are an extension to the normal bash prompts. They return
154 154 # N terms of the path, after replacing $HOME with '~'
155 155 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
156 156 r'\X1': '${self.cwd_filt(1)}',
157 157 r'\X2': '${self.cwd_filt(2)}',
158 158 r'\X3': '${self.cwd_filt(3)}',
159 159 r'\X4': '${self.cwd_filt(4)}',
160 160 r'\X5': '${self.cwd_filt(5)}',
161 161 # Y<N> are similar to X<N>, but they show '~' if it's the directory
162 162 # N+1 in the list. Somewhat like %cN in tcsh.
163 163 r'\Y0': '${self.cwd_filt2(0)}',
164 164 r'\Y1': '${self.cwd_filt2(1)}',
165 165 r'\Y2': '${self.cwd_filt2(2)}',
166 166 r'\Y3': '${self.cwd_filt2(3)}',
167 167 r'\Y4': '${self.cwd_filt2(4)}',
168 168 r'\Y5': '${self.cwd_filt2(5)}',
169 169 # Hostname up to first .
170 170 r'\h': HOSTNAME_SHORT,
171 171 # Full hostname
172 172 r'\H': HOSTNAME,
173 173 # Username of current user
174 174 r'\u': USER,
175 175 # Escaped '\'
176 176 '\\\\': '\\',
177 177 # Newline
178 178 r'\n': '\n',
179 179 # Carriage return
180 180 r'\r': '\r',
181 181 # Release version
182 182 r'\v': release.version,
183 183 # Root symbol ($ or #)
184 184 r'\$': ROOT_SYMBOL,
185 185 }
186 186
187 187 # A copy of the prompt_specials dictionary but with all color escapes removed,
188 188 # so we can correctly compute the prompt length for the auto_rewrite method.
189 189 prompt_specials_nocolor = prompt_specials_color.copy()
190 190 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
191 191 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
192 192
193 193 # Add in all the InputTermColors color escapes as valid prompt characters.
194 194 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
195 195 # with a color name which may begin with a letter used by any other of the
196 196 # allowed specials. This of course means that \\C will never be allowed for
197 197 # anything else.
198 198 input_colors = coloransi.InputTermColors
199 199 for _color in dir(input_colors):
200 200 if _color[0] != '_':
201 201 c_name = r'\C_'+_color
202 202 prompt_specials_color[c_name] = getattr(input_colors,_color)
203 203 prompt_specials_nocolor[c_name] = ''
204 204
205 205 # we default to no color for safety. Note that prompt_specials is a global
206 206 # variable used by all prompt objects.
207 207 prompt_specials = prompt_specials_nocolor
208 208
209 209 #-----------------------------------------------------------------------------
210 210 # More utilities
211 211 #-----------------------------------------------------------------------------
212 212
213 213 def str_safe(arg):
214 214 """Convert to a string, without ever raising an exception.
215 215
216 216 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
217 217 error message."""
218 218
219 219 try:
220 220 out = str(arg)
221 221 except UnicodeError:
222 222 try:
223 223 out = arg.encode('utf_8','replace')
224 224 except Exception,msg:
225 225 # let's keep this little duplication here, so that the most common
226 226 # case doesn't suffer from a double try wrapping.
227 227 out = '<ERROR: %s>' % msg
228 228 except Exception,msg:
229 229 out = '<ERROR: %s>' % msg
230 230 #raise # dbg
231 231 return out
232 232
233 233 #-----------------------------------------------------------------------------
234 234 # Prompt classes
235 235 #-----------------------------------------------------------------------------
236 236
237 237 class BasePrompt(object):
238 238 """Interactive prompt similar to Mathematica's."""
239 239
240 240 def _get_p_template(self):
241 241 return self._p_template
242 242
243 243 def _set_p_template(self,val):
244 244 self._p_template = val
245 245 self.set_p_str()
246 246
247 247 p_template = property(_get_p_template,_set_p_template,
248 248 doc='Template for prompt string creation')
249 249
250 250 def __init__(self, cache, sep, prompt, pad_left=False):
251 251
252 252 # Hack: we access information about the primary prompt through the
253 253 # cache argument. We need this, because we want the secondary prompt
254 254 # to be aligned with the primary one. Color table info is also shared
255 255 # by all prompt classes through the cache. Nice OO spaghetti code!
256 256 self.cache = cache
257 257 self.sep = sep
258 258
259 259 # regexp to count the number of spaces at the end of a prompt
260 260 # expression, useful for prompt auto-rewriting
261 261 self.rspace = re.compile(r'(\s*)$')
262 262 # Flag to left-pad prompt strings to match the length of the primary
263 263 # prompt
264 264 self.pad_left = pad_left
265 265
266 266 # Set template to create each actual prompt (where numbers change).
267 267 # Use a property
268 268 self.p_template = prompt
269 269 self.set_p_str()
270 270
271 271 def set_p_str(self):
272 272 """ Set the interpolating prompt strings.
273 273
274 274 This must be called every time the color settings change, because the
275 275 prompt_specials global may have changed."""
276 276
277 277 import os,time # needed in locals for prompt string handling
278 278 loc = locals()
279 279 try:
280 280 self.p_str = ItplNS('%s%s%s' %
281 281 ('${self.sep}${self.col_p}',
282 282 multiple_replace(prompt_specials, self.p_template),
283 283 '${self.col_norm}'),self.cache.shell.user_ns,loc)
284 284
285 285 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
286 286 self.p_template),
287 287 self.cache.shell.user_ns,loc)
288 288 except:
289 289 print "Illegal prompt template (check $ usage!):",self.p_template
290 290 self.p_str = self.p_template
291 291 self.p_str_nocolor = self.p_template
292 292
293 293 def write(self, msg):
294 294 sys.stdout.write(msg)
295 295 return ''
296 296
297 297 def __str__(self):
298 298 """Return a string form of the prompt.
299 299
300 300 This for is useful for continuation and output prompts, since it is
301 301 left-padded to match lengths with the primary one (if the
302 302 self.pad_left attribute is set)."""
303 303
304 304 out_str = str_safe(self.p_str)
305 305 if self.pad_left:
306 306 # We must find the amount of padding required to match lengths,
307 307 # taking the color escapes (which are invisible on-screen) into
308 308 # account.
309 309 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
310 310 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
311 311 return format % out_str
312 312 else:
313 313 return out_str
314 314
315 315 # these path filters are put in as methods so that we can control the
316 316 # namespace where the prompt strings get evaluated
317 317 def cwd_filt(self, depth):
318 318 """Return the last depth elements of the current working directory.
319 319
320 320 $HOME is always replaced with '~'.
321 321 If depth==0, the full path is returned."""
322 322
323 323 cwd = os.getcwd().replace(HOME,"~")
324 324 out = os.sep.join(cwd.split(os.sep)[-depth:])
325 325 if out:
326 326 return out
327 327 else:
328 328 return os.sep
329 329
330 330 def cwd_filt2(self, depth):
331 331 """Return the last depth elements of the current working directory.
332 332
333 333 $HOME is always replaced with '~'.
334 334 If depth==0, the full path is returned."""
335 335
336 336 full_cwd = os.getcwd()
337 337 cwd = full_cwd.replace(HOME,"~").split(os.sep)
338 338 if '~' in cwd and len(cwd) == depth+1:
339 339 depth += 1
340 340 drivepart = ''
341 341 if sys.platform == 'win32' and len(cwd) > depth:
342 342 drivepart = os.path.splitdrive(full_cwd)[0]
343 343 out = drivepart + '/'.join(cwd[-depth:])
344 344
345 345 if out:
346 346 return out
347 347 else:
348 348 return os.sep
349 349
350 350 def __nonzero__(self):
351 351 """Implement boolean behavior.
352 352
353 353 Checks whether the p_str attribute is non-empty"""
354 354
355 355 return bool(self.p_template)
356 356
357 357
358 358 class Prompt1(BasePrompt):
359 359 """Input interactive prompt similar to Mathematica's."""
360 360
361 361 def __init__(self, cache, sep='\n', prompt='In [\\#]: ', pad_left=True):
362 362 BasePrompt.__init__(self, cache, sep, prompt, pad_left)
363 363
364 364 def set_colors(self):
365 365 self.set_p_str()
366 366 Colors = self.cache.color_table.active_colors # shorthand
367 367 self.col_p = Colors.in_prompt
368 368 self.col_num = Colors.in_number
369 369 self.col_norm = Colors.in_normal
370 370 # We need a non-input version of these escapes for the '--->'
371 371 # auto-call prompts used in the auto_rewrite() method.
372 372 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
373 373 self.col_norm_ni = Colors.normal
374 374
375 375 def __str__(self):
376 376 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
377 377 return str_safe(self.p_str)
378 378
379 379 def auto_rewrite(self):
380 380 """Return a string of the form '--->' which lines up with the previous
381 381 input string. Useful for systems which re-write the user input when
382 382 handling automatically special syntaxes."""
383 383
384 384 curr = str(self.cache.last_prompt)
385 385 nrspaces = len(self.rspace.search(curr).group())
386 386 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
387 387 ' '*nrspaces,self.col_norm_ni)
388 388
389 389
390 390 class PromptOut(BasePrompt):
391 391 """Output interactive prompt similar to Mathematica's."""
392 392
393 393 def __init__(self, cache, sep='', prompt='Out[\\#]: ', pad_left=True):
394 394 BasePrompt.__init__(self, cache, sep, prompt, pad_left)
395 395 if not self.p_template:
396 396 self.__str__ = lambda: ''
397 397
398 398 def set_colors(self):
399 399 self.set_p_str()
400 400 Colors = self.cache.color_table.active_colors # shorthand
401 401 self.col_p = Colors.out_prompt
402 402 self.col_num = Colors.out_number
403 403 self.col_norm = Colors.normal
404 404
405 405
406 406 class Prompt2(BasePrompt):
407 407 """Interactive continuation prompt."""
408 408
409 409 def __init__(self, cache, prompt=' .\\D.: ', pad_left=True):
410 410 self.cache = cache
411 411 self.p_template = prompt
412 412 self.pad_left = pad_left
413 413 self.set_p_str()
414 414
415 415 def set_p_str(self):
416 416 import os,time # needed in locals for prompt string handling
417 417 loc = locals()
418 418 self.p_str = ItplNS('%s%s%s' %
419 419 ('${self.col_p2}',
420 420 multiple_replace(prompt_specials, self.p_template),
421 421 '$self.col_norm'),
422 422 self.cache.shell.user_ns,loc)
423 423 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
424 424 self.p_template),
425 425 self.cache.shell.user_ns,loc)
426 426
427 427 def set_colors(self):
428 428 self.set_p_str()
429 429 Colors = self.cache.color_table.active_colors
430 430 self.col_p2 = Colors.in_prompt2
431 431 self.col_norm = Colors.in_normal
432 432 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
433 433 # updated their prompt_in2 definitions. Remove eventually.
434 434 self.col_p = Colors.out_prompt
435 435 self.col_num = Colors.out_number
436 436
@@ -1,138 +1,138 b''
1 1 # encoding: utf-8
2 2 """
3 3 Simple utility for splitting user input. This is used by both inputsplitter and
4 4 prefilter.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2011 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 import re
24 24 import sys
25 25
26 26 from IPython.utils import py3compat
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Main function
30 30 #-----------------------------------------------------------------------------
31 31
32 32 # RegExp for splitting line contents into pre-char//first word-method//rest.
33 33 # For clarity, each group in on one line.
34 34
35 35 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
36 36 # they are hardwired in.
37 37
38 38 # Although it's not solely driven by the regex, note that:
39 39 # ,;/% only trigger if they are the first character on the line
40 40 # ! and !! trigger if they are first char(s) *or* follow an indent
41 41 # ? triggers as first or last char.
42 42
43 43 line_split = re.compile("""
44 44 ^(\s*) # any leading space
45 45 ([,;/%]|!!?|\?\??)? # escape character or characters
46 46 \s*(%?[\w\.\*]*) # function/method, possibly with leading %
47 47 # to correctly treat things like '?%magic'
48 48 (.*?$|$) # rest of line
49 49 """, re.VERBOSE)
50 50
51 51 def split_user_input(line, pattern=None):
52 52 """Split user input into initial whitespace, escape character, function part
53 53 and the rest.
54 54 """
55 55 # We need to ensure that the rest of this routine deals only with unicode
56 56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
57 57
58 58 if pattern is None:
59 59 pattern = line_split
60 60 match = pattern.match(line)
61 61 if not match:
62 62 # print "match failed for line '%s'" % line
63 63 try:
64 64 ifun, the_rest = line.split(None,1)
65 65 except ValueError:
66 66 # print "split failed for line '%s'" % line
67 67 ifun, the_rest = line, u''
68 68 pre = re.match('^(\s*)(.*)',line).groups()[0]
69 69 esc = ""
70 70 else:
71 71 pre, esc, ifun, the_rest = match.groups()
72 72
73 73 #print 'line:<%s>' % line # dbg
74 74 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
75 75 return pre, esc or '', ifun.strip(), the_rest.lstrip()
76 76
77 77 class LineInfo(object):
78 78 """A single line of input and associated info.
79 79
80 80 Includes the following as properties:
81 81
82 82 line
83 83 The original, raw line
84 84
85 85 continue_prompt
86 86 Is this line a continuation in a sequence of multiline input?
87 87
88 88 pre
89 89 Any leading whitespace.
90 90
91 91 esc
92 92 The escape character(s) in pre or the empty string if there isn't one.
93 93 Note that '!!' and '??' are possible values for esc. Otherwise it will
94 94 always be a single character.
95 95
96 96 ifun
97 97 The 'function part', which is basically the maximal initial sequence
98 98 of valid python identifiers and the '.' character. This is what is
99 99 checked for alias and magic transformations, used for auto-calling,
100 100 etc. In contrast to Python identifiers, it may start with "%" and contain
101 101 "*".
102 102
103 103 the_rest
104 104 Everything else on the line.
105 105 """
106 106 def __init__(self, line, continue_prompt=False):
107 107 self.line = line
108 108 self.continue_prompt = continue_prompt
109 109 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
110 110
111 111 self.pre_char = self.pre.strip()
112 112 if self.pre_char:
113 113 self.pre_whitespace = '' # No whitespace allowd before esc chars
114 114 else:
115 115 self.pre_whitespace = self.pre
116 116
117 117 self._oinfo = None
118 118
119 119 def ofind(self, ip):
120 120 """Do a full, attribute-walking lookup of the ifun in the various
121 121 namespaces for the given IPython InteractiveShell instance.
122 122
123 123 Return a dict with keys: found,obj,ospace,ismagic
124 124
125 125 Note: can cause state changes because of calling getattr, but should
126 126 only be run if autocall is on and if the line hasn't matched any
127 127 other, less dangerous handlers.
128 128
129 129 Does cache the results of the call, so can be called multiple times
130 130 without worrying about *further* damaging state.
131 131 """
132 132 if not self._oinfo:
133 133 # ip.shell._ofind is actually on the Magic class!
134 134 self._oinfo = ip.shell._ofind(self.ifun)
135 135 return self._oinfo
136 136
137 137 def __str__(self):
138 138 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -1,75 +1,75 b''
1 1 # coding: utf-8
2 2 """Tests for the compilerop module.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2010 The IPython Development Team.
5 # Copyright (C) 2010-2011 The IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15 from __future__ import print_function
16 16
17 17 # Stdlib imports
18 18 import linecache
19 19 import sys
20 20
21 21 # Third-party imports
22 22 import nose.tools as nt
23 23
24 24 # Our own imports
25 25 from IPython.core import compilerop
26 26 from IPython.utils import py3compat
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Test functions
30 30 #-----------------------------------------------------------------------------
31 31
32 32 def test_code_name():
33 33 code = 'x=1'
34 34 name = compilerop.code_name(code)
35 35 nt.assert_true(name.startswith('<ipython-input-0'))
36 36
37 37
38 38 def test_code_name2():
39 39 code = 'x=1'
40 40 name = compilerop.code_name(code, 9)
41 41 nt.assert_true(name.startswith('<ipython-input-9'))
42 42
43 43
44 44 def test_cache():
45 45 """Test the compiler correctly compiles and caches inputs
46 46 """
47 47 cp = compilerop.CachingCompiler()
48 48 ncache = len(linecache.cache)
49 49 cp.cache('x=1')
50 50 nt.assert_true(len(linecache.cache) > ncache)
51 51
52 52 def setUp():
53 53 # Check we're in a proper Python 2 environment (some imports, such
54 54 # as GTK, can change the default encoding, which can hide bugs.)
55 55 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
56 56
57 57 def test_cache_unicode():
58 58 cp = compilerop.CachingCompiler()
59 59 ncache = len(linecache.cache)
60 60 cp.cache(u"t = 'žćčšđ'")
61 61 nt.assert_true(len(linecache.cache) > ncache)
62 62
63 63 def test_compiler_check_cache():
64 64 """Test the compiler properly manages the cache.
65 65 """
66 66 # Rather simple-minded tests that just exercise the API
67 67 cp = compilerop.CachingCompiler()
68 68 cp.cache('x=1', 99)
69 69 # Ensure now that after clearing the cache, our entries survive
70 70 cp.check_cache()
71 71 for k in linecache.cache:
72 72 if k.startswith('<ipython-input-99'):
73 73 break
74 74 else:
75 75 raise AssertionError('Entry for input-99 missing from linecache')
@@ -1,706 +1,706 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module.
3 3
4 4 Authors
5 5 -------
6 6 * Fernando Perez
7 7 * Robert Kern
8 8 """
9 9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19 # stdlib
20 20 import unittest
21 21 import sys
22 22
23 23 # Third party
24 24 import nose.tools as nt
25 25
26 26 # Our own
27 27 from IPython.core import inputsplitter as isp
28 28 from IPython.testing import tools as tt
29 29 from IPython.utils import py3compat
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Semi-complete examples (also used as tests)
33 33 #-----------------------------------------------------------------------------
34 34
35 35 # Note: at the bottom, there's a slightly more complete version of this that
36 36 # can be useful during development of code here.
37 37
38 38 def mini_interactive_loop(input_func):
39 39 """Minimal example of the logic of an interactive interpreter loop.
40 40
41 41 This serves as an example, and it is used by the test system with a fake
42 42 raw_input that simulates interactive input."""
43 43
44 44 from IPython.core.inputsplitter import InputSplitter
45 45
46 46 isp = InputSplitter()
47 47 # In practice, this input loop would be wrapped in an outside loop to read
48 48 # input indefinitely, until some exit/quit command was issued. Here we
49 49 # only illustrate the basic inner loop.
50 50 while isp.push_accepts_more():
51 51 indent = ' '*isp.indent_spaces
52 52 prompt = '>>> ' + indent
53 53 line = indent + input_func(prompt)
54 54 isp.push(line)
55 55
56 56 # Here we just return input so we can use it in a test suite, but a real
57 57 # interpreter would instead send it for execution somewhere.
58 58 src = isp.source_reset()
59 59 #print 'Input source was:\n', src # dbg
60 60 return src
61 61
62 62 #-----------------------------------------------------------------------------
63 63 # Test utilities, just for local use
64 64 #-----------------------------------------------------------------------------
65 65
66 66 def assemble(block):
67 67 """Assemble a block into multi-line sub-blocks."""
68 68 return ['\n'.join(sub_block)+'\n' for sub_block in block]
69 69
70 70
71 71 def pseudo_input(lines):
72 72 """Return a function that acts like raw_input but feeds the input list."""
73 73 ilines = iter(lines)
74 74 def raw_in(prompt):
75 75 try:
76 76 return next(ilines)
77 77 except StopIteration:
78 78 return ''
79 79 return raw_in
80 80
81 81 #-----------------------------------------------------------------------------
82 82 # Tests
83 83 #-----------------------------------------------------------------------------
84 84 def test_spaces():
85 85 tests = [('', 0),
86 86 (' ', 1),
87 87 ('\n', 0),
88 88 (' \n', 1),
89 89 ('x', 0),
90 90 (' x', 1),
91 91 (' x',2),
92 92 (' x',4),
93 93 # Note: tabs are counted as a single whitespace!
94 94 ('\tx', 1),
95 95 ('\t x', 2),
96 96 ]
97 97 tt.check_pairs(isp.num_ini_spaces, tests)
98 98
99 99
100 100 def test_remove_comments():
101 101 tests = [('text', 'text'),
102 102 ('text # comment', 'text '),
103 103 ('text # comment\n', 'text \n'),
104 104 ('text # comment \n', 'text \n'),
105 105 ('line # c \nline\n','line \nline\n'),
106 106 ('line # c \nline#c2 \nline\nline #c\n\n',
107 107 'line \nline\nline\nline \n\n'),
108 108 ]
109 109 tt.check_pairs(isp.remove_comments, tests)
110 110
111 111 def test_has_comment():
112 112 tests = [('text', False),
113 113 ('text #comment', True),
114 114 ('text #comment\n', True),
115 115 ('#comment', True),
116 116 ('#comment\n', True),
117 117 ('a = "#string"', False),
118 118 ('a = "#string" # comment', True),
119 119 ('a #comment not "string"', True),
120 120 ]
121 121 tt.check_pairs(isp.has_comment, tests)
122 122
123 123
124 124 def test_get_input_encoding():
125 125 encoding = isp.get_input_encoding()
126 126 nt.assert_true(isinstance(encoding, basestring))
127 127 # simple-minded check that at least encoding a simple string works with the
128 128 # encoding we got.
129 129 nt.assert_equal(u'test'.encode(encoding), b'test')
130 130
131 131
132 132 class NoInputEncodingTestCase(unittest.TestCase):
133 133 def setUp(self):
134 134 self.old_stdin = sys.stdin
135 135 class X: pass
136 136 fake_stdin = X()
137 137 sys.stdin = fake_stdin
138 138
139 139 def test(self):
140 140 # Verify that if sys.stdin has no 'encoding' attribute we do the right
141 141 # thing
142 142 enc = isp.get_input_encoding()
143 143 self.assertEqual(enc, 'ascii')
144 144
145 145 def tearDown(self):
146 146 sys.stdin = self.old_stdin
147 147
148 148
149 149 class InputSplitterTestCase(unittest.TestCase):
150 150 def setUp(self):
151 151 self.isp = isp.InputSplitter()
152 152
153 153 def test_reset(self):
154 154 isp = self.isp
155 155 isp.push('x=1')
156 156 isp.reset()
157 157 self.assertEqual(isp._buffer, [])
158 158 self.assertEqual(isp.indent_spaces, 0)
159 159 self.assertEqual(isp.source, '')
160 160 self.assertEqual(isp.code, None)
161 161 self.assertEqual(isp._is_complete, False)
162 162
163 163 def test_source(self):
164 164 self.isp._store('1')
165 165 self.isp._store('2')
166 166 self.assertEqual(self.isp.source, '1\n2\n')
167 167 self.assertTrue(len(self.isp._buffer)>0)
168 168 self.assertEqual(self.isp.source_reset(), '1\n2\n')
169 169 self.assertEqual(self.isp._buffer, [])
170 170 self.assertEqual(self.isp.source, '')
171 171
172 172 def test_indent(self):
173 173 isp = self.isp # shorthand
174 174 isp.push('x=1')
175 175 self.assertEqual(isp.indent_spaces, 0)
176 176 isp.push('if 1:\n x=1')
177 177 self.assertEqual(isp.indent_spaces, 4)
178 178 isp.push('y=2\n')
179 179 self.assertEqual(isp.indent_spaces, 0)
180 180
181 181 def test_indent2(self):
182 182 # In cell mode, inputs must be fed in whole blocks, so skip this test
183 183 if self.isp.input_mode == 'cell': return
184 184
185 185 isp = self.isp
186 186 isp.push('if 1:')
187 187 self.assertEqual(isp.indent_spaces, 4)
188 188 isp.push(' x=1')
189 189 self.assertEqual(isp.indent_spaces, 4)
190 190 # Blank lines shouldn't change the indent level
191 191 isp.push(' '*2)
192 192 self.assertEqual(isp.indent_spaces, 4)
193 193
194 194 def test_indent3(self):
195 195 # In cell mode, inputs must be fed in whole blocks, so skip this test
196 196 if self.isp.input_mode == 'cell': return
197 197
198 198 isp = self.isp
199 199 # When a multiline statement contains parens or multiline strings, we
200 200 # shouldn't get confused.
201 201 isp.push("if 1:")
202 202 isp.push(" x = (1+\n 2)")
203 203 self.assertEqual(isp.indent_spaces, 4)
204 204
205 205 def test_indent4(self):
206 206 # In cell mode, inputs must be fed in whole blocks, so skip this test
207 207 if self.isp.input_mode == 'cell': return
208 208
209 209 isp = self.isp
210 210 # whitespace after ':' should not screw up indent level
211 211 isp.push('if 1: \n x=1')
212 212 self.assertEqual(isp.indent_spaces, 4)
213 213 isp.push('y=2\n')
214 214 self.assertEqual(isp.indent_spaces, 0)
215 215 isp.push('if 1:\t\n x=1')
216 216 self.assertEqual(isp.indent_spaces, 4)
217 217 isp.push('y=2\n')
218 218 self.assertEqual(isp.indent_spaces, 0)
219 219
220 220 def test_dedent_pass(self):
221 221 isp = self.isp # shorthand
222 222 # should NOT cause dedent
223 223 isp.push('if 1:\n passes = 5')
224 224 self.assertEqual(isp.indent_spaces, 4)
225 225 isp.push('if 1:\n pass')
226 226 self.assertEqual(isp.indent_spaces, 0)
227 227 isp.push('if 1:\n pass ')
228 228 self.assertEqual(isp.indent_spaces, 0)
229 229
230 230 def test_dedent_raise(self):
231 231 isp = self.isp # shorthand
232 232 # should NOT cause dedent
233 233 isp.push('if 1:\n raised = 4')
234 234 self.assertEqual(isp.indent_spaces, 4)
235 235 isp.push('if 1:\n raise TypeError()')
236 236 self.assertEqual(isp.indent_spaces, 0)
237 237 isp.push('if 1:\n raise')
238 238 self.assertEqual(isp.indent_spaces, 0)
239 239 isp.push('if 1:\n raise ')
240 240 self.assertEqual(isp.indent_spaces, 0)
241 241
242 242 def test_dedent_return(self):
243 243 isp = self.isp # shorthand
244 244 # should NOT cause dedent
245 245 isp.push('if 1:\n returning = 4')
246 246 self.assertEqual(isp.indent_spaces, 4)
247 247 isp.push('if 1:\n return 5 + 493')
248 248 self.assertEqual(isp.indent_spaces, 0)
249 249 isp.push('if 1:\n return')
250 250 self.assertEqual(isp.indent_spaces, 0)
251 251 isp.push('if 1:\n return ')
252 252 self.assertEqual(isp.indent_spaces, 0)
253 253 isp.push('if 1:\n return(0)')
254 254 self.assertEqual(isp.indent_spaces, 0)
255 255
256 256 def test_push(self):
257 257 isp = self.isp
258 258 self.assertTrue(isp.push('x=1'))
259 259
260 260 def test_push2(self):
261 261 isp = self.isp
262 262 self.assertFalse(isp.push('if 1:'))
263 263 for line in [' x=1', '# a comment', ' y=2']:
264 264 self.assertTrue(isp.push(line))
265 265
266 266 def test_push3(self):
267 267 isp = self.isp
268 268 isp.push('if True:')
269 269 isp.push(' a = 1')
270 270 self.assertFalse(isp.push('b = [1,'))
271 271
272 272 def test_replace_mode(self):
273 273 isp = self.isp
274 274 isp.input_mode = 'cell'
275 275 isp.push('x=1')
276 276 self.assertEqual(isp.source, 'x=1\n')
277 277 isp.push('x=2')
278 278 self.assertEqual(isp.source, 'x=2\n')
279 279
280 280 def test_push_accepts_more(self):
281 281 isp = self.isp
282 282 isp.push('x=1')
283 283 self.assertFalse(isp.push_accepts_more())
284 284
285 285 def test_push_accepts_more2(self):
286 286 # In cell mode, inputs must be fed in whole blocks, so skip this test
287 287 if self.isp.input_mode == 'cell': return
288 288
289 289 isp = self.isp
290 290 isp.push('if 1:')
291 291 self.assertTrue(isp.push_accepts_more())
292 292 isp.push(' x=1')
293 293 self.assertTrue(isp.push_accepts_more())
294 294 isp.push('')
295 295 self.assertFalse(isp.push_accepts_more())
296 296
297 297 def test_push_accepts_more3(self):
298 298 isp = self.isp
299 299 isp.push("x = (2+\n3)")
300 300 self.assertFalse(isp.push_accepts_more())
301 301
302 302 def test_push_accepts_more4(self):
303 303 # In cell mode, inputs must be fed in whole blocks, so skip this test
304 304 if self.isp.input_mode == 'cell': return
305 305
306 306 isp = self.isp
307 307 # When a multiline statement contains parens or multiline strings, we
308 308 # shouldn't get confused.
309 309 # FIXME: we should be able to better handle de-dents in statements like
310 310 # multiline strings and multiline expressions (continued with \ or
311 311 # parens). Right now we aren't handling the indentation tracking quite
312 312 # correctly with this, though in practice it may not be too much of a
313 313 # problem. We'll need to see.
314 314 isp.push("if 1:")
315 315 isp.push(" x = (2+")
316 316 isp.push(" 3)")
317 317 self.assertTrue(isp.push_accepts_more())
318 318 isp.push(" y = 3")
319 319 self.assertTrue(isp.push_accepts_more())
320 320 isp.push('')
321 321 self.assertFalse(isp.push_accepts_more())
322 322
323 323 def test_push_accepts_more5(self):
324 324 # In cell mode, inputs must be fed in whole blocks, so skip this test
325 325 if self.isp.input_mode == 'cell': return
326 326
327 327 isp = self.isp
328 328 isp.push('try:')
329 329 isp.push(' a = 5')
330 330 isp.push('except:')
331 331 isp.push(' raise')
332 332 self.assertTrue(isp.push_accepts_more())
333 333
334 334 def test_continuation(self):
335 335 isp = self.isp
336 336 isp.push("import os, \\")
337 337 self.assertTrue(isp.push_accepts_more())
338 338 isp.push("sys")
339 339 self.assertFalse(isp.push_accepts_more())
340 340
341 341 def test_syntax_error(self):
342 342 isp = self.isp
343 343 # Syntax errors immediately produce a 'ready' block, so the invalid
344 344 # Python can be sent to the kernel for evaluation with possible ipython
345 345 # special-syntax conversion.
346 346 isp.push('run foo')
347 347 self.assertFalse(isp.push_accepts_more())
348 348
349 349 def test_unicode(self):
350 350 self.isp.push(u"Pérez")
351 351 self.isp.push(u'\xc3\xa9')
352 352 self.isp.push(u"u'\xc3\xa9'")
353 353
354 354 class InteractiveLoopTestCase(unittest.TestCase):
355 355 """Tests for an interactive loop like a python shell.
356 356 """
357 357 def check_ns(self, lines, ns):
358 358 """Validate that the given input lines produce the resulting namespace.
359 359
360 360 Note: the input lines are given exactly as they would be typed in an
361 361 auto-indenting environment, as mini_interactive_loop above already does
362 362 auto-indenting and prepends spaces to the input.
363 363 """
364 364 src = mini_interactive_loop(pseudo_input(lines))
365 365 test_ns = {}
366 366 exec src in test_ns
367 367 # We can't check that the provided ns is identical to the test_ns,
368 368 # because Python fills test_ns with extra keys (copyright, etc). But
369 369 # we can check that the given dict is *contained* in test_ns
370 370 for k,v in ns.iteritems():
371 371 self.assertEqual(test_ns[k], v)
372 372
373 373 def test_simple(self):
374 374 self.check_ns(['x=1'], dict(x=1))
375 375
376 376 def test_simple2(self):
377 377 self.check_ns(['if 1:', 'x=2'], dict(x=2))
378 378
379 379 def test_xy(self):
380 380 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
381 381
382 382 def test_abc(self):
383 383 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
384 384
385 385 def test_multi(self):
386 386 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
387 387
388 388
389 389 def test_LineInfo():
390 390 """Simple test for LineInfo construction and str()"""
391 391 linfo = isp.LineInfo(' %cd /home')
392 392 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
393 393
394 394 # Transformer tests
395 395 def transform_checker(tests, func):
396 396 """Utility to loop over test inputs"""
397 397 for inp, tr in tests:
398 398 nt.assert_equals(func(inp), tr)
399 399
400 400 # Data for all the syntax tests in the form of lists of pairs of
401 401 # raw/transformed input. We store it here as a global dict so that we can use
402 402 # it both within single-function tests and also to validate the behavior of the
403 403 # larger objects
404 404
405 405 syntax = \
406 406 dict(assign_system =
407 407 [(i,py3compat.u_format(o)) for i,o in \
408 408 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
409 409 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
410 410 ('x=1', 'x=1'), # normal input is unmodified
411 411 (' ',' '), # blank lines are kept intact
412 412 ]],
413 413
414 414 assign_magic =
415 415 [(i,py3compat.u_format(o)) for i,o in \
416 416 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
417 417 (u'b = %who', "b = get_ipython().magic({u}'who')"),
418 418 ('x=1', 'x=1'), # normal input is unmodified
419 419 (' ',' '), # blank lines are kept intact
420 420 ]],
421 421
422 422 classic_prompt =
423 423 [('>>> x=1', 'x=1'),
424 424 ('x=1', 'x=1'), # normal input is unmodified
425 425 (' ', ' '), # blank lines are kept intact
426 426 ('... ', ''), # continuation prompts
427 427 ],
428 428
429 429 ipy_prompt =
430 430 [('In [1]: x=1', 'x=1'),
431 431 ('x=1', 'x=1'), # normal input is unmodified
432 432 (' ',' '), # blank lines are kept intact
433 433 (' ....: ', ''), # continuation prompts
434 434 ],
435 435
436 436 # Tests for the escape transformer to leave normal code alone
437 437 escaped_noesc =
438 438 [ (' ', ' '),
439 439 ('x=1', 'x=1'),
440 440 ],
441 441
442 442 # System calls
443 443 escaped_shell =
444 444 [(i,py3compat.u_format(o)) for i,o in \
445 445 [ (u'!ls', "get_ipython().system({u}'ls')"),
446 446 # Double-escape shell, this means to capture the output of the
447 447 # subprocess and return it
448 448 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
449 449 ]],
450 450
451 451 # Help/object info
452 452 escaped_help =
453 453 [(i,py3compat.u_format(o)) for i,o in \
454 454 [ (u'?', 'get_ipython().show_usage()'),
455 455 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
456 456 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
457 457 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
458 458 (u'?%hist', "get_ipython().magic({u}'pinfo %hist')"),
459 459 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
460 460 ]],
461 461
462 462 end_help =
463 463 [(i,py3compat.u_format(o)) for i,o in \
464 464 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
465 465 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
466 466 (u'%hist?', "get_ipython().magic({u}'pinfo %hist')"),
467 467 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
468 468 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
469 469 (u'a = abc?', "get_ipython().magic({u}'pinfo abc', next_input={u}'a = abc')"),
470 470 (u'a = abc.qe??', "get_ipython().magic({u}'pinfo2 abc.qe', next_input={u}'a = abc.qe')"),
471 471 (u'a = *.items?', "get_ipython().magic({u}'psearch *.items', next_input={u}'a = *.items')"),
472 472 (u'plot(a?', "get_ipython().magic({u}'pinfo a', next_input={u}'plot(a')"),
473 473 (u'a*2 #comment?', 'a*2 #comment?'),
474 474 ]],
475 475
476 476 # Explicit magic calls
477 477 escaped_magic =
478 478 [(i,py3compat.u_format(o)) for i,o in \
479 479 [ (u'%cd', "get_ipython().magic({u}'cd')"),
480 480 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
481 481 # Backslashes need to be escaped.
482 482 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
483 483 (u' %magic', " get_ipython().magic({u}'magic')"),
484 484 ]],
485 485
486 486 # Quoting with separate arguments
487 487 escaped_quote =
488 488 [ (',f', 'f("")'),
489 489 (',f x', 'f("x")'),
490 490 (' ,f y', ' f("y")'),
491 491 (',f a b', 'f("a", "b")'),
492 492 ],
493 493
494 494 # Quoting with single argument
495 495 escaped_quote2 =
496 496 [ (';f', 'f("")'),
497 497 (';f x', 'f("x")'),
498 498 (' ;f y', ' f("y")'),
499 499 (';f a b', 'f("a b")'),
500 500 ],
501 501
502 502 # Simply apply parens
503 503 escaped_paren =
504 504 [ ('/f', 'f()'),
505 505 ('/f x', 'f(x)'),
506 506 (' /f y', ' f(y)'),
507 507 ('/f a b', 'f(a, b)'),
508 508 ],
509 509
510 510 # Check that we transform prompts before other transforms
511 511 mixed =
512 512 [(i,py3compat.u_format(o)) for i,o in \
513 513 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
514 514 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
515 515 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
516 516 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
517 517 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
518 518 ]],
519 519 )
520 520
521 521 # multiline syntax examples. Each of these should be a list of lists, with
522 522 # each entry itself having pairs of raw/transformed input. The union (with
523 523 # '\n'.join() of the transformed inputs is what the splitter should produce
524 524 # when fed the raw lines one at a time via push.
525 525 syntax_ml = \
526 526 dict(classic_prompt =
527 527 [ [('>>> for i in range(10):','for i in range(10):'),
528 528 ('... print i',' print i'),
529 529 ('... ', ''),
530 530 ],
531 531 ],
532 532
533 533 ipy_prompt =
534 534 [ [('In [24]: for i in range(10):','for i in range(10):'),
535 535 (' ....: print i',' print i'),
536 536 (' ....: ', ''),
537 537 ],
538 538 ],
539 539
540 540 multiline_datastructure =
541 541 [ [('>>> a = [1,','a = [1,'),
542 542 ('... 2]','2]'),
543 543 ],
544 544 ],
545 545 )
546 546
547 547
548 548 def test_assign_system():
549 549 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
550 550
551 551
552 552 def test_assign_magic():
553 553 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
554 554
555 555
556 556 def test_classic_prompt():
557 557 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
558 558 for example in syntax_ml['classic_prompt']:
559 559 transform_checker(example, isp.transform_classic_prompt)
560 560
561 561
562 562 def test_ipy_prompt():
563 563 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
564 564 for example in syntax_ml['ipy_prompt']:
565 565 transform_checker(example, isp.transform_ipy_prompt)
566 566
567 567 def test_end_help():
568 568 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
569 569
570 570 def test_escaped_noesc():
571 571 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
572 572
573 573
574 574 def test_escaped_shell():
575 575 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
576 576
577 577
578 578 def test_escaped_help():
579 579 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
580 580
581 581
582 582 def test_escaped_magic():
583 583 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
584 584
585 585
586 586 def test_escaped_quote():
587 587 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
588 588
589 589
590 590 def test_escaped_quote2():
591 591 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
592 592
593 593
594 594 def test_escaped_paren():
595 595 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
596 596
597 597
598 598 class IPythonInputTestCase(InputSplitterTestCase):
599 599 """By just creating a new class whose .isp is a different instance, we
600 600 re-run the same test battery on the new input splitter.
601 601
602 602 In addition, this runs the tests over the syntax and syntax_ml dicts that
603 603 were tested by individual functions, as part of the OO interface.
604 604
605 605 It also makes some checks on the raw buffer storage.
606 606 """
607 607
608 608 def setUp(self):
609 609 self.isp = isp.IPythonInputSplitter(input_mode='line')
610 610
611 611 def test_syntax(self):
612 612 """Call all single-line syntax tests from the main object"""
613 613 isp = self.isp
614 614 for example in syntax.itervalues():
615 615 for raw, out_t in example:
616 616 if raw.startswith(' '):
617 617 continue
618 618
619 619 isp.push(raw)
620 620 out, out_raw = isp.source_raw_reset()
621 621 self.assertEqual(out.rstrip(), out_t,
622 622 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
623 623 self.assertEqual(out_raw.rstrip(), raw.rstrip())
624 624
625 625 def test_syntax_multiline(self):
626 626 isp = self.isp
627 627 for example in syntax_ml.itervalues():
628 628 out_t_parts = []
629 629 raw_parts = []
630 630 for line_pairs in example:
631 631 for lraw, out_t_part in line_pairs:
632 632 isp.push(lraw)
633 633 out_t_parts.append(out_t_part)
634 634 raw_parts.append(lraw)
635 635
636 636 out, out_raw = isp.source_raw_reset()
637 637 out_t = '\n'.join(out_t_parts).rstrip()
638 638 raw = '\n'.join(raw_parts).rstrip()
639 639 self.assertEqual(out.rstrip(), out_t)
640 640 self.assertEqual(out_raw.rstrip(), raw)
641 641
642 642
643 643 class BlockIPythonInputTestCase(IPythonInputTestCase):
644 644
645 645 # Deactivate tests that don't make sense for the block mode
646 646 test_push3 = test_split = lambda s: None
647 647
648 648 def setUp(self):
649 649 self.isp = isp.IPythonInputSplitter(input_mode='cell')
650 650
651 651 def test_syntax_multiline(self):
652 652 isp = self.isp
653 653 for example in syntax_ml.itervalues():
654 654 raw_parts = []
655 655 out_t_parts = []
656 656 for line_pairs in example:
657 657 for raw, out_t_part in line_pairs:
658 658 raw_parts.append(raw)
659 659 out_t_parts.append(out_t_part)
660 660
661 661 raw = '\n'.join(raw_parts)
662 662 out_t = '\n'.join(out_t_parts)
663 663
664 664 isp.push(raw)
665 665 out, out_raw = isp.source_raw_reset()
666 666 # Match ignoring trailing whitespace
667 667 self.assertEqual(out.rstrip(), out_t.rstrip())
668 668 self.assertEqual(out_raw.rstrip(), raw.rstrip())
669 669
670 670
671 671 #-----------------------------------------------------------------------------
672 672 # Main - use as a script, mostly for developer experiments
673 673 #-----------------------------------------------------------------------------
674 674
675 675 if __name__ == '__main__':
676 676 # A simple demo for interactive experimentation. This code will not get
677 677 # picked up by any test suite.
678 678 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
679 679
680 680 # configure here the syntax to use, prompt and whether to autoindent
681 681 #isp, start_prompt = InputSplitter(), '>>> '
682 682 isp, start_prompt = IPythonInputSplitter(), 'In> '
683 683
684 684 autoindent = True
685 685 #autoindent = False
686 686
687 687 try:
688 688 while True:
689 689 prompt = start_prompt
690 690 while isp.push_accepts_more():
691 691 indent = ' '*isp.indent_spaces
692 692 if autoindent:
693 693 line = indent + raw_input(prompt+indent)
694 694 else:
695 695 line = raw_input(prompt)
696 696 isp.push(line)
697 697 prompt = '... '
698 698
699 699 # Here we just return input so we can use it in a test suite, but a
700 700 # real interpreter would instead send it for execution somewhere.
701 701 #src = isp.source; raise EOFError # dbg
702 702 src, raw = isp.source_raw_reset()
703 703 print 'Input source was:\n', src
704 704 print 'Raw source was:\n', raw
705 705 except EOFError:
706 706 print 'Bye'
@@ -1,121 +1,121 b''
1 1 #-----------------------------------------------------------------------------
2 # Copyright (c) 2010, IPython Development Team.
2 # Copyright (C) 2010-2011, IPython Development Team.
3 3 #
4 4 # Distributed under the terms of the Modified BSD License.
5 5 #
6 6 # The full license is in the file COPYING.txt, distributed with this software.
7 7 #-----------------------------------------------------------------------------
8 8
9 9 from nose.tools import assert_equal, assert_true
10 10
11 11 from IPython.external import argparse
12 12 from IPython.core.magic_arguments import (argument, argument_group, kwds,
13 13 magic_arguments, parse_argstring, real_name)
14 14 from IPython.testing.decorators import parametric
15 15
16 16
17 17 @magic_arguments()
18 18 @argument('-f', '--foo', help="an argument")
19 19 def magic_foo1(self, args):
20 20 """ A docstring.
21 21 """
22 22 return parse_argstring(magic_foo1, args)
23 23
24 24
25 25 @magic_arguments()
26 26 def magic_foo2(self, args):
27 27 """ A docstring.
28 28 """
29 29 return parse_argstring(magic_foo2, args)
30 30
31 31
32 32 @magic_arguments()
33 33 @argument('-f', '--foo', help="an argument")
34 34 @argument_group('Group')
35 35 @argument('-b', '--bar', help="a grouped argument")
36 36 @argument_group('Second Group')
37 37 @argument('-z', '--baz', help="another grouped argument")
38 38 def magic_foo3(self, args):
39 39 """ A docstring.
40 40 """
41 41 return parse_argstring(magic_foo3, args)
42 42
43 43
44 44 @magic_arguments()
45 45 @kwds(argument_default=argparse.SUPPRESS)
46 46 @argument('-f', '--foo', help="an argument")
47 47 def magic_foo4(self, args):
48 48 """ A docstring.
49 49 """
50 50 return parse_argstring(magic_foo4, args)
51 51
52 52
53 53 @magic_arguments('frobnicate')
54 54 @argument('-f', '--foo', help="an argument")
55 55 def magic_foo5(self, args):
56 56 """ A docstring.
57 57 """
58 58 return parse_argstring(magic_foo5, args)
59 59
60 60
61 61 @magic_arguments()
62 62 @argument('-f', '--foo', help="an argument")
63 63 def magic_magic_foo(self, args):
64 64 """ A docstring.
65 65 """
66 66 return parse_argstring(magic_magic_foo, args)
67 67
68 68
69 69 @magic_arguments()
70 70 @argument('-f', '--foo', help="an argument")
71 71 def foo(self, args):
72 72 """ A docstring.
73 73 """
74 74 return parse_argstring(foo, args)
75 75
76 76
77 77 @parametric
78 78 def test_magic_arguments():
79 79 # Ideally, these would be doctests, but I could not get it to work.
80 80 yield assert_equal(magic_foo1.__doc__, '%foo1 [-f FOO]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
81 81 yield assert_equal(getattr(magic_foo1, 'argcmd_name', None), None)
82 82 yield assert_equal(real_name(magic_foo1), 'foo1')
83 83 yield assert_equal(magic_foo1(None, ''), argparse.Namespace(foo=None))
84 84 yield assert_true(hasattr(magic_foo1, 'has_arguments'))
85 85
86 86 yield assert_equal(magic_foo2.__doc__, '%foo2\n\nA docstring.\n')
87 87 yield assert_equal(getattr(magic_foo2, 'argcmd_name', None), None)
88 88 yield assert_equal(real_name(magic_foo2), 'foo2')
89 89 yield assert_equal(magic_foo2(None, ''), argparse.Namespace())
90 90 yield assert_true(hasattr(magic_foo2, 'has_arguments'))
91 91
92 92 yield assert_equal(magic_foo3.__doc__, '%foo3 [-f FOO] [-b BAR] [-z BAZ]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n')
93 93 yield assert_equal(getattr(magic_foo3, 'argcmd_name', None), None)
94 94 yield assert_equal(real_name(magic_foo3), 'foo3')
95 95 yield assert_equal(magic_foo3(None, ''),
96 96 argparse.Namespace(bar=None, baz=None, foo=None))
97 97 yield assert_true(hasattr(magic_foo3, 'has_arguments'))
98 98
99 99 yield assert_equal(magic_foo4.__doc__, '%foo4 [-f FOO]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
100 100 yield assert_equal(getattr(magic_foo4, 'argcmd_name', None), None)
101 101 yield assert_equal(real_name(magic_foo4), 'foo4')
102 102 yield assert_equal(magic_foo4(None, ''), argparse.Namespace())
103 103 yield assert_true(hasattr(magic_foo4, 'has_arguments'))
104 104
105 105 yield assert_equal(magic_foo5.__doc__, '%frobnicate [-f FOO]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
106 106 yield assert_equal(getattr(magic_foo5, 'argcmd_name', None), 'frobnicate')
107 107 yield assert_equal(real_name(magic_foo5), 'frobnicate')
108 108 yield assert_equal(magic_foo5(None, ''), argparse.Namespace(foo=None))
109 109 yield assert_true(hasattr(magic_foo5, 'has_arguments'))
110 110
111 111 yield assert_equal(magic_magic_foo.__doc__, '%magic_foo [-f FOO]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
112 112 yield assert_equal(getattr(magic_magic_foo, 'argcmd_name', None), None)
113 113 yield assert_equal(real_name(magic_magic_foo), 'magic_foo')
114 114 yield assert_equal(magic_magic_foo(None, ''), argparse.Namespace(foo=None))
115 115 yield assert_true(hasattr(magic_magic_foo, 'has_arguments'))
116 116
117 117 yield assert_equal(foo.__doc__, '%foo [-f FOO]\n\nA docstring.\n\noptional arguments:\n -f FOO, --foo FOO an argument\n')
118 118 yield assert_equal(getattr(foo, 'argcmd_name', None), None)
119 119 yield assert_equal(real_name(foo), 'foo')
120 120 yield assert_equal(foo(None, ''), argparse.Namespace(foo=None))
121 121 yield assert_true(hasattr(foo, 'has_arguments'))
@@ -1,136 +1,136 b''
1 1 """Tests for the object inspection functionality.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010 The IPython Development Team.
4 # Copyright (C) 2010-2011 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14 from __future__ import print_function
15 15
16 16 # Stdlib imports
17 17
18 18 # Third-party imports
19 19 import nose.tools as nt
20 20
21 21 # Our own imports
22 22 from .. import oinspect
23 23 from IPython.utils import py3compat
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Globals and constants
27 27 #-----------------------------------------------------------------------------
28 28
29 29 inspector = oinspect.Inspector()
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Local utilities
33 33 #-----------------------------------------------------------------------------
34 34
35 35 # A few generic objects we can then inspect in the tests below
36 36
37 37 class Call(object):
38 38 """This is the class docstring."""
39 39
40 40 def __init__(self, x, y=1):
41 41 """This is the constructor docstring."""
42 42
43 43 def __call__(self, *a, **kw):
44 44 """This is the call docstring."""
45 45
46 46 def method(self, x, z=2):
47 47 """Some method's docstring"""
48 48
49 49 class OldStyle:
50 50 """An old-style class for testing."""
51 51 pass
52 52
53 53 def f(x, y=2, *a, **kw):
54 54 """A simple function."""
55 55
56 56 def g(y, z=3, *a, **kw):
57 57 pass # no docstring
58 58
59 59
60 60 def check_calltip(obj, name, call, docstring):
61 61 """Generic check pattern all calltip tests will use"""
62 62 info = inspector.info(obj, name)
63 63 call_line, ds = oinspect.call_tip(info)
64 64 nt.assert_equal(call_line, call)
65 65 nt.assert_equal(ds, docstring)
66 66
67 67 #-----------------------------------------------------------------------------
68 68 # Tests
69 69 #-----------------------------------------------------------------------------
70 70
71 71 def test_calltip_class():
72 72 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
73 73
74 74
75 75 def test_calltip_instance():
76 76 c = Call(1)
77 77 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
78 78
79 79
80 80 def test_calltip_method():
81 81 c = Call(1)
82 82 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
83 83
84 84
85 85 def test_calltip_function():
86 86 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
87 87
88 88
89 89 def test_calltip_function2():
90 90 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
91 91
92 92
93 93 def test_calltip_builtin():
94 94 check_calltip(sum, 'sum', None, sum.__doc__)
95 95
96 96 def test_info():
97 97 "Check that Inspector.info fills out various fields as expected."
98 98 i = inspector.info(Call, oname='Call')
99 99 nt.assert_equal(i['type_name'], 'type')
100 100 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
101 101 nt.assert_equal(i['base_class'], expted_class)
102 102 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
103 103 fname = __file__
104 104 if fname.endswith(".pyc"):
105 105 fname = fname[:-1]
106 106 # case-insensitive comparison needed on some filesystems
107 107 # e.g. Windows:
108 108 nt.assert_equal(i['file'].lower(), fname.lower())
109 109 nt.assert_equal(i['definition'], 'Call(self, *a, **kw)\n')
110 110 nt.assert_equal(i['docstring'], Call.__doc__)
111 111 nt.assert_equal(i['source'], None)
112 112 nt.assert_true(i['isclass'])
113 113 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
114 114 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
115 115
116 116 i = inspector.info(Call, detail_level=1)
117 117 nt.assert_not_equal(i['source'], None)
118 118 nt.assert_equal(i['docstring'], None)
119 119
120 120 c = Call(1)
121 121 c.__doc__ = "Modified instance docstring"
122 122 i = inspector.info(c)
123 123 nt.assert_equal(i['type_name'], 'Call')
124 124 nt.assert_equal(i['docstring'], "Modified instance docstring")
125 125 nt.assert_equal(i['class_docstring'], Call.__doc__)
126 126 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
127 127 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
128 128
129 129 # Test old-style classes, which for example may not have an __init__ method.
130 130 if not py3compat.PY3:
131 131 i = inspector.info(OldStyle)
132 132 nt.assert_equal(i['type_name'], 'classobj')
133 133
134 134 i = inspector.info(OldStyle())
135 135 nt.assert_equal(i['type_name'], 'instance')
136 136 nt.assert_equal(i['docstring'], OldStyle.__doc__)
@@ -1,20 +1,20 b''
1 1 #-----------------------------------------------------------------------------
2 # Copyright (C) 2010 The IPython Development Team.
2 # Copyright (C) 2010-2011 The IPython Development Team.
3 3 #
4 4 # Distributed under the terms of the BSD License.
5 5 #
6 6 # The full license is in the file COPYING.txt, distributed with this software.
7 7 #-----------------------------------------------------------------------------
8 8 import io
9 9
10 10 # N.B. For the test suite, page.page is overridden (see IPython.testing.globalipapp)
11 11 from IPython.core import page
12 12
13 13 def test_detect_screen_size():
14 14 """Simple smoketest for page._detect_screen_size."""
15 15 try:
16 16 page._detect_screen_size(True, 25)
17 17 except (TypeError, io.UnsupportedOperation):
18 18 # This can happen in the test suite, because stdout may not have a
19 19 # fileno.
20 20 pass
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now