##// END OF EJS Templates
Progress towards getting the test suite in shape again....
Fernando Perez -
Show More
@@ -1,163 +1,163 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.config.loader
4 Tests for IPython.config.loader
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.config.loader import (
27 from IPython.config.loader import (
28 Config,
28 Config,
29 PyFileConfigLoader,
29 PyFileConfigLoader,
30 ArgParseConfigLoader,
30 ArgParseConfigLoader,
31 ConfigError
31 ConfigError
32 )
32 )
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Actual tests
35 # Actual tests
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 pyfile = """
39 pyfile = """
40 a = 10
40 a = 10
41 b = 20
41 b = 20
42 Foo.Bar.value = 10
42 Foo.Bar.value = 10
43 Foo.Bam.value = range(10)
43 Foo.Bam.value = range(10)
44 D.C.value = 'hi there'
44 D.C.value = 'hi there'
45 """
45 """
46
46
47 class TestPyFileCL(TestCase):
47 class TestPyFileCL(TestCase):
48
48
49 def test_basic(self):
49 def test_basic(self):
50 fd, fname = mkstemp()
50 fd, fname = mkstemp('.py')
51 f = os.fdopen(fd, 'w')
51 f = os.fdopen(fd, 'w')
52 f.write(pyfile)
52 f.write(pyfile)
53 f.close()
53 f.close()
54 # Unlink the file
54 # Unlink the file
55 cl = PyFileConfigLoader(fname)
55 cl = PyFileConfigLoader(fname)
56 config = cl.load_config()
56 config = cl.load_config()
57 self.assertEquals(config.a, 10)
57 self.assertEquals(config.a, 10)
58 self.assertEquals(config.b, 20)
58 self.assertEquals(config.b, 20)
59 self.assertEquals(config.Foo.Bar.value, 10)
59 self.assertEquals(config.Foo.Bar.value, 10)
60 self.assertEquals(config.Foo.Bam.value, range(10))
60 self.assertEquals(config.Foo.Bam.value, range(10))
61 self.assertEquals(config.D.C.value, 'hi there')
61 self.assertEquals(config.D.C.value, 'hi there')
62
62
63
63
64 class TestArgParseCL(TestCase):
64 class TestArgParseCL(TestCase):
65
65
66 def test_basic(self):
66 def test_basic(self):
67
67
68 class MyLoader(ArgParseConfigLoader):
68 class MyLoader(ArgParseConfigLoader):
69 arguments = (
69 arguments = (
70 (('-f','--foo'), dict(dest='Global.foo', type=str)),
70 (('-f','--foo'), dict(dest='Global.foo', type=str)),
71 (('-b',), dict(dest='MyClass.bar', type=int)),
71 (('-b',), dict(dest='MyClass.bar', type=int)),
72 (('-n',), dict(dest='n', action='store_true')),
72 (('-n',), dict(dest='n', action='store_true')),
73 (('Global.bam',), dict(type=str))
73 (('Global.bam',), dict(type=str))
74 )
74 )
75
75
76 cl = MyLoader()
76 cl = MyLoader()
77 config = cl.load_config('-f hi -b 10 -n wow'.split())
77 config = cl.load_config('-f hi -b 10 -n wow'.split())
78 self.assertEquals(config.Global.foo, 'hi')
78 self.assertEquals(config.Global.foo, 'hi')
79 self.assertEquals(config.MyClass.bar, 10)
79 self.assertEquals(config.MyClass.bar, 10)
80 self.assertEquals(config.n, True)
80 self.assertEquals(config.n, True)
81 self.assertEquals(config.Global.bam, 'wow')
81 self.assertEquals(config.Global.bam, 'wow')
82
82
83 def test_add_arguments(self):
83 def test_add_arguments(self):
84
84
85 class MyLoader(ArgParseConfigLoader):
85 class MyLoader(ArgParseConfigLoader):
86 def _add_arguments(self):
86 def _add_arguments(self):
87 subparsers = self.parser.add_subparsers(dest='subparser_name')
87 subparsers = self.parser.add_subparsers(dest='subparser_name')
88 subparser1 = subparsers.add_parser('1')
88 subparser1 = subparsers.add_parser('1')
89 subparser1.add_argument('-x',dest='Global.x')
89 subparser1.add_argument('-x',dest='Global.x')
90 subparser2 = subparsers.add_parser('2')
90 subparser2 = subparsers.add_parser('2')
91 subparser2.add_argument('y')
91 subparser2.add_argument('y')
92
92
93 cl = MyLoader()
93 cl = MyLoader()
94 config = cl.load_config('2 frobble'.split())
94 config = cl.load_config('2 frobble'.split())
95 self.assertEquals(config.subparser_name, '2')
95 self.assertEquals(config.subparser_name, '2')
96 self.assertEquals(config.y, 'frobble')
96 self.assertEquals(config.y, 'frobble')
97 config = cl.load_config('1 -x frobble'.split())
97 config = cl.load_config('1 -x frobble'.split())
98 self.assertEquals(config.subparser_name, '1')
98 self.assertEquals(config.subparser_name, '1')
99 self.assertEquals(config.Global.x, 'frobble')
99 self.assertEquals(config.Global.x, 'frobble')
100
100
101 class TestConfig(TestCase):
101 class TestConfig(TestCase):
102
102
103 def test_setget(self):
103 def test_setget(self):
104 c = Config()
104 c = Config()
105 c.a = 10
105 c.a = 10
106 self.assertEquals(c.a, 10)
106 self.assertEquals(c.a, 10)
107 self.assertEquals(c.has_key('b'), False)
107 self.assertEquals(c.has_key('b'), False)
108
108
109 def test_auto_section(self):
109 def test_auto_section(self):
110 c = Config()
110 c = Config()
111 self.assertEquals(c.has_key('A'), True)
111 self.assertEquals(c.has_key('A'), True)
112 self.assertEquals(c._has_section('A'), False)
112 self.assertEquals(c._has_section('A'), False)
113 A = c.A
113 A = c.A
114 A.foo = 'hi there'
114 A.foo = 'hi there'
115 self.assertEquals(c._has_section('A'), True)
115 self.assertEquals(c._has_section('A'), True)
116 self.assertEquals(c.A.foo, 'hi there')
116 self.assertEquals(c.A.foo, 'hi there')
117 del c.A
117 del c.A
118 self.assertEquals(len(c.A.keys()),0)
118 self.assertEquals(len(c.A.keys()),0)
119
119
120 def test_merge_doesnt_exist(self):
120 def test_merge_doesnt_exist(self):
121 c1 = Config()
121 c1 = Config()
122 c2 = Config()
122 c2 = Config()
123 c2.bar = 10
123 c2.bar = 10
124 c2.Foo.bar = 10
124 c2.Foo.bar = 10
125 c1._merge(c2)
125 c1._merge(c2)
126 self.assertEquals(c1.Foo.bar, 10)
126 self.assertEquals(c1.Foo.bar, 10)
127 self.assertEquals(c1.bar, 10)
127 self.assertEquals(c1.bar, 10)
128 c2.Bar.bar = 10
128 c2.Bar.bar = 10
129 c1._merge(c2)
129 c1._merge(c2)
130 self.assertEquals(c1.Bar.bar, 10)
130 self.assertEquals(c1.Bar.bar, 10)
131
131
132 def test_merge_exists(self):
132 def test_merge_exists(self):
133 c1 = Config()
133 c1 = Config()
134 c2 = Config()
134 c2 = Config()
135 c1.Foo.bar = 10
135 c1.Foo.bar = 10
136 c1.Foo.bam = 30
136 c1.Foo.bam = 30
137 c2.Foo.bar = 20
137 c2.Foo.bar = 20
138 c2.Foo.wow = 40
138 c2.Foo.wow = 40
139 c1._merge(c2)
139 c1._merge(c2)
140 self.assertEquals(c1.Foo.bam, 30)
140 self.assertEquals(c1.Foo.bam, 30)
141 self.assertEquals(c1.Foo.bar, 20)
141 self.assertEquals(c1.Foo.bar, 20)
142 self.assertEquals(c1.Foo.wow, 40)
142 self.assertEquals(c1.Foo.wow, 40)
143 c2.Foo.Bam.bam = 10
143 c2.Foo.Bam.bam = 10
144 c1._merge(c2)
144 c1._merge(c2)
145 self.assertEquals(c1.Foo.Bam.bam, 10)
145 self.assertEquals(c1.Foo.Bam.bam, 10)
146
146
147 def test_deepcopy(self):
147 def test_deepcopy(self):
148 c1 = Config()
148 c1 = Config()
149 c1.Foo.bar = 10
149 c1.Foo.bar = 10
150 c1.Foo.bam = 30
150 c1.Foo.bam = 30
151 c1.a = 'asdf'
151 c1.a = 'asdf'
152 c1.b = range(10)
152 c1.b = range(10)
153 import copy
153 import copy
154 c2 = copy.deepcopy(c1)
154 c2 = copy.deepcopy(c1)
155 self.assertEquals(c1, c2)
155 self.assertEquals(c1, c2)
156 self.assert_(c1 is not c2)
156 self.assert_(c1 is not c2)
157 self.assert_(c1.Foo is not c2.Foo)
157 self.assert_(c1.Foo is not c2.Foo)
158
158
159 def test_builtin(self):
159 def test_builtin(self):
160 c1 = Config()
160 c1 = Config()
161 exec 'foo = True' in c1
161 exec 'foo = True' in c1
162 self.assertEquals(c1.foo, True)
162 self.assertEquals(c1.foo, True)
163 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
163 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
@@ -1,381 +1,390 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 An application for IPython.
4 An application for IPython.
5
5
6 All top-level applications should use the classes in this module for
6 All top-level applications should use the classes in this module for
7 handling configuration and creating componenets.
7 handling configuration and creating componenets.
8
8
9 The job of an :class:`Application` is to create the master configuration
9 The job of an :class:`Application` is to create the master configuration
10 object and then create the components, passing the config to them.
10 object and then create the components, passing the config to them.
11
11
12 Authors:
12 Authors:
13
13
14 * Brian Granger
14 * Brian Granger
15 * Fernando Perez
15 * Fernando Perez
16
16
17 Notes
17 Notes
18 -----
18 -----
19 """
19 """
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Copyright (C) 2008-2009 The IPython Development Team
22 # Copyright (C) 2008-2009 The IPython Development Team
23 #
23 #
24 # Distributed under the terms of the BSD License. The full license is in
24 # Distributed under the terms of the BSD License. The full license is in
25 # the file COPYING, distributed as part of this software.
25 # the file COPYING, distributed as part of this software.
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Imports
29 # Imports
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 import logging
32 import logging
33 import os
33 import os
34 import sys
34 import sys
35
35
36 from IPython.core import release
36 from IPython.core import release
37 from IPython.utils.genutils import get_ipython_dir, get_ipython_package_dir
37 from IPython.utils.genutils import get_ipython_dir, get_ipython_package_dir
38 from IPython.config.loader import (
38 from IPython.config.loader import (
39 PyFileConfigLoader,
39 PyFileConfigLoader,
40 ArgParseConfigLoader,
40 ArgParseConfigLoader,
41 Config,
41 Config,
42 NoConfigDefault
42 NoConfigDefault
43 )
43 )
44
44
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46 # Classes and functions
46 # Classes and functions
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48
48
49
49
50 class BaseAppArgParseConfigLoader(ArgParseConfigLoader):
50 class BaseAppArgParseConfigLoader(ArgParseConfigLoader):
51 """Default command line options for IPython based applications."""
51 """Default command line options for IPython based applications."""
52
52
53 def _add_other_arguments(self):
53 def _add_other_arguments(self):
54 self.parser.add_argument('--ipython-dir',
54 self.parser.add_argument('--ipython-dir',
55 dest='Global.ipython_dir',type=unicode,
55 dest='Global.ipython_dir',type=unicode,
56 help='Set to override default location of Global.ipython_dir.',
56 help='Set to override default location of Global.ipython_dir.',
57 default=NoConfigDefault,
57 default=NoConfigDefault,
58 metavar='Global.ipython_dir')
58 metavar='Global.ipython_dir')
59 self.parser.add_argument('-p', '--profile',
59 self.parser.add_argument('-p', '--profile',
60 dest='Global.profile',type=unicode,
60 dest='Global.profile',type=unicode,
61 help='The string name of the ipython profile to be used.',
61 help='The string name of the ipython profile to be used.',
62 default=NoConfigDefault,
62 default=NoConfigDefault,
63 metavar='Global.profile')
63 metavar='Global.profile')
64 self.parser.add_argument('--log-level',
64 self.parser.add_argument('--log-level',
65 dest="Global.log_level",type=int,
65 dest="Global.log_level",type=int,
66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
67 default=NoConfigDefault,
67 default=NoConfigDefault,
68 metavar='Global.log_level')
68 metavar='Global.log_level')
69 self.parser.add_argument('--config-file',
69 self.parser.add_argument('--config-file',
70 dest='Global.config_file',type=unicode,
70 dest='Global.config_file',type=unicode,
71 help='Set the config file name to override default.',
71 help='Set the config file name to override default.',
72 default=NoConfigDefault,
72 default=NoConfigDefault,
73 metavar='Global.config_file')
73 metavar='Global.config_file')
74
74
75
75
76 class ApplicationError(Exception):
76 class ApplicationError(Exception):
77 pass
77 pass
78
78
79
79
80 class Application(object):
80 class Application(object):
81 """Load a config, construct components and set them running."""
81 """Load a config, construct components and set them running."""
82
82
83 name = u'ipython'
83 name = u'ipython'
84 description = 'IPython: an enhanced interactive Python shell.'
84 description = 'IPython: an enhanced interactive Python shell.'
85
85
86 config_file_name = u'ipython_config.py'
86 config_file_name = u'ipython_config.py'
87 # Track the default and actual separately because some messages are
87 # Track the default and actual separately because some messages are
88 # only printed if we aren't using the default.
88 # only printed if we aren't using the default.
89 default_config_file_name = config_file_name
89 default_config_file_name = config_file_name
90 default_log_level = logging.WARN
90 default_log_level = logging.WARN
91 # Set by --profile option
91 # Set by --profile option
92 profile_name = None
92 profile_name = None
93 #: User's ipython directory, typically ~/.ipython/
93 #: User's ipython directory, typically ~/.ipython/
94 ipython_dir = None
94 ipython_dir = None
95 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
95 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
96 argv = None
96 argv = None
97
97
98 # Private attributes
98 # Private attributes
99 _exiting = False
99 _exiting = False
100 _initialized = False
100
101
101 def __init__(self, argv=None):
102 def __init__(self, argv=None):
102 self.argv = sys.argv[1:] if argv is None else argv
103 self.argv = sys.argv[1:] if argv is None else argv
103 self.init_logger()
104 self.init_logger()
104
105
105 def init_logger(self):
106 def init_logger(self):
106 self.log = logging.getLogger(self.__class__.__name__)
107 self.log = logging.getLogger(self.__class__.__name__)
107 # This is used as the default until the command line arguments are read.
108 # This is used as the default until the command line arguments are read.
108 self.log.setLevel(self.default_log_level)
109 self.log.setLevel(self.default_log_level)
109 self._log_handler = logging.StreamHandler()
110 self._log_handler = logging.StreamHandler()
110 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
111 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
111 self._log_handler.setFormatter(self._log_formatter)
112 self._log_handler.setFormatter(self._log_formatter)
112 self.log.addHandler(self._log_handler)
113 self.log.addHandler(self._log_handler)
113
114
114 def _set_log_level(self, level):
115 def _set_log_level(self, level):
115 self.log.setLevel(level)
116 self.log.setLevel(level)
116
117
117 def _get_log_level(self):
118 def _get_log_level(self):
118 return self.log.level
119 return self.log.level
119
120
120 log_level = property(_get_log_level, _set_log_level)
121 log_level = property(_get_log_level, _set_log_level)
121
122
122 def start(self):
123 def initialize(self):
123 """Start the application."""
124 """Start the application."""
125
126 if self._initialized:
127 return
128
124 self.attempt(self.create_default_config)
129 self.attempt(self.create_default_config)
125 self.log_default_config()
130 self.log_default_config()
126 self.set_default_config_log_level()
131 self.set_default_config_log_level()
127 self.attempt(self.pre_load_command_line_config)
132 self.attempt(self.pre_load_command_line_config)
128 self.attempt(self.load_command_line_config, action='abort')
133 self.attempt(self.load_command_line_config, action='abort')
129 self.set_command_line_config_log_level()
134 self.set_command_line_config_log_level()
130 self.attempt(self.post_load_command_line_config)
135 self.attempt(self.post_load_command_line_config)
131 self.log_command_line_config()
136 self.log_command_line_config()
132 self.attempt(self.find_ipython_dir)
137 self.attempt(self.find_ipython_dir)
133 self.attempt(self.find_resources)
138 self.attempt(self.find_resources)
134 self.attempt(self.find_config_file_name)
139 self.attempt(self.find_config_file_name)
135 self.attempt(self.find_config_file_paths)
140 self.attempt(self.find_config_file_paths)
136 self.attempt(self.pre_load_file_config)
141 self.attempt(self.pre_load_file_config)
137 self.attempt(self.load_file_config)
142 self.attempt(self.load_file_config)
138 self.set_file_config_log_level()
143 self.set_file_config_log_level()
139 self.attempt(self.post_load_file_config)
144 self.attempt(self.post_load_file_config)
140 self.log_file_config()
145 self.log_file_config()
141 self.attempt(self.merge_configs)
146 self.attempt(self.merge_configs)
142 self.log_master_config()
147 self.log_master_config()
143 self.attempt(self.pre_construct)
148 self.attempt(self.pre_construct)
144 self.attempt(self.construct)
149 self.attempt(self.construct)
145 self.attempt(self.post_construct)
150 self.attempt(self.post_construct)
151 self._initialized = True
152
153 def start(self):
154 self.initialize()
146 self.attempt(self.start_app)
155 self.attempt(self.start_app)
147
156
148 #-------------------------------------------------------------------------
157 #-------------------------------------------------------------------------
149 # Various stages of Application creation
158 # Various stages of Application creation
150 #-------------------------------------------------------------------------
159 #-------------------------------------------------------------------------
151
160
152 def create_default_config(self):
161 def create_default_config(self):
153 """Create defaults that can't be set elsewhere.
162 """Create defaults that can't be set elsewhere.
154
163
155 For the most part, we try to set default in the class attributes
164 For the most part, we try to set default in the class attributes
156 of Components. But, defaults the top-level Application (which is
165 of Components. But, defaults the top-level Application (which is
157 not a HasTraitlets or Component) are not set in this way. Instead
166 not a HasTraitlets or Component) are not set in this way. Instead
158 we set them here. The Global section is for variables like this that
167 we set them here. The Global section is for variables like this that
159 don't belong to a particular component.
168 don't belong to a particular component.
160 """
169 """
161 c = Config()
170 c = Config()
162 c.Global.ipython_dir = get_ipython_dir()
171 c.Global.ipython_dir = get_ipython_dir()
163 c.Global.log_level = self.log_level
172 c.Global.log_level = self.log_level
164 self.default_config = c
173 self.default_config = c
165
174
166 def log_default_config(self):
175 def log_default_config(self):
167 self.log.debug('Default config loaded:')
176 self.log.debug('Default config loaded:')
168 self.log.debug(repr(self.default_config))
177 self.log.debug(repr(self.default_config))
169
178
170 def set_default_config_log_level(self):
179 def set_default_config_log_level(self):
171 try:
180 try:
172 self.log_level = self.default_config.Global.log_level
181 self.log_level = self.default_config.Global.log_level
173 except AttributeError:
182 except AttributeError:
174 # Fallback to the default_log_level class attribute
183 # Fallback to the default_log_level class attribute
175 pass
184 pass
176
185
177 def create_command_line_config(self):
186 def create_command_line_config(self):
178 """Create and return a command line config loader."""
187 """Create and return a command line config loader."""
179 return BaseAppArgParseConfigLoader(self.argv,
188 return BaseAppArgParseConfigLoader(self.argv,
180 description=self.description,
189 description=self.description,
181 version=release.version
190 version=release.version
182 )
191 )
183
192
184 def pre_load_command_line_config(self):
193 def pre_load_command_line_config(self):
185 """Do actions just before loading the command line config."""
194 """Do actions just before loading the command line config."""
186 pass
195 pass
187
196
188 def load_command_line_config(self):
197 def load_command_line_config(self):
189 """Load the command line config."""
198 """Load the command line config."""
190 loader = self.create_command_line_config()
199 loader = self.create_command_line_config()
191 self.command_line_config = loader.load_config()
200 self.command_line_config = loader.load_config()
192 self.extra_args = loader.get_extra_args()
201 self.extra_args = loader.get_extra_args()
193
202
194 def set_command_line_config_log_level(self):
203 def set_command_line_config_log_level(self):
195 try:
204 try:
196 self.log_level = self.command_line_config.Global.log_level
205 self.log_level = self.command_line_config.Global.log_level
197 except AttributeError:
206 except AttributeError:
198 pass
207 pass
199
208
200 def post_load_command_line_config(self):
209 def post_load_command_line_config(self):
201 """Do actions just after loading the command line config."""
210 """Do actions just after loading the command line config."""
202 pass
211 pass
203
212
204 def log_command_line_config(self):
213 def log_command_line_config(self):
205 self.log.debug("Command line config loaded:")
214 self.log.debug("Command line config loaded:")
206 self.log.debug(repr(self.command_line_config))
215 self.log.debug(repr(self.command_line_config))
207
216
208 def find_ipython_dir(self):
217 def find_ipython_dir(self):
209 """Set the IPython directory.
218 """Set the IPython directory.
210
219
211 This sets ``self.ipython_dir``, but the actual value that is passed to
220 This sets ``self.ipython_dir``, but the actual value that is passed to
212 the application is kept in either ``self.default_config`` or
221 the application is kept in either ``self.default_config`` or
213 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
222 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
214 ``sys.path`` so config files there can be referenced by other config
223 ``sys.path`` so config files there can be referenced by other config
215 files.
224 files.
216 """
225 """
217
226
218 try:
227 try:
219 self.ipython_dir = self.command_line_config.Global.ipython_dir
228 self.ipython_dir = self.command_line_config.Global.ipython_dir
220 except AttributeError:
229 except AttributeError:
221 self.ipython_dir = self.default_config.Global.ipython_dir
230 self.ipython_dir = self.default_config.Global.ipython_dir
222 sys.path.append(os.path.abspath(self.ipython_dir))
231 sys.path.append(os.path.abspath(self.ipython_dir))
223 if not os.path.isdir(self.ipython_dir):
232 if not os.path.isdir(self.ipython_dir):
224 os.makedirs(self.ipython_dir, mode=0777)
233 os.makedirs(self.ipython_dir, mode=0777)
225 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
234 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
226
235
227 def find_resources(self):
236 def find_resources(self):
228 """Find other resources that need to be in place.
237 """Find other resources that need to be in place.
229
238
230 Things like cluster directories need to be in place to find the
239 Things like cluster directories need to be in place to find the
231 config file. These happen right after the IPython directory has
240 config file. These happen right after the IPython directory has
232 been set.
241 been set.
233 """
242 """
234 pass
243 pass
235
244
236 def find_config_file_name(self):
245 def find_config_file_name(self):
237 """Find the config file name for this application.
246 """Find the config file name for this application.
238
247
239 This must set ``self.config_file_name`` to the filename of the
248 This must set ``self.config_file_name`` to the filename of the
240 config file to use (just the filename). The search paths for the
249 config file to use (just the filename). The search paths for the
241 config file are set in :meth:`find_config_file_paths` and then passed
250 config file are set in :meth:`find_config_file_paths` and then passed
242 to the config file loader where they are resolved to an absolute path.
251 to the config file loader where they are resolved to an absolute path.
243
252
244 If a profile has been set at the command line, this will resolve it.
253 If a profile has been set at the command line, this will resolve it.
245 """
254 """
246
255
247 try:
256 try:
248 self.config_file_name = self.command_line_config.Global.config_file
257 self.config_file_name = self.command_line_config.Global.config_file
249 except AttributeError:
258 except AttributeError:
250 pass
259 pass
251
260
252 try:
261 try:
253 self.profile_name = self.command_line_config.Global.profile
262 self.profile_name = self.command_line_config.Global.profile
254 except AttributeError:
263 except AttributeError:
255 pass
264 pass
256 else:
265 else:
257 name_parts = self.config_file_name.split('.')
266 name_parts = self.config_file_name.split('.')
258 name_parts.insert(1, u'_' + self.profile_name + u'.')
267 name_parts.insert(1, u'_' + self.profile_name + u'.')
259 self.config_file_name = ''.join(name_parts)
268 self.config_file_name = ''.join(name_parts)
260
269
261 def find_config_file_paths(self):
270 def find_config_file_paths(self):
262 """Set the search paths for resolving the config file.
271 """Set the search paths for resolving the config file.
263
272
264 This must set ``self.config_file_paths`` to a sequence of search
273 This must set ``self.config_file_paths`` to a sequence of search
265 paths to pass to the config file loader.
274 paths to pass to the config file loader.
266 """
275 """
267 # Include our own profiles directory last, so that users can still find
276 # Include our own profiles directory last, so that users can still find
268 # our shipped copies of builtin profiles even if they don't have them
277 # our shipped copies of builtin profiles even if they don't have them
269 # in their local ipython directory.
278 # in their local ipython directory.
270 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
279 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
271 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
280 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
272
281
273 def pre_load_file_config(self):
282 def pre_load_file_config(self):
274 """Do actions before the config file is loaded."""
283 """Do actions before the config file is loaded."""
275 pass
284 pass
276
285
277 def load_file_config(self):
286 def load_file_config(self):
278 """Load the config file.
287 """Load the config file.
279
288
280 This tries to load the config file from disk. If successful, the
289 This tries to load the config file from disk. If successful, the
281 ``CONFIG_FILE`` config variable is set to the resolved config file
290 ``CONFIG_FILE`` config variable is set to the resolved config file
282 location. If not successful, an empty config is used.
291 location. If not successful, an empty config is used.
283 """
292 """
284 self.log.debug("Attempting to load config file: %s" %
293 self.log.debug("Attempting to load config file: %s" %
285 self.config_file_name)
294 self.config_file_name)
286 loader = PyFileConfigLoader(self.config_file_name,
295 loader = PyFileConfigLoader(self.config_file_name,
287 path=self.config_file_paths)
296 path=self.config_file_paths)
288 try:
297 try:
289 self.file_config = loader.load_config()
298 self.file_config = loader.load_config()
290 self.file_config.Global.config_file = loader.full_filename
299 self.file_config.Global.config_file = loader.full_filename
291 except IOError:
300 except IOError:
292 # Only warn if the default config file was NOT being used.
301 # Only warn if the default config file was NOT being used.
293 if not self.config_file_name==self.default_config_file_name:
302 if not self.config_file_name==self.default_config_file_name:
294 self.log.warn("Config file not found, skipping: %s" %
303 self.log.warn("Config file not found, skipping: %s" %
295 self.config_file_name, exc_info=True)
304 self.config_file_name, exc_info=True)
296 self.file_config = Config()
305 self.file_config = Config()
297 except:
306 except:
298 self.log.warn("Error loading config file: %s" %
307 self.log.warn("Error loading config file: %s" %
299 self.config_file_name, exc_info=True)
308 self.config_file_name, exc_info=True)
300 self.file_config = Config()
309 self.file_config = Config()
301
310
302 def set_file_config_log_level(self):
311 def set_file_config_log_level(self):
303 # We need to keeep self.log_level updated. But we only use the value
312 # We need to keeep self.log_level updated. But we only use the value
304 # of the file_config if a value was not specified at the command
313 # of the file_config if a value was not specified at the command
305 # line, because the command line overrides everything.
314 # line, because the command line overrides everything.
306 if not hasattr(self.command_line_config.Global, 'log_level'):
315 if not hasattr(self.command_line_config.Global, 'log_level'):
307 try:
316 try:
308 self.log_level = self.file_config.Global.log_level
317 self.log_level = self.file_config.Global.log_level
309 except AttributeError:
318 except AttributeError:
310 pass # Use existing value
319 pass # Use existing value
311
320
312 def post_load_file_config(self):
321 def post_load_file_config(self):
313 """Do actions after the config file is loaded."""
322 """Do actions after the config file is loaded."""
314 pass
323 pass
315
324
316 def log_file_config(self):
325 def log_file_config(self):
317 if hasattr(self.file_config.Global, 'config_file'):
326 if hasattr(self.file_config.Global, 'config_file'):
318 self.log.debug("Config file loaded: %s" %
327 self.log.debug("Config file loaded: %s" %
319 self.file_config.Global.config_file)
328 self.file_config.Global.config_file)
320 self.log.debug(repr(self.file_config))
329 self.log.debug(repr(self.file_config))
321
330
322 def merge_configs(self):
331 def merge_configs(self):
323 """Merge the default, command line and file config objects."""
332 """Merge the default, command line and file config objects."""
324 config = Config()
333 config = Config()
325 config._merge(self.default_config)
334 config._merge(self.default_config)
326 config._merge(self.file_config)
335 config._merge(self.file_config)
327 config._merge(self.command_line_config)
336 config._merge(self.command_line_config)
328 self.master_config = config
337 self.master_config = config
329
338
330 def log_master_config(self):
339 def log_master_config(self):
331 self.log.debug("Master config created:")
340 self.log.debug("Master config created:")
332 self.log.debug(repr(self.master_config))
341 self.log.debug(repr(self.master_config))
333
342
334 def pre_construct(self):
343 def pre_construct(self):
335 """Do actions after the config has been built, but before construct."""
344 """Do actions after the config has been built, but before construct."""
336 pass
345 pass
337
346
338 def construct(self):
347 def construct(self):
339 """Construct the main components that make up this app."""
348 """Construct the main components that make up this app."""
340 self.log.debug("Constructing components for application")
349 self.log.debug("Constructing components for application")
341
350
342 def post_construct(self):
351 def post_construct(self):
343 """Do actions after construct, but before starting the app."""
352 """Do actions after construct, but before starting the app."""
344 pass
353 pass
345
354
346 def start_app(self):
355 def start_app(self):
347 """Actually start the app."""
356 """Actually start the app."""
348 self.log.debug("Starting application")
357 self.log.debug("Starting application")
349
358
350 #-------------------------------------------------------------------------
359 #-------------------------------------------------------------------------
351 # Utility methods
360 # Utility methods
352 #-------------------------------------------------------------------------
361 #-------------------------------------------------------------------------
353
362
354 def abort(self):
363 def abort(self):
355 """Abort the starting of the application."""
364 """Abort the starting of the application."""
356 if self._exiting:
365 if self._exiting:
357 pass
366 pass
358 else:
367 else:
359 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
368 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
360 self._exiting = True
369 self._exiting = True
361 sys.exit(1)
370 sys.exit(1)
362
371
363 def exit(self, exit_status=0):
372 def exit(self, exit_status=0):
364 if self._exiting:
373 if self._exiting:
365 pass
374 pass
366 else:
375 else:
367 self.log.debug("Exiting application: %s" % self.name)
376 self.log.debug("Exiting application: %s" % self.name)
368 self._exiting = True
377 self._exiting = True
369 sys.exit(exit_status)
378 sys.exit(exit_status)
370
379
371 def attempt(self, func, action='abort'):
380 def attempt(self, func, action='abort'):
372 try:
381 try:
373 func()
382 func()
374 except SystemExit:
383 except SystemExit:
375 raise
384 raise
376 except:
385 except:
377 if action == 'abort':
386 if action == 'abort':
378 self.abort()
387 self.abort()
379 elif action == 'exit':
388 elif action == 'exit':
380 self.exit(0)
389 self.exit(0)
381
390
@@ -1,254 +1,255 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """ History related magics and functionality """
2 """ History related magics and functionality """
3
3
4 # Stdlib imports
4 # Stdlib imports
5 import fnmatch
5 import fnmatch
6 import os
6 import os
7
7
8 from IPython.utils.genutils import Term, ask_yes_no, warn
8 from IPython.utils.genutils import Term, ask_yes_no, warn
9 from IPython.core import ipapi
9 from IPython.core import ipapi
10
10
11 def magic_history(self, parameter_s = ''):
11 def magic_history(self, parameter_s = ''):
12 """Print input history (_i<n> variables), with most recent last.
12 """Print input history (_i<n> variables), with most recent last.
13
13
14 %history -> print at most 40 inputs (some may be multi-line)\\
14 %history -> print at most 40 inputs (some may be multi-line)\\
15 %history n -> print at most n inputs\\
15 %history n -> print at most n inputs\\
16 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
16 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
17
17
18 Each input's number <n> is shown, and is accessible as the
18 Each input's number <n> is shown, and is accessible as the
19 automatically generated variable _i<n>. Multi-line statements are
19 automatically generated variable _i<n>. Multi-line statements are
20 printed starting at a new line for easy copy/paste.
20 printed starting at a new line for easy copy/paste.
21
21
22
22
23 Options:
23 Options:
24
24
25 -n: do NOT print line numbers. This is useful if you want to get a
25 -n: do NOT print line numbers. This is useful if you want to get a
26 printout of many lines which can be directly pasted into a text
26 printout of many lines which can be directly pasted into a text
27 editor.
27 editor.
28
28
29 This feature is only available if numbered prompts are in use.
29 This feature is only available if numbered prompts are in use.
30
30
31 -t: (default) print the 'translated' history, as IPython understands it.
31 -t: (default) print the 'translated' history, as IPython understands it.
32 IPython filters your input and converts it all into valid Python source
32 IPython filters your input and converts it all into valid Python source
33 before executing it (things like magics or aliases are turned into
33 before executing it (things like magics or aliases are turned into
34 function calls, for example). With this option, you'll see the native
34 function calls, for example). With this option, you'll see the native
35 history instead of the user-entered version: '%cd /' will be seen as
35 history instead of the user-entered version: '%cd /' will be seen as
36 '_ip.magic("%cd /")' instead of '%cd /'.
36 '_ip.magic("%cd /")' instead of '%cd /'.
37
37
38 -r: print the 'raw' history, i.e. the actual commands you typed.
38 -r: print the 'raw' history, i.e. the actual commands you typed.
39
39
40 -g: treat the arg as a pattern to grep for in (full) history.
40 -g: treat the arg as a pattern to grep for in (full) history.
41 This includes the "shadow history" (almost all commands ever written).
41 This includes the "shadow history" (almost all commands ever written).
42 Use '%hist -g' to show full shadow history (may be very long).
42 Use '%hist -g' to show full shadow history (may be very long).
43 In shadow history, every index nuwber starts with 0.
43 In shadow history, every index nuwber starts with 0.
44
44
45 -f FILENAME: instead of printing the output to the screen, redirect it to
45 -f FILENAME: instead of printing the output to the screen, redirect it to
46 the given file. The file is always overwritten, though IPython asks for
46 the given file. The file is always overwritten, though IPython asks for
47 confirmation first if it already exists.
47 confirmation first if it already exists.
48 """
48 """
49
49
50 if not self.outputcache.do_full_cache:
50 if not self.outputcache.do_full_cache:
51 print 'This feature is only available if numbered prompts are in use.'
51 print 'This feature is only available if numbered prompts are in use.'
52 return
52 return
53 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
53 opts,args = self.parse_options(parameter_s,'gntsrf:',mode='list')
54
54
55 # Check if output to specific file was requested.
55 # Check if output to specific file was requested.
56 try:
56 try:
57 outfname = opts['f']
57 outfname = opts['f']
58 except KeyError:
58 except KeyError:
59 outfile = Term.cout # default
59 outfile = Term.cout # default
60 # We don't want to close stdout at the end!
60 # We don't want to close stdout at the end!
61 close_at_end = False
61 close_at_end = False
62 else:
62 else:
63 if os.path.exists(outfname):
63 if os.path.exists(outfname):
64 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
64 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
65 print 'Aborting.'
65 print 'Aborting.'
66 return
66 return
67
67
68 outfile = open(outfname,'w')
68 outfile = open(outfname,'w')
69 close_at_end = True
69 close_at_end = True
70
70
71 if 't' in opts:
71 if 't' in opts:
72 input_hist = self.input_hist
72 input_hist = self.input_hist
73 elif 'r' in opts:
73 elif 'r' in opts:
74 input_hist = self.input_hist_raw
74 input_hist = self.input_hist_raw
75 else:
75 else:
76 input_hist = self.input_hist
76 input_hist = self.input_hist
77
77
78 default_length = 40
78 default_length = 40
79 pattern = None
79 pattern = None
80 if 'g' in opts:
80 if 'g' in opts:
81 init = 1
81 init = 1
82 final = len(input_hist)
82 final = len(input_hist)
83 parts = parameter_s.split(None,1)
83 parts = parameter_s.split(None,1)
84 if len(parts) == 1:
84 if len(parts) == 1:
85 parts += '*'
85 parts += '*'
86 head, pattern = parts
86 head, pattern = parts
87 pattern = "*" + pattern + "*"
87 pattern = "*" + pattern + "*"
88 elif len(args) == 0:
88 elif len(args) == 0:
89 final = len(input_hist)
89 final = len(input_hist)
90 init = max(1,final-default_length)
90 init = max(1,final-default_length)
91 elif len(args) == 1:
91 elif len(args) == 1:
92 final = len(input_hist)
92 final = len(input_hist)
93 init = max(1,final-int(args[0]))
93 init = max(1,final-int(args[0]))
94 elif len(args) == 2:
94 elif len(args) == 2:
95 init,final = map(int,args)
95 init,final = map(int,args)
96 else:
96 else:
97 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
97 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
98 print self.magic_hist.__doc__
98 print self.magic_hist.__doc__
99 return
99 return
100 width = len(str(final))
100 width = len(str(final))
101 line_sep = ['','\n']
101 line_sep = ['','\n']
102 print_nums = not opts.has_key('n')
102 print_nums = not opts.has_key('n')
103
103
104 found = False
104 found = False
105 if pattern is not None:
105 if pattern is not None:
106 sh = self.shadowhist.all()
106 sh = self.shadowhist.all()
107 for idx, s in sh:
107 for idx, s in sh:
108 if fnmatch.fnmatch(s, pattern):
108 if fnmatch.fnmatch(s, pattern):
109 print "0%d: %s" %(idx, s)
109 print "0%d: %s" %(idx, s)
110 found = True
110 found = True
111
111
112 if found:
112 if found:
113 print "==="
113 print "==="
114 print "shadow history ends, fetch by %rep <number> (must start with 0)"
114 print "shadow history ends, fetch by %rep <number> (must start with 0)"
115 print "=== start of normal history ==="
115 print "=== start of normal history ==="
116
116
117 for in_num in range(init,final):
117 for in_num in range(init,final):
118 inline = input_hist[in_num]
118 inline = input_hist[in_num]
119 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
119 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
120 continue
120 continue
121
121
122 multiline = int(inline.count('\n') > 1)
122 multiline = int(inline.count('\n') > 1)
123 if print_nums:
123 if print_nums:
124 print >> outfile, \
124 print >> outfile, \
125 '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
125 '%s:%s' % (str(in_num).ljust(width),line_sep[multiline]),
126 print >> outfile, inline,
126 print >> outfile, inline,
127
127
128 if close_at_end:
128 if close_at_end:
129 outfile.close()
129 outfile.close()
130
130
131
131
132 def magic_hist(self, parameter_s=''):
132 def magic_hist(self, parameter_s=''):
133 """Alternate name for %history."""
133 """Alternate name for %history."""
134 return self.magic_history(parameter_s)
134 return self.magic_history(parameter_s)
135
135
136
136
137 def rep_f(self, arg):
137 def rep_f(self, arg):
138 r""" Repeat a command, or get command to input line for editing
138 r""" Repeat a command, or get command to input line for editing
139
139
140 - %rep (no arguments):
140 - %rep (no arguments):
141
141
142 Place a string version of last computation result (stored in the special '_'
142 Place a string version of last computation result (stored in the special '_'
143 variable) to the next input prompt. Allows you to create elaborate command
143 variable) to the next input prompt. Allows you to create elaborate command
144 lines without using copy-paste::
144 lines without using copy-paste::
145
145
146 $ l = ["hei", "vaan"]
146 $ l = ["hei", "vaan"]
147 $ "".join(l)
147 $ "".join(l)
148 ==> heivaan
148 ==> heivaan
149 $ %rep
149 $ %rep
150 $ heivaan_ <== cursor blinking
150 $ heivaan_ <== cursor blinking
151
151
152 %rep 45
152 %rep 45
153
153
154 Place history line 45 to next input prompt. Use %hist to find out the
154 Place history line 45 to next input prompt. Use %hist to find out the
155 number.
155 number.
156
156
157 %rep 1-4 6-7 3
157 %rep 1-4 6-7 3
158
158
159 Repeat the specified lines immediately. Input slice syntax is the same as
159 Repeat the specified lines immediately. Input slice syntax is the same as
160 in %macro and %save.
160 in %macro and %save.
161
161
162 %rep foo
162 %rep foo
163
163
164 Place the most recent line that has the substring "foo" to next input.
164 Place the most recent line that has the substring "foo" to next input.
165 (e.g. 'svn ci -m foobar').
165 (e.g. 'svn ci -m foobar').
166 """
166 """
167
167
168 opts,args = self.parse_options(arg,'',mode='list')
168 opts,args = self.parse_options(arg,'',mode='list')
169 if not args:
169 if not args:
170 self.set_next_input(str(self.user_ns["_"]))
170 self.set_next_input(str(self.user_ns["_"]))
171 return
171 return
172
172
173 if len(args) == 1 and not '-' in args[0]:
173 if len(args) == 1 and not '-' in args[0]:
174 arg = args[0]
174 arg = args[0]
175 if len(arg) > 1 and arg.startswith('0'):
175 if len(arg) > 1 and arg.startswith('0'):
176 # get from shadow hist
176 # get from shadow hist
177 num = int(arg[1:])
177 num = int(arg[1:])
178 line = self.shadowhist.get(num)
178 line = self.shadowhist.get(num)
179 self.set_next_input(str(line))
179 self.set_next_input(str(line))
180 return
180 return
181 try:
181 try:
182 num = int(args[0])
182 num = int(args[0])
183 self.set_next_input(str(self.input_hist_raw[num]).rstrip())
183 self.set_next_input(str(self.input_hist_raw[num]).rstrip())
184 return
184 return
185 except ValueError:
185 except ValueError:
186 pass
186 pass
187
187
188 for h in reversed(self.input_hist_raw):
188 for h in reversed(self.input_hist_raw):
189 if 'rep' in h:
189 if 'rep' in h:
190 continue
190 continue
191 if fnmatch.fnmatch(h,'*' + arg + '*'):
191 if fnmatch.fnmatch(h,'*' + arg + '*'):
192 self.set_next_input(str(h).rstrip())
192 self.set_next_input(str(h).rstrip())
193 return
193 return
194
194
195 try:
195 try:
196 lines = self.extract_input_slices(args, True)
196 lines = self.extract_input_slices(args, True)
197 print "lines",lines
197 print "lines",lines
198 self.runlines(lines)
198 self.runlines(lines)
199 except ValueError:
199 except ValueError:
200 print "Not found in recent history:", args
200 print "Not found in recent history:", args
201
201
202
202
203 _sentinel = object()
203 _sentinel = object()
204
204
205 class ShadowHist(object):
205 class ShadowHist(object):
206 def __init__(self,db):
206 def __init__(self,db):
207 # cmd => idx mapping
207 # cmd => idx mapping
208 self.curidx = 0
208 self.curidx = 0
209 self.db = db
209 self.db = db
210 self.disabled = False
210 self.disabled = False
211
211
212 def inc_idx(self):
212 def inc_idx(self):
213 idx = self.db.get('shadowhist_idx', 1)
213 idx = self.db.get('shadowhist_idx', 1)
214 self.db['shadowhist_idx'] = idx + 1
214 self.db['shadowhist_idx'] = idx + 1
215 return idx
215 return idx
216
216
217 def add(self, ent):
217 def add(self, ent):
218 if self.disabled:
218 if self.disabled:
219 return
219 return
220 try:
220 try:
221 old = self.db.hget('shadowhist', ent, _sentinel)
221 old = self.db.hget('shadowhist', ent, _sentinel)
222 if old is not _sentinel:
222 if old is not _sentinel:
223 return
223 return
224 newidx = self.inc_idx()
224 newidx = self.inc_idx()
225 #print "new",newidx # dbg
225 #print "new",newidx # dbg
226 self.db.hset('shadowhist',ent, newidx)
226 self.db.hset('shadowhist',ent, newidx)
227 except:
227 except:
228 ipapi.get().showtraceback()
228 ipapi.get().showtraceback()
229 print "WARNING: disabling shadow history"
229 print "WARNING: disabling shadow history"
230 self.disabled = True
230 self.disabled = True
231
231
232 def all(self):
232 def all(self):
233 d = self.db.hdict('shadowhist')
233 d = self.db.hdict('shadowhist')
234 items = [(i,s) for (s,i) in d.items()]
234 items = [(i,s) for (s,i) in d.items()]
235 items.sort()
235 items.sort()
236 return items
236 return items
237
237
238 def get(self, idx):
238 def get(self, idx):
239 all = self.all()
239 all = self.all()
240
240
241 for k, v in all:
241 for k, v in all:
242 #print k,v
242 #print k,v
243 if k == idx:
243 if k == idx:
244 return v
244 return v
245
245
246
246
247 def init_ipython(ip):
247 def init_ipython(ip):
248 import ipy_completers
248 # XXX - ipy_completers are in quarantine, need to be updated to new apis
249 #import ipy_completers
249
250
250 ip.define_magic("rep",rep_f)
251 ip.define_magic("rep",rep_f)
251 ip.define_magic("hist",magic_hist)
252 ip.define_magic("hist",magic_hist)
252 ip.define_magic("history",magic_history)
253 ip.define_magic("history",magic_history)
253
254
254 ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
255 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,587 +1,582 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The :class:`~IPython.core.application.Application` object for the command
4 The :class:`~IPython.core.application.Application` object for the command
5 line :command:`ipython` program.
5 line :command:`ipython` program.
6
6
7 Authors:
7 Authors:
8
8
9 * Brian Granger
9 * Brian Granger
10 * Fernando Perez
10 * Fernando Perez
11
11
12 Notes
12 Notes
13 -----
13 -----
14 """
14 """
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008-2009 The IPython Development Team
17 # Copyright (C) 2008-2009 The IPython Development Team
18 #
18 #
19 # Distributed under the terms of the BSD License. The full license is in
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Imports
24 # Imports
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 import logging
27 import logging
28 import os
28 import os
29 import sys
29 import sys
30
30
31 from IPython.core import release
31 from IPython.core import release
32 from IPython.core.application import Application, BaseAppArgParseConfigLoader
32 from IPython.core.application import Application, BaseAppArgParseConfigLoader
33 from IPython.core.error import UsageError
33 from IPython.core.error import UsageError
34 from IPython.core.iplib import InteractiveShell
34 from IPython.core.iplib import InteractiveShell
35 from IPython.core.pylabtools import pylab_activate
35 from IPython.core.pylabtools import pylab_activate
36 from IPython.config.loader import (
36 from IPython.config.loader import (
37 NoConfigDefault,
37 NoConfigDefault,
38 Config,
38 Config,
39 PyFileConfigLoader
39 PyFileConfigLoader
40 )
40 )
41 from IPython.lib import inputhook
41 from IPython.lib import inputhook
42 from IPython.utils.genutils import filefind, get_ipython_dir
42 from IPython.utils.genutils import filefind, get_ipython_dir
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Utilities and helpers
45 # Utilities and helpers
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 ipython_desc = """
48 ipython_desc = """
49 A Python shell with automatic history (input and output), dynamic object
49 A Python shell with automatic history (input and output), dynamic object
50 introspection, easier configuration, command completion, access to the system
50 introspection, easier configuration, command completion, access to the system
51 shell and more.
51 shell and more.
52 """
52 """
53
53
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55 # Main classes and functions
55 # Main classes and functions
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57
57
58 cl_args = (
58 cl_args = (
59 (('--autocall',), dict(
59 (('--autocall',), dict(
60 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
60 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
61 help='Set the autocall value (0,1,2).',
61 help='Set the autocall value (0,1,2).',
62 metavar='InteractiveShell.autocall')
62 metavar='InteractiveShell.autocall')
63 ),
63 ),
64 (('--autoindent',), dict(
64 (('--autoindent',), dict(
65 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
65 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
66 help='Turn on autoindenting.')
66 help='Turn on autoindenting.')
67 ),
67 ),
68 (('--no-autoindent',), dict(
68 (('--no-autoindent',), dict(
69 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
69 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
70 help='Turn off autoindenting.')
70 help='Turn off autoindenting.')
71 ),
71 ),
72 (('--automagic',), dict(
72 (('--automagic',), dict(
73 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
73 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
74 help='Turn on the auto calling of magic commands.')
74 help='Turn on the auto calling of magic commands.')
75 ),
75 ),
76 (('--no-automagic',), dict(
76 (('--no-automagic',), dict(
77 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
77 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
78 help='Turn off the auto calling of magic commands.')
78 help='Turn off the auto calling of magic commands.')
79 ),
79 ),
80 (('--autoedit-syntax',), dict(
80 (('--autoedit-syntax',), dict(
81 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
81 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
82 help='Turn on auto editing of files with syntax errors.')
82 help='Turn on auto editing of files with syntax errors.')
83 ),
83 ),
84 (('--no-autoedit-syntax',), dict(
84 (('--no-autoedit-syntax',), dict(
85 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
85 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
86 help='Turn off auto editing of files with syntax errors.')
86 help='Turn off auto editing of files with syntax errors.')
87 ),
87 ),
88 (('--banner',), dict(
88 (('--banner',), dict(
89 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
89 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
90 help='Display a banner upon starting IPython.')
90 help='Display a banner upon starting IPython.')
91 ),
91 ),
92 (('--no-banner',), dict(
92 (('--no-banner',), dict(
93 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
93 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
94 help="Don't display a banner upon starting IPython.")
94 help="Don't display a banner upon starting IPython.")
95 ),
95 ),
96 (('--cache-size',), dict(
96 (('--cache-size',), dict(
97 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
97 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
98 help="Set the size of the output cache.",
98 help="Set the size of the output cache.",
99 metavar='InteractiveShell.cache_size')
99 metavar='InteractiveShell.cache_size')
100 ),
100 ),
101 (('--classic',), dict(
101 (('--classic',), dict(
102 action='store_true', dest='Global.classic', default=NoConfigDefault,
102 action='store_true', dest='Global.classic', default=NoConfigDefault,
103 help="Gives IPython a similar feel to the classic Python prompt.")
103 help="Gives IPython a similar feel to the classic Python prompt.")
104 ),
104 ),
105 (('--colors',), dict(
105 (('--colors',), dict(
106 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
106 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
107 help="Set the color scheme (NoColor, Linux, and LightBG).",
107 help="Set the color scheme (NoColor, Linux, and LightBG).",
108 metavar='InteractiveShell.colors')
108 metavar='InteractiveShell.colors')
109 ),
109 ),
110 (('--color-info',), dict(
110 (('--color-info',), dict(
111 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
111 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
112 help="Enable using colors for info related things.")
112 help="Enable using colors for info related things.")
113 ),
113 ),
114 (('--no-color-info',), dict(
114 (('--no-color-info',), dict(
115 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
115 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
116 help="Disable using colors for info related things.")
116 help="Disable using colors for info related things.")
117 ),
117 ),
118 (('--confirm-exit',), dict(
118 (('--confirm-exit',), dict(
119 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
119 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
120 help="Prompt the user when existing.")
120 help="Prompt the user when existing.")
121 ),
121 ),
122 (('--no-confirm-exit',), dict(
122 (('--no-confirm-exit',), dict(
123 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
123 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
124 help="Don't prompt the user when existing.")
124 help="Don't prompt the user when existing.")
125 ),
125 ),
126 (('--deep-reload',), dict(
126 (('--deep-reload',), dict(
127 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
127 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
128 help="Enable deep (recursive) reloading by default.")
128 help="Enable deep (recursive) reloading by default.")
129 ),
129 ),
130 (('--no-deep-reload',), dict(
130 (('--no-deep-reload',), dict(
131 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
131 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
132 help="Disable deep (recursive) reloading by default.")
132 help="Disable deep (recursive) reloading by default.")
133 ),
133 ),
134 (('--editor',), dict(
134 (('--editor',), dict(
135 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
135 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
136 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
136 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
137 metavar='InteractiveShell.editor')
137 metavar='InteractiveShell.editor')
138 ),
138 ),
139 (('--log','-l'), dict(
139 (('--log','-l'), dict(
140 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
140 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
141 help="Start logging to the default file (./ipython_log.py).")
141 help="Start logging to the default file (./ipython_log.py).")
142 ),
142 ),
143 (('--logfile','-lf'), dict(
143 (('--logfile','-lf'), dict(
144 type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
144 type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
145 help="Start logging to logfile.",
145 help="Start logging to logfile.",
146 metavar='InteractiveShell.logfile')
146 metavar='InteractiveShell.logfile')
147 ),
147 ),
148 (('--log-append','-la'), dict(
148 (('--log-append','-la'), dict(
149 type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
149 type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
150 help="Start logging to the give file in append mode.",
150 help="Start logging to the give file in append mode.",
151 metavar='InteractiveShell.logfile')
151 metavar='InteractiveShell.logfile')
152 ),
152 ),
153 (('--pdb',), dict(
153 (('--pdb',), dict(
154 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
154 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
155 help="Enable auto calling the pdb debugger after every exception.")
155 help="Enable auto calling the pdb debugger after every exception.")
156 ),
156 ),
157 (('--no-pdb',), dict(
157 (('--no-pdb',), dict(
158 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
158 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
159 help="Disable auto calling the pdb debugger after every exception.")
159 help="Disable auto calling the pdb debugger after every exception.")
160 ),
160 ),
161 (('--pprint',), dict(
161 (('--pprint',), dict(
162 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
162 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
163 help="Enable auto pretty printing of results.")
163 help="Enable auto pretty printing of results.")
164 ),
164 ),
165 (('--no-pprint',), dict(
165 (('--no-pprint',), dict(
166 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
166 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
167 help="Disable auto auto pretty printing of results.")
167 help="Disable auto auto pretty printing of results.")
168 ),
168 ),
169 (('--prompt-in1','-pi1'), dict(
169 (('--prompt-in1','-pi1'), dict(
170 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
170 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
171 help="Set the main input prompt ('In [\#]: ')",
171 help="Set the main input prompt ('In [\#]: ')",
172 metavar='InteractiveShell.prompt_in1')
172 metavar='InteractiveShell.prompt_in1')
173 ),
173 ),
174 (('--prompt-in2','-pi2'), dict(
174 (('--prompt-in2','-pi2'), dict(
175 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
175 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
176 help="Set the secondary input prompt (' .\D.: ')",
176 help="Set the secondary input prompt (' .\D.: ')",
177 metavar='InteractiveShell.prompt_in2')
177 metavar='InteractiveShell.prompt_in2')
178 ),
178 ),
179 (('--prompt-out','-po'), dict(
179 (('--prompt-out','-po'), dict(
180 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
180 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
181 help="Set the output prompt ('Out[\#]:')",
181 help="Set the output prompt ('Out[\#]:')",
182 metavar='InteractiveShell.prompt_out')
182 metavar='InteractiveShell.prompt_out')
183 ),
183 ),
184 (('--quick',), dict(
184 (('--quick',), dict(
185 action='store_true', dest='Global.quick', default=NoConfigDefault,
185 action='store_true', dest='Global.quick', default=NoConfigDefault,
186 help="Enable quick startup with no config files.")
186 help="Enable quick startup with no config files.")
187 ),
187 ),
188 (('--readline',), dict(
188 (('--readline',), dict(
189 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
189 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
190 help="Enable readline for command line usage.")
190 help="Enable readline for command line usage.")
191 ),
191 ),
192 (('--no-readline',), dict(
192 (('--no-readline',), dict(
193 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
193 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
194 help="Disable readline for command line usage.")
194 help="Disable readline for command line usage.")
195 ),
195 ),
196 (('--screen-length','-sl'), dict(
196 (('--screen-length','-sl'), dict(
197 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
197 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
198 help='Number of lines on screen, used to control printing of long strings.',
198 help='Number of lines on screen, used to control printing of long strings.',
199 metavar='InteractiveShell.screen_length')
199 metavar='InteractiveShell.screen_length')
200 ),
200 ),
201 (('--separate-in','-si'), dict(
201 (('--separate-in','-si'), dict(
202 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
202 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
203 help="Separator before input prompts. Default '\n'.",
203 help="Separator before input prompts. Default '\n'.",
204 metavar='InteractiveShell.separate_in')
204 metavar='InteractiveShell.separate_in')
205 ),
205 ),
206 (('--separate-out','-so'), dict(
206 (('--separate-out','-so'), dict(
207 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
207 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
208 help="Separator before output prompts. Default 0 (nothing).",
208 help="Separator before output prompts. Default 0 (nothing).",
209 metavar='InteractiveShell.separate_out')
209 metavar='InteractiveShell.separate_out')
210 ),
210 ),
211 (('--separate-out2','-so2'), dict(
211 (('--separate-out2','-so2'), dict(
212 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
212 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
213 help="Separator after output prompts. Default 0 (nonight).",
213 help="Separator after output prompts. Default 0 (nonight).",
214 metavar='InteractiveShell.separate_out2')
214 metavar='InteractiveShell.separate_out2')
215 ),
215 ),
216 (('-no-sep',), dict(
216 (('-no-sep',), dict(
217 action='store_true', dest='Global.nosep', default=NoConfigDefault,
217 action='store_true', dest='Global.nosep', default=NoConfigDefault,
218 help="Eliminate all spacing between prompts.")
218 help="Eliminate all spacing between prompts.")
219 ),
219 ),
220 (('--term-title',), dict(
220 (('--term-title',), dict(
221 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
221 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
222 help="Enable auto setting the terminal title.")
222 help="Enable auto setting the terminal title.")
223 ),
223 ),
224 (('--no-term-title',), dict(
224 (('--no-term-title',), dict(
225 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
225 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
226 help="Disable auto setting the terminal title.")
226 help="Disable auto setting the terminal title.")
227 ),
227 ),
228 (('--xmode',), dict(
228 (('--xmode',), dict(
229 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
229 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
230 help="Exception mode ('Plain','Context','Verbose')",
230 help="Exception mode ('Plain','Context','Verbose')",
231 metavar='InteractiveShell.xmode')
231 metavar='InteractiveShell.xmode')
232 ),
232 ),
233 (('--ext',), dict(
233 (('--ext',), dict(
234 type=str, dest='Global.extra_extension', default=NoConfigDefault,
234 type=str, dest='Global.extra_extension', default=NoConfigDefault,
235 help="The dotted module name of an IPython extension to load.",
235 help="The dotted module name of an IPython extension to load.",
236 metavar='Global.extra_extension')
236 metavar='Global.extra_extension')
237 ),
237 ),
238 (('-c',), dict(
238 (('-c',), dict(
239 type=str, dest='Global.code_to_run', default=NoConfigDefault,
239 type=str, dest='Global.code_to_run', default=NoConfigDefault,
240 help="Execute the given command string.",
240 help="Execute the given command string.",
241 metavar='Global.code_to_run')
241 metavar='Global.code_to_run')
242 ),
242 ),
243 (('-i',), dict(
243 (('-i',), dict(
244 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
244 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
245 help="If running code from the command line, become interactive afterwards.")
245 help="If running code from the command line, become interactive afterwards.")
246 ),
246 ),
247
247
248 # Options to start with GUI control enabled from the beginning
248 # Options to start with GUI control enabled from the beginning
249 (('--gui',), dict(
249 (('--gui',), dict(
250 type=str, dest='Global.gui', default=NoConfigDefault,
250 type=str, dest='Global.gui', default=NoConfigDefault,
251 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
251 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
252 metavar='gui-mode')
252 metavar='gui-mode')
253 ),
253 ),
254
254
255 (('--pylab',), dict(
255 (('--pylab','-pylab'), dict(
256 type=str, dest='Global.pylab', default=NoConfigDefault,
256 type=str, dest='Global.pylab', default=NoConfigDefault,
257 nargs='?', const='auto', metavar='gui-mode',
257 nargs='?', const='auto', metavar='gui-mode',
258 help="Pre-load matplotlib and numpy for interactive use. "+
258 help="Pre-load matplotlib and numpy for interactive use. "+
259 "If no value is given, the gui backend is matplotlib's, else use "+
259 "If no value is given, the gui backend is matplotlib's, else use "+
260 "one of: ['tk', 'qt', 'wx', 'gtk'].")
260 "one of: ['tk', 'qt', 'wx', 'gtk'].")
261 ),
261 ),
262
262
263 # Legacy GUI options. Leave them in for backwards compatibility, but the
263 # Legacy GUI options. Leave them in for backwards compatibility, but the
264 # 'thread' names are really a misnomer now.
264 # 'thread' names are really a misnomer now.
265 (('--wthread','-wthread'), dict(
265 (('--wthread','-wthread'), dict(
266 action='store_true', dest='Global.wthread', default=NoConfigDefault,
266 action='store_true', dest='Global.wthread', default=NoConfigDefault,
267 help="Enable wxPython event loop integration "+
267 help="Enable wxPython event loop integration "+
268 "(DEPRECATED, use --gui wx)")
268 "(DEPRECATED, use --gui wx)")
269 ),
269 ),
270 (('--q4thread','--qthread','-q4thread','-qthread'), dict(
270 (('--q4thread','--qthread','-q4thread','-qthread'), dict(
271 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
271 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
272 help="Enable Qt4 event loop integration. Qt3 is no longer supported. "+
272 help="Enable Qt4 event loop integration. Qt3 is no longer supported. "+
273 "(DEPRECATED, use --gui qt)")
273 "(DEPRECATED, use --gui qt)")
274 ),
274 ),
275 (('--gthread','-gthread'), dict(
275 (('--gthread','-gthread'), dict(
276 action='store_true', dest='Global.gthread', default=NoConfigDefault,
276 action='store_true', dest='Global.gthread', default=NoConfigDefault,
277 help="Enable GTK event loop integration. "+
277 help="Enable GTK event loop integration. "+
278 "(DEPRECATED, use --gui gtk)")
278 "(DEPRECATED, use --gui gtk)")
279 ),
279 ),
280 )
280 )
281
281
282
282
283 class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader):
283 class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader):
284
284
285 arguments = cl_args
285 arguments = cl_args
286
286
287 def load_config(self):
288 """Do actions just before loading the command line config."""
289
290 # Special hack: there are countless uses of 'ipython -pylab' (with one
291 # dash) in the wild, including in printed books. Since argparse does
292 # will interpret -pylab as '-p ylab', sending us in a search for a
293 # profile named 'ylab', instead we special-case here -pylab as the
294 # first or second option only (this is how old ipython used to work)
295 # and convert this use to --pylab. Ugly, but needed for this one
296 # very widely used case.
297 firstargs = sys.argv[:3]
298 try:
299 idx = firstargs.index('-pylab')
300 except ValueError:
301 pass
302 else:
303 sys.argv[idx] = '--pylab'
304 return super(IPythonAppCLConfigLoader, self).load_config()
305
287
306 default_config_file_name = u'ipython_config.py'
288 default_config_file_name = u'ipython_config.py'
307
289
308
290
309 class IPythonApp(Application):
291 class IPythonApp(Application):
310 name = u'ipython'
292 name = u'ipython'
311 description = 'IPython: an enhanced interactive Python shell.'
293 description = 'IPython: an enhanced interactive Python shell.'
312 config_file_name = default_config_file_name
294 config_file_name = default_config_file_name
313
295
296 def __init__(self, argv=None, **shell_params):
297 """Create a new IPythonApp.
298
299 Parameters
300 ----------
301 argv : optional, list
302 If given, used as the command-line argv environment to read arguments
303 from.
304
305 shell_params : optional, dict
306 All other keywords are passed to the :class:`iplib.InteractiveShell`
307 constructor.
308 """
309 super(IPythonApp, self).__init__(argv)
310 self.shell_params = shell_params
311
314 def create_default_config(self):
312 def create_default_config(self):
315 super(IPythonApp, self).create_default_config()
313 super(IPythonApp, self).create_default_config()
316 # Eliminate multiple lookups
314 # Eliminate multiple lookups
317 Global = self.default_config.Global
315 Global = self.default_config.Global
318
316
319 # Set all default values
317 # Set all default values
320 Global.display_banner = True
318 Global.display_banner = True
321
319
322 # If the -c flag is given or a file is given to run at the cmd line
320 # If the -c flag is given or a file is given to run at the cmd line
323 # like "ipython foo.py", normally we exit without starting the main
321 # like "ipython foo.py", normally we exit without starting the main
324 # loop. The force_interact config variable allows a user to override
322 # loop. The force_interact config variable allows a user to override
325 # this and interact. It is also set by the -i cmd line flag, just
323 # this and interact. It is also set by the -i cmd line flag, just
326 # like Python.
324 # like Python.
327 Global.force_interact = False
325 Global.force_interact = False
328
326
329 # By default always interact by starting the IPython mainloop.
327 # By default always interact by starting the IPython mainloop.
330 Global.interact = True
328 Global.interact = True
331
329
332 # No GUI integration by default
330 # No GUI integration by default
333 Global.gui = False
331 Global.gui = False
334 # Pylab off by default
332 # Pylab off by default
335 Global.pylab = False
333 Global.pylab = False
336
334
337 # Deprecated versions of gui support that used threading, we support
335 # Deprecated versions of gui support that used threading, we support
338 # them just for bacwards compatibility as an alternate spelling for
336 # them just for bacwards compatibility as an alternate spelling for
339 # '--gui X'
337 # '--gui X'
340 Global.qthread = False
338 Global.qthread = False
341 Global.q4thread = False
339 Global.q4thread = False
342 Global.wthread = False
340 Global.wthread = False
343 Global.gthread = False
341 Global.gthread = False
344
342
345 def create_command_line_config(self):
343 def create_command_line_config(self):
346 """Create and return a command line config loader."""
344 """Create and return a command line config loader."""
347 return IPythonAppCLConfigLoader(self.argv,
345 return IPythonAppCLConfigLoader(self.argv,
348 description=self.description,
346 description=self.description,
349 version=release.version
347 version=release.version
350 )
348 )
351
349
352
353 def load_file_config(self):
350 def load_file_config(self):
354 if hasattr(self.command_line_config.Global, 'quick'):
351 if hasattr(self.command_line_config.Global, 'quick'):
355 if self.command_line_config.Global.quick:
352 if self.command_line_config.Global.quick:
356 self.file_config = Config()
353 self.file_config = Config()
357 return
354 return
358 super(IPythonApp, self).load_file_config()
355 super(IPythonApp, self).load_file_config()
359
356
360 def post_load_file_config(self):
357 def post_load_file_config(self):
361 if hasattr(self.command_line_config.Global, 'extra_extension'):
358 if hasattr(self.command_line_config.Global, 'extra_extension'):
362 if not hasattr(self.file_config.Global, 'extensions'):
359 if not hasattr(self.file_config.Global, 'extensions'):
363 self.file_config.Global.extensions = []
360 self.file_config.Global.extensions = []
364 self.file_config.Global.extensions.append(
361 self.file_config.Global.extensions.append(
365 self.command_line_config.Global.extra_extension)
362 self.command_line_config.Global.extra_extension)
366 del self.command_line_config.Global.extra_extension
363 del self.command_line_config.Global.extra_extension
367
364
368 def pre_construct(self):
365 def pre_construct(self):
369 config = self.master_config
366 config = self.master_config
370
367
371 if hasattr(config.Global, 'classic'):
368 if hasattr(config.Global, 'classic'):
372 if config.Global.classic:
369 if config.Global.classic:
373 config.InteractiveShell.cache_size = 0
370 config.InteractiveShell.cache_size = 0
374 config.InteractiveShell.pprint = 0
371 config.InteractiveShell.pprint = 0
375 config.InteractiveShell.prompt_in1 = '>>> '
372 config.InteractiveShell.prompt_in1 = '>>> '
376 config.InteractiveShell.prompt_in2 = '... '
373 config.InteractiveShell.prompt_in2 = '... '
377 config.InteractiveShell.prompt_out = ''
374 config.InteractiveShell.prompt_out = ''
378 config.InteractiveShell.separate_in = \
375 config.InteractiveShell.separate_in = \
379 config.InteractiveShell.separate_out = \
376 config.InteractiveShell.separate_out = \
380 config.InteractiveShell.separate_out2 = ''
377 config.InteractiveShell.separate_out2 = ''
381 config.InteractiveShell.colors = 'NoColor'
378 config.InteractiveShell.colors = 'NoColor'
382 config.InteractiveShell.xmode = 'Plain'
379 config.InteractiveShell.xmode = 'Plain'
383
380
384 if hasattr(config.Global, 'nosep'):
381 if hasattr(config.Global, 'nosep'):
385 if config.Global.nosep:
382 if config.Global.nosep:
386 config.InteractiveShell.separate_in = \
383 config.InteractiveShell.separate_in = \
387 config.InteractiveShell.separate_out = \
384 config.InteractiveShell.separate_out = \
388 config.InteractiveShell.separate_out2 = ''
385 config.InteractiveShell.separate_out2 = ''
389
386
390 # if there is code of files to run from the cmd line, don't interact
387 # if there is code of files to run from the cmd line, don't interact
391 # unless the -i flag (Global.force_interact) is true.
388 # unless the -i flag (Global.force_interact) is true.
392 code_to_run = config.Global.get('code_to_run','')
389 code_to_run = config.Global.get('code_to_run','')
393 file_to_run = False
390 file_to_run = False
394 if len(self.extra_args)>=1:
391 if len(self.extra_args)>=1:
395 if self.extra_args[0]:
392 if self.extra_args[0]:
396 file_to_run = True
393 file_to_run = True
397 if file_to_run or code_to_run:
394 if file_to_run or code_to_run:
398 if not config.Global.force_interact:
395 if not config.Global.force_interact:
399 config.Global.interact = False
396 config.Global.interact = False
400
397
401 def construct(self):
398 def construct(self):
402 # I am a little hesitant to put these into InteractiveShell itself.
399 # I am a little hesitant to put these into InteractiveShell itself.
403 # But that might be the place for them
400 # But that might be the place for them
404 sys.path.insert(0, '')
401 sys.path.insert(0, '')
405
402
406 # Create an InteractiveShell instance
403 # Create an InteractiveShell instance
407 self.shell = InteractiveShell(
404 self.shell = InteractiveShell(None, self.master_config,
408 parent=None,
405 **self.shell_params )
409 config=self.master_config
410 )
411
406
412 def post_construct(self):
407 def post_construct(self):
413 """Do actions after construct, but before starting the app."""
408 """Do actions after construct, but before starting the app."""
414 config = self.master_config
409 config = self.master_config
415
410
416 # shell.display_banner should always be False for the terminal
411 # shell.display_banner should always be False for the terminal
417 # based app, because we call shell.show_banner() by hand below
412 # based app, because we call shell.show_banner() by hand below
418 # so the banner shows *before* all extension loading stuff.
413 # so the banner shows *before* all extension loading stuff.
419 self.shell.display_banner = False
414 self.shell.display_banner = False
420
415
421 if config.Global.display_banner and \
416 if config.Global.display_banner and \
422 config.Global.interact:
417 config.Global.interact:
423 self.shell.show_banner()
418 self.shell.show_banner()
424
419
425 # Make sure there is a space below the banner.
420 # Make sure there is a space below the banner.
426 if self.log_level <= logging.INFO: print
421 if self.log_level <= logging.INFO: print
427
422
428 # Now a variety of things that happen after the banner is printed.
423 # Now a variety of things that happen after the banner is printed.
429 self._enable_gui_pylab()
424 self._enable_gui_pylab()
430 self._load_extensions()
425 self._load_extensions()
431 self._run_exec_lines()
426 self._run_exec_lines()
432 self._run_exec_files()
427 self._run_exec_files()
433 self._run_cmd_line_code()
428 self._run_cmd_line_code()
434 self._configure_xmode()
429 self._configure_xmode()
435
430
436 def _enable_gui_pylab(self):
431 def _enable_gui_pylab(self):
437 """Enable GUI event loop integration, taking pylab into account."""
432 """Enable GUI event loop integration, taking pylab into account."""
438 Global = self.master_config.Global
433 Global = self.master_config.Global
439
434
440 # Select which gui to use
435 # Select which gui to use
441 if Global.gui:
436 if Global.gui:
442 gui = Global.gui
437 gui = Global.gui
443 # The following are deprecated, but there's likely to be a lot of use
438 # The following are deprecated, but there's likely to be a lot of use
444 # of this form out there, so we might as well support it for now. But
439 # of this form out there, so we might as well support it for now. But
445 # the --gui option above takes precedence.
440 # the --gui option above takes precedence.
446 elif Global.wthread:
441 elif Global.wthread:
447 gui = inputhook.GUI_WX
442 gui = inputhook.GUI_WX
448 elif Global.qthread:
443 elif Global.qthread:
449 gui = inputhook.GUI_QT
444 gui = inputhook.GUI_QT
450 elif Global.gthread:
445 elif Global.gthread:
451 gui = inputhook.GUI_GTK
446 gui = inputhook.GUI_GTK
452 else:
447 else:
453 gui = None
448 gui = None
454
449
455 # Using --pylab will also require gui activation, though which toolkit
450 # Using --pylab will also require gui activation, though which toolkit
456 # to use may be chosen automatically based on mpl configuration.
451 # to use may be chosen automatically based on mpl configuration.
457 if Global.pylab:
452 if Global.pylab:
458 activate = self.shell.enable_pylab
453 activate = self.shell.enable_pylab
459 if Global.pylab == 'auto':
454 if Global.pylab == 'auto':
460 gui = None
455 gui = None
461 else:
456 else:
462 gui = Global.pylab
457 gui = Global.pylab
463 else:
458 else:
464 # Enable only GUI integration, no pylab
459 # Enable only GUI integration, no pylab
465 activate = inputhook.enable_gui
460 activate = inputhook.enable_gui
466
461
467 if gui or Global.pylab:
462 if gui or Global.pylab:
468 try:
463 try:
469 self.log.info("Enabling GUI event loop integration, "
464 self.log.info("Enabling GUI event loop integration, "
470 "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
465 "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
471 activate(gui)
466 activate(gui)
472 except:
467 except:
473 self.log.warn("Error in enabling GUI event loop integration:")
468 self.log.warn("Error in enabling GUI event loop integration:")
474 self.shell.showtraceback()
469 self.shell.showtraceback()
475
470
476 def _load_extensions(self):
471 def _load_extensions(self):
477 """Load all IPython extensions in Global.extensions.
472 """Load all IPython extensions in Global.extensions.
478
473
479 This uses the :meth:`InteractiveShell.load_extensions` to load all
474 This uses the :meth:`InteractiveShell.load_extensions` to load all
480 the extensions listed in ``self.master_config.Global.extensions``.
475 the extensions listed in ``self.master_config.Global.extensions``.
481 """
476 """
482 try:
477 try:
483 if hasattr(self.master_config.Global, 'extensions'):
478 if hasattr(self.master_config.Global, 'extensions'):
484 self.log.debug("Loading IPython extensions...")
479 self.log.debug("Loading IPython extensions...")
485 extensions = self.master_config.Global.extensions
480 extensions = self.master_config.Global.extensions
486 for ext in extensions:
481 for ext in extensions:
487 try:
482 try:
488 self.log.info("Loading IPython extension: %s" % ext)
483 self.log.info("Loading IPython extension: %s" % ext)
489 self.shell.load_extension(ext)
484 self.shell.load_extension(ext)
490 except:
485 except:
491 self.log.warn("Error in loading extension: %s" % ext)
486 self.log.warn("Error in loading extension: %s" % ext)
492 self.shell.showtraceback()
487 self.shell.showtraceback()
493 except:
488 except:
494 self.log.warn("Unknown error in loading extensions:")
489 self.log.warn("Unknown error in loading extensions:")
495 self.shell.showtraceback()
490 self.shell.showtraceback()
496
491
497 def _run_exec_lines(self):
492 def _run_exec_lines(self):
498 """Run lines of code in Global.exec_lines in the user's namespace."""
493 """Run lines of code in Global.exec_lines in the user's namespace."""
499 try:
494 try:
500 if hasattr(self.master_config.Global, 'exec_lines'):
495 if hasattr(self.master_config.Global, 'exec_lines'):
501 self.log.debug("Running code from Global.exec_lines...")
496 self.log.debug("Running code from Global.exec_lines...")
502 exec_lines = self.master_config.Global.exec_lines
497 exec_lines = self.master_config.Global.exec_lines
503 for line in exec_lines:
498 for line in exec_lines:
504 try:
499 try:
505 self.log.info("Running code in user namespace: %s" % line)
500 self.log.info("Running code in user namespace: %s" % line)
506 self.shell.runlines(line)
501 self.shell.runlines(line)
507 except:
502 except:
508 self.log.warn("Error in executing line in user namespace: %s" % line)
503 self.log.warn("Error in executing line in user namespace: %s" % line)
509 self.shell.showtraceback()
504 self.shell.showtraceback()
510 except:
505 except:
511 self.log.warn("Unknown error in handling Global.exec_lines:")
506 self.log.warn("Unknown error in handling Global.exec_lines:")
512 self.shell.showtraceback()
507 self.shell.showtraceback()
513
508
514 def _exec_file(self, fname):
509 def _exec_file(self, fname):
515 full_filename = filefind(fname, [u'.', self.ipython_dir])
510 full_filename = filefind(fname, [u'.', self.ipython_dir])
516 if os.path.isfile(full_filename):
511 if os.path.isfile(full_filename):
517 if full_filename.endswith(u'.py'):
512 if full_filename.endswith(u'.py'):
518 self.log.info("Running file in user namespace: %s" % full_filename)
513 self.log.info("Running file in user namespace: %s" % full_filename)
519 self.shell.safe_execfile(full_filename, self.shell.user_ns)
514 self.shell.safe_execfile(full_filename, self.shell.user_ns)
520 elif full_filename.endswith('.ipy'):
515 elif full_filename.endswith('.ipy'):
521 self.log.info("Running file in user namespace: %s" % full_filename)
516 self.log.info("Running file in user namespace: %s" % full_filename)
522 self.shell.safe_execfile_ipy(full_filename)
517 self.shell.safe_execfile_ipy(full_filename)
523 else:
518 else:
524 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
519 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
525
520
526 def _run_exec_files(self):
521 def _run_exec_files(self):
527 try:
522 try:
528 if hasattr(self.master_config.Global, 'exec_files'):
523 if hasattr(self.master_config.Global, 'exec_files'):
529 self.log.debug("Running files in Global.exec_files...")
524 self.log.debug("Running files in Global.exec_files...")
530 exec_files = self.master_config.Global.exec_files
525 exec_files = self.master_config.Global.exec_files
531 for fname in exec_files:
526 for fname in exec_files:
532 self._exec_file(fname)
527 self._exec_file(fname)
533 except:
528 except:
534 self.log.warn("Unknown error in handling Global.exec_files:")
529 self.log.warn("Unknown error in handling Global.exec_files:")
535 self.shell.showtraceback()
530 self.shell.showtraceback()
536
531
537 def _run_cmd_line_code(self):
532 def _run_cmd_line_code(self):
538 if hasattr(self.master_config.Global, 'code_to_run'):
533 if hasattr(self.master_config.Global, 'code_to_run'):
539 line = self.master_config.Global.code_to_run
534 line = self.master_config.Global.code_to_run
540 try:
535 try:
541 self.log.info("Running code given at command line (-c): %s" % line)
536 self.log.info("Running code given at command line (-c): %s" % line)
542 self.shell.runlines(line)
537 self.shell.runlines(line)
543 except:
538 except:
544 self.log.warn("Error in executing line in user namespace: %s" % line)
539 self.log.warn("Error in executing line in user namespace: %s" % line)
545 self.shell.showtraceback()
540 self.shell.showtraceback()
546 return
541 return
547 # Like Python itself, ignore the second if the first of these is present
542 # Like Python itself, ignore the second if the first of these is present
548 try:
543 try:
549 fname = self.extra_args[0]
544 fname = self.extra_args[0]
550 except:
545 except:
551 pass
546 pass
552 else:
547 else:
553 try:
548 try:
554 self._exec_file(fname)
549 self._exec_file(fname)
555 except:
550 except:
556 self.log.warn("Error in executing file in user namespace: %s" % fname)
551 self.log.warn("Error in executing file in user namespace: %s" % fname)
557 self.shell.showtraceback()
552 self.shell.showtraceback()
558
553
559 def _configure_xmode(self):
554 def _configure_xmode(self):
560 # XXX - shouldn't this be read from the config? I'm still a little
555 # XXX - shouldn't this be read from the config? I'm still a little
561 # lost with all the details of handling the new config guys...
556 # lost with all the details of handling the new config guys...
562 self.shell.InteractiveTB.set_mode(mode=self.shell.xmode)
557 self.shell.InteractiveTB.set_mode(mode=self.shell.xmode)
563
558
564 def start_app(self):
559 def start_app(self):
565 if self.master_config.Global.interact:
560 if self.master_config.Global.interact:
566 self.log.debug("Starting IPython's mainloop...")
561 self.log.debug("Starting IPython's mainloop...")
567 self.shell.mainloop()
562 self.shell.mainloop()
568 else:
563 else:
569 self.log.debug("IPython not interactive, start_app is no-op...")
564 self.log.debug("IPython not interactive, start_app is no-op...")
570
565
571
566
572 def load_default_config(ipython_dir=None):
567 def load_default_config(ipython_dir=None):
573 """Load the default config file from the default ipython_dir.
568 """Load the default config file from the default ipython_dir.
574
569
575 This is useful for embedded shells.
570 This is useful for embedded shells.
576 """
571 """
577 if ipython_dir is None:
572 if ipython_dir is None:
578 ipython_dir = get_ipython_dir()
573 ipython_dir = get_ipython_dir()
579 cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
574 cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
580 config = cl.load_config()
575 config = cl.load_config()
581 return config
576 return config
582
577
583
578
584 def launch_new_instance():
579 def launch_new_instance():
585 """Create and run a full blown IPython instance"""
580 """Create and run a full blown IPython instance"""
586 app = IPythonApp()
581 app = IPythonApp()
587 app.start()
582 app.start()
@@ -1,2525 +1,2526 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Main IPython Component
3 Main IPython Component
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from __future__ import with_statement
19 from __future__ import with_statement
20
20
21 import __builtin__
21 import __builtin__
22 import StringIO
22 import StringIO
23 import bdb
23 import bdb
24 import codeop
24 import codeop
25 import exceptions
25 import exceptions
26 import new
26 import new
27 import os
27 import os
28 import re
28 import re
29 import string
29 import string
30 import sys
30 import sys
31 import tempfile
31 import tempfile
32 from contextlib import nested
32 from contextlib import nested
33
33
34 from IPython.core import debugger, oinspect
34 from IPython.core import debugger, oinspect
35 from IPython.core import history as ipcorehist
35 from IPython.core import history as ipcorehist
36 from IPython.core import prefilter
36 from IPython.core import prefilter
37 from IPython.core import shadowns
37 from IPython.core import shadowns
38 from IPython.core import ultratb
38 from IPython.core import ultratb
39 from IPython.core.alias import AliasManager
39 from IPython.core.alias import AliasManager
40 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.component import Component
41 from IPython.core.component import Component
42 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.display_trap import DisplayTrap
43 from IPython.core.error import TryNext, UsageError
43 from IPython.core.error import TryNext, UsageError
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.logger import Logger
45 from IPython.core.logger import Logger
46 from IPython.core.magic import Magic
46 from IPython.core.magic import Magic
47 from IPython.core.prefilter import PrefilterManager
47 from IPython.core.prefilter import PrefilterManager
48 from IPython.core.prompts import CachedOutput
48 from IPython.core.prompts import CachedOutput
49 from IPython.core.pylabtools import pylab_activate
49 from IPython.core.pylabtools import pylab_activate
50 from IPython.core.usage import interactive_usage, default_banner
50 from IPython.core.usage import interactive_usage, default_banner
51 from IPython.external.Itpl import ItplNS
51 from IPython.external.Itpl import ItplNS
52 from IPython.lib.inputhook import enable_gui
52 from IPython.lib.inputhook import enable_gui
53 from IPython.lib.backgroundjobs import BackgroundJobManager
53 from IPython.lib.backgroundjobs import BackgroundJobManager
54 from IPython.utils import PyColorize
54 from IPython.utils import PyColorize
55 from IPython.utils import pickleshare
55 from IPython.utils import pickleshare
56 from IPython.utils.genutils import get_ipython_dir
56 from IPython.utils.genutils import get_ipython_dir
57 from IPython.utils.ipstruct import Struct
57 from IPython.utils.ipstruct import Struct
58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
59 from IPython.utils.strdispatch import StrDispatch
59 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.syspathcontext import prepended_to_syspath
60 from IPython.utils.syspathcontext import prepended_to_syspath
61
61
62 # XXX - need to clean up this import * line
62 # XXX - need to clean up this import * line
63 from IPython.utils.genutils import *
63 from IPython.utils.genutils import *
64
64
65 # from IPython.utils import growl
65 # from IPython.utils import growl
66 # growl.start("IPython")
66 # growl.start("IPython")
67
67
68 from IPython.utils.traitlets import (
68 from IPython.utils.traitlets import (
69 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
69 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
70 )
70 )
71
71
72 #-----------------------------------------------------------------------------
72 #-----------------------------------------------------------------------------
73 # Globals
73 # Globals
74 #-----------------------------------------------------------------------------
74 #-----------------------------------------------------------------------------
75
75
76 # store the builtin raw_input globally, and use this always, in case user code
76 # store the builtin raw_input globally, and use this always, in case user code
77 # overwrites it (like wx.py.PyShell does)
77 # overwrites it (like wx.py.PyShell does)
78 raw_input_original = raw_input
78 raw_input_original = raw_input
79
79
80 # compiled regexps for autoindent management
80 # compiled regexps for autoindent management
81 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
81 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
82
82
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84 # Utilities
84 # Utilities
85 #-----------------------------------------------------------------------------
85 #-----------------------------------------------------------------------------
86
86
87 ini_spaces_re = re.compile(r'^(\s+)')
87 ini_spaces_re = re.compile(r'^(\s+)')
88
88
89
89
90 def num_ini_spaces(strng):
90 def num_ini_spaces(strng):
91 """Return the number of initial spaces in a string"""
91 """Return the number of initial spaces in a string"""
92
92
93 ini_spaces = ini_spaces_re.match(strng)
93 ini_spaces = ini_spaces_re.match(strng)
94 if ini_spaces:
94 if ini_spaces:
95 return ini_spaces.end()
95 return ini_spaces.end()
96 else:
96 else:
97 return 0
97 return 0
98
98
99
99
100 def softspace(file, newvalue):
100 def softspace(file, newvalue):
101 """Copied from code.py, to remove the dependency"""
101 """Copied from code.py, to remove the dependency"""
102
102
103 oldvalue = 0
103 oldvalue = 0
104 try:
104 try:
105 oldvalue = file.softspace
105 oldvalue = file.softspace
106 except AttributeError:
106 except AttributeError:
107 pass
107 pass
108 try:
108 try:
109 file.softspace = newvalue
109 file.softspace = newvalue
110 except (AttributeError, TypeError):
110 except (AttributeError, TypeError):
111 # "attribute-less object" or "read-only attributes"
111 # "attribute-less object" or "read-only attributes"
112 pass
112 pass
113 return oldvalue
113 return oldvalue
114
114
115
115
116 def no_op(*a, **kw): pass
116 def no_op(*a, **kw): pass
117
117
118 class SpaceInInput(exceptions.Exception): pass
118 class SpaceInInput(exceptions.Exception): pass
119
119
120 class Bunch: pass
120 class Bunch: pass
121
121
122 class InputList(list):
122 class InputList(list):
123 """Class to store user input.
123 """Class to store user input.
124
124
125 It's basically a list, but slices return a string instead of a list, thus
125 It's basically a list, but slices return a string instead of a list, thus
126 allowing things like (assuming 'In' is an instance):
126 allowing things like (assuming 'In' is an instance):
127
127
128 exec In[4:7]
128 exec In[4:7]
129
129
130 or
130 or
131
131
132 exec In[5:9] + In[14] + In[21:25]"""
132 exec In[5:9] + In[14] + In[21:25]"""
133
133
134 def __getslice__(self,i,j):
134 def __getslice__(self,i,j):
135 return ''.join(list.__getslice__(self,i,j))
135 return ''.join(list.__getslice__(self,i,j))
136
136
137
137
138 class SyntaxTB(ultratb.ListTB):
138 class SyntaxTB(ultratb.ListTB):
139 """Extension which holds some state: the last exception value"""
139 """Extension which holds some state: the last exception value"""
140
140
141 def __init__(self,color_scheme = 'NoColor'):
141 def __init__(self,color_scheme = 'NoColor'):
142 ultratb.ListTB.__init__(self,color_scheme)
142 ultratb.ListTB.__init__(self,color_scheme)
143 self.last_syntax_error = None
143 self.last_syntax_error = None
144
144
145 def __call__(self, etype, value, elist):
145 def __call__(self, etype, value, elist):
146 self.last_syntax_error = value
146 self.last_syntax_error = value
147 ultratb.ListTB.__call__(self,etype,value,elist)
147 ultratb.ListTB.__call__(self,etype,value,elist)
148
148
149 def clear_err_state(self):
149 def clear_err_state(self):
150 """Return the current error state and clear it"""
150 """Return the current error state and clear it"""
151 e = self.last_syntax_error
151 e = self.last_syntax_error
152 self.last_syntax_error = None
152 self.last_syntax_error = None
153 return e
153 return e
154
154
155
155
156 def get_default_editor():
156 def get_default_editor():
157 try:
157 try:
158 ed = os.environ['EDITOR']
158 ed = os.environ['EDITOR']
159 except KeyError:
159 except KeyError:
160 if os.name == 'posix':
160 if os.name == 'posix':
161 ed = 'vi' # the only one guaranteed to be there!
161 ed = 'vi' # the only one guaranteed to be there!
162 else:
162 else:
163 ed = 'notepad' # same in Windows!
163 ed = 'notepad' # same in Windows!
164 return ed
164 return ed
165
165
166
166
167 def get_default_colors():
167 def get_default_colors():
168 if sys.platform=='darwin':
168 if sys.platform=='darwin':
169 return "LightBG"
169 return "LightBG"
170 elif os.name=='nt':
170 elif os.name=='nt':
171 return 'Linux'
171 return 'Linux'
172 else:
172 else:
173 return 'Linux'
173 return 'Linux'
174
174
175
175
176 class SeparateStr(Str):
176 class SeparateStr(Str):
177 """A Str subclass to validate separate_in, separate_out, etc.
177 """A Str subclass to validate separate_in, separate_out, etc.
178
178
179 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
179 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
180 """
180 """
181
181
182 def validate(self, obj, value):
182 def validate(self, obj, value):
183 if value == '0': value = ''
183 if value == '0': value = ''
184 value = value.replace('\\n','\n')
184 value = value.replace('\\n','\n')
185 return super(SeparateStr, self).validate(obj, value)
185 return super(SeparateStr, self).validate(obj, value)
186
186
187
187
188 def make_user_namespaces(user_ns=None, user_global_ns=None):
189 """Return a valid local and global user interactive namespaces.
190
191 This builds a dict with the minimal information needed to operate as a
192 valid IPython user namespace, which you can pass to the various
193 embedding classes in ipython. The default implementation returns the
194 same dict for both the locals and the globals to allow functions to
195 refer to variables in the namespace. Customized implementations can
196 return different dicts. The locals dictionary can actually be anything
197 following the basic mapping protocol of a dict, but the globals dict
198 must be a true dict, not even a subclass. It is recommended that any
199 custom object for the locals namespace synchronize with the globals
200 dict somehow.
201
202 Raises TypeError if the provided globals namespace is not a true dict.
203
204 Parameters
205 ----------
206 user_ns : dict-like, optional
207 The current user namespace. The items in this namespace should
208 be included in the output. If None, an appropriate blank
209 namespace should be created.
210 user_global_ns : dict, optional
211 The current user global namespace. The items in this namespace
212 should be included in the output. If None, an appropriate
213 blank namespace should be created.
214
215 Returns
216 -------
217 A pair of dictionary-like object to be used as the local namespace
218 of the interpreter and a dict to be used as the global namespace.
219 """
220
221 if user_ns is None:
222 # Set __name__ to __main__ to better match the behavior of the
223 # normal interpreter.
224 user_ns = {'__name__' :'__main__',
225 '__builtins__' : __builtin__,
226 }
227 else:
228 user_ns.setdefault('__name__','__main__')
229 user_ns.setdefault('__builtins__',__builtin__)
230
231 if user_global_ns is None:
232 user_global_ns = user_ns
233 if type(user_global_ns) is not dict:
234 raise TypeError("user_global_ns must be a true dict; got %r"
235 % type(user_global_ns))
236
237 return user_ns, user_global_ns
238
188 #-----------------------------------------------------------------------------
239 #-----------------------------------------------------------------------------
189 # Main IPython class
240 # Main IPython class
190 #-----------------------------------------------------------------------------
241 #-----------------------------------------------------------------------------
191
242
192
243
193 class InteractiveShell(Component, Magic):
244 class InteractiveShell(Component, Magic):
194 """An enhanced, interactive shell for Python."""
245 """An enhanced, interactive shell for Python."""
195
246
196 autocall = Enum((0,1,2), default_value=1, config=True)
247 autocall = Enum((0,1,2), default_value=1, config=True)
197 autoedit_syntax = CBool(False, config=True)
248 autoedit_syntax = CBool(False, config=True)
198 autoindent = CBool(True, config=True)
249 autoindent = CBool(True, config=True)
199 automagic = CBool(True, config=True)
250 automagic = CBool(True, config=True)
200 banner = Str('')
251 banner = Str('')
201 banner1 = Str(default_banner, config=True)
252 banner1 = Str(default_banner, config=True)
202 banner2 = Str('', config=True)
253 banner2 = Str('', config=True)
203 cache_size = Int(1000, config=True)
254 cache_size = Int(1000, config=True)
204 color_info = CBool(True, config=True)
255 color_info = CBool(True, config=True)
205 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
256 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
206 default_value=get_default_colors(), config=True)
257 default_value=get_default_colors(), config=True)
207 confirm_exit = CBool(True, config=True)
258 confirm_exit = CBool(True, config=True)
208 debug = CBool(False, config=True)
259 debug = CBool(False, config=True)
209 deep_reload = CBool(False, config=True)
260 deep_reload = CBool(False, config=True)
210 # This display_banner only controls whether or not self.show_banner()
261 # This display_banner only controls whether or not self.show_banner()
211 # is called when mainloop/interact are called. The default is False
262 # is called when mainloop/interact are called. The default is False
212 # because for the terminal based application, the banner behavior
263 # because for the terminal based application, the banner behavior
213 # is controlled by Global.display_banner, which IPythonApp looks at
264 # is controlled by Global.display_banner, which IPythonApp looks at
214 # to determine if *it* should call show_banner() by hand or not.
265 # to determine if *it* should call show_banner() by hand or not.
215 display_banner = CBool(False) # This isn't configurable!
266 display_banner = CBool(False) # This isn't configurable!
216 embedded = CBool(False)
267 embedded = CBool(False)
217 embedded_active = CBool(False)
268 embedded_active = CBool(False)
218 editor = Str(get_default_editor(), config=True)
269 editor = Str(get_default_editor(), config=True)
219 filename = Str("<ipython console>")
270 filename = Str("<ipython console>")
220 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
271 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
221 logstart = CBool(False, config=True)
272 logstart = CBool(False, config=True)
222 logfile = Str('', config=True)
273 logfile = Str('', config=True)
223 logappend = Str('', config=True)
274 logappend = Str('', config=True)
224 object_info_string_level = Enum((0,1,2), default_value=0,
275 object_info_string_level = Enum((0,1,2), default_value=0,
225 config=True)
276 config=True)
226 pager = Str('less', config=True)
277 pager = Str('less', config=True)
227 pdb = CBool(False, config=True)
278 pdb = CBool(False, config=True)
228 pprint = CBool(True, config=True)
279 pprint = CBool(True, config=True)
229 profile = Str('', config=True)
280 profile = Str('', config=True)
230 prompt_in1 = Str('In [\\#]: ', config=True)
281 prompt_in1 = Str('In [\\#]: ', config=True)
231 prompt_in2 = Str(' .\\D.: ', config=True)
282 prompt_in2 = Str(' .\\D.: ', config=True)
232 prompt_out = Str('Out[\\#]: ', config=True)
283 prompt_out = Str('Out[\\#]: ', config=True)
233 prompts_pad_left = CBool(True, config=True)
284 prompts_pad_left = CBool(True, config=True)
234 quiet = CBool(False, config=True)
285 quiet = CBool(False, config=True)
235
286
236 readline_use = CBool(True, config=True)
287 readline_use = CBool(True, config=True)
237 readline_merge_completions = CBool(True, config=True)
288 readline_merge_completions = CBool(True, config=True)
238 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
289 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
239 readline_remove_delims = Str('-/~', config=True)
290 readline_remove_delims = Str('-/~', config=True)
240 readline_parse_and_bind = List([
291 readline_parse_and_bind = List([
241 'tab: complete',
292 'tab: complete',
242 '"\C-l": possible-completions',
293 '"\C-l": possible-completions',
243 'set show-all-if-ambiguous on',
294 'set show-all-if-ambiguous on',
244 '"\C-o": tab-insert',
295 '"\C-o": tab-insert',
245 '"\M-i": " "',
296 '"\M-i": " "',
246 '"\M-o": "\d\d\d\d"',
297 '"\M-o": "\d\d\d\d"',
247 '"\M-I": "\d\d\d\d"',
298 '"\M-I": "\d\d\d\d"',
248 '"\C-r": reverse-search-history',
299 '"\C-r": reverse-search-history',
249 '"\C-s": forward-search-history',
300 '"\C-s": forward-search-history',
250 '"\C-p": history-search-backward',
301 '"\C-p": history-search-backward',
251 '"\C-n": history-search-forward',
302 '"\C-n": history-search-forward',
252 '"\e[A": history-search-backward',
303 '"\e[A": history-search-backward',
253 '"\e[B": history-search-forward',
304 '"\e[B": history-search-forward',
254 '"\C-k": kill-line',
305 '"\C-k": kill-line',
255 '"\C-u": unix-line-discard',
306 '"\C-u": unix-line-discard',
256 ], allow_none=False, config=True)
307 ], allow_none=False, config=True)
257
308
258 screen_length = Int(0, config=True)
309 screen_length = Int(0, config=True)
259
310
260 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
311 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
261 separate_in = SeparateStr('\n', config=True)
312 separate_in = SeparateStr('\n', config=True)
262 separate_out = SeparateStr('', config=True)
313 separate_out = SeparateStr('', config=True)
263 separate_out2 = SeparateStr('', config=True)
314 separate_out2 = SeparateStr('', config=True)
264
315
265 system_header = Str('IPython system call: ', config=True)
316 system_header = Str('IPython system call: ', config=True)
266 system_verbose = CBool(False, config=True)
317 system_verbose = CBool(False, config=True)
267 term_title = CBool(False, config=True)
318 term_title = CBool(False, config=True)
268 wildcards_case_sensitive = CBool(True, config=True)
319 wildcards_case_sensitive = CBool(True, config=True)
269 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
320 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
270 default_value='Context', config=True)
321 default_value='Context', config=True)
271
322
272 autoexec = List(allow_none=False)
323 autoexec = List(allow_none=False)
273
324
274 # class attribute to indicate whether the class supports threads or not.
325 # class attribute to indicate whether the class supports threads or not.
275 # Subclasses with thread support should override this as needed.
326 # Subclasses with thread support should override this as needed.
276 isthreaded = False
327 isthreaded = False
277
328
278 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
329 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
279 user_ns=None, user_global_ns=None,
330 user_ns=None, user_global_ns=None,
280 banner1=None, banner2=None, display_banner=None,
331 banner1=None, banner2=None, display_banner=None,
281 custom_exceptions=((),None)):
332 custom_exceptions=((),None)):
282
333
283 # This is where traitlets with a config_key argument are updated
334 # This is where traitlets with a config_key argument are updated
284 # from the values on config.
335 # from the values on config.
285 super(InteractiveShell, self).__init__(parent, config=config)
336 super(InteractiveShell, self).__init__(parent, config=config)
286
337
287 # These are relatively independent and stateless
338 # These are relatively independent and stateless
288 self.init_ipython_dir(ipython_dir)
339 self.init_ipython_dir(ipython_dir)
289 self.init_instance_attrs()
340 self.init_instance_attrs()
290 self.init_term_title()
341 self.init_term_title()
291 self.init_usage(usage)
342 self.init_usage(usage)
292 self.init_banner(banner1, banner2, display_banner)
343 self.init_banner(banner1, banner2, display_banner)
293
344
294 # Create namespaces (user_ns, user_global_ns, etc.)
345 # Create namespaces (user_ns, user_global_ns, etc.)
295 self.init_create_namespaces(user_ns, user_global_ns)
346 self.init_create_namespaces(user_ns, user_global_ns)
296 # This has to be done after init_create_namespaces because it uses
347 # This has to be done after init_create_namespaces because it uses
297 # something in self.user_ns, but before init_sys_modules, which
348 # something in self.user_ns, but before init_sys_modules, which
298 # is the first thing to modify sys.
349 # is the first thing to modify sys.
299 self.save_sys_module_state()
350 self.save_sys_module_state()
300 self.init_sys_modules()
351 self.init_sys_modules()
301
352
302 self.init_history()
353 self.init_history()
303 self.init_encoding()
354 self.init_encoding()
304 self.init_prefilter()
355 self.init_prefilter()
305
356
306 Magic.__init__(self, self)
357 Magic.__init__(self, self)
307
358
308 self.init_syntax_highlighting()
359 self.init_syntax_highlighting()
309 self.init_hooks()
360 self.init_hooks()
310 self.init_pushd_popd_magic()
361 self.init_pushd_popd_magic()
311 self.init_traceback_handlers(custom_exceptions)
362 self.init_traceback_handlers(custom_exceptions)
312 self.init_user_ns()
363 self.init_user_ns()
313 self.init_logger()
364 self.init_logger()
314 self.init_alias()
365 self.init_alias()
315 self.init_builtins()
366 self.init_builtins()
316
367
317 # pre_config_initialization
368 # pre_config_initialization
318 self.init_shadow_hist()
369 self.init_shadow_hist()
319
370
320 # The next section should contain averything that was in ipmaker.
371 # The next section should contain averything that was in ipmaker.
321 self.init_logstart()
372 self.init_logstart()
322
373
323 # The following was in post_config_initialization
374 # The following was in post_config_initialization
324 self.init_inspector()
375 self.init_inspector()
325 self.init_readline()
376 self.init_readline()
326 self.init_prompts()
377 self.init_prompts()
327 self.init_displayhook()
378 self.init_displayhook()
328 self.init_reload_doctest()
379 self.init_reload_doctest()
329 self.init_magics()
380 self.init_magics()
330 self.init_pdb()
381 self.init_pdb()
331 self.hooks.late_startup_hook()
382 self.hooks.late_startup_hook()
332
383
333 def get_ipython(self):
384 def get_ipython(self):
334 return self
385 return self
335
386
336 #-------------------------------------------------------------------------
387 #-------------------------------------------------------------------------
337 # Traitlet changed handlers
388 # Traitlet changed handlers
338 #-------------------------------------------------------------------------
389 #-------------------------------------------------------------------------
339
390
340 def _banner1_changed(self):
391 def _banner1_changed(self):
341 self.compute_banner()
392 self.compute_banner()
342
393
343 def _banner2_changed(self):
394 def _banner2_changed(self):
344 self.compute_banner()
395 self.compute_banner()
345
396
346 def _ipython_dir_changed(self, name, new):
397 def _ipython_dir_changed(self, name, new):
347 if not os.path.isdir(new):
398 if not os.path.isdir(new):
348 os.makedirs(new, mode = 0777)
399 os.makedirs(new, mode = 0777)
349 if not os.path.isdir(self.ipython_extension_dir):
400 if not os.path.isdir(self.ipython_extension_dir):
350 os.makedirs(self.ipython_extension_dir, mode = 0777)
401 os.makedirs(self.ipython_extension_dir, mode = 0777)
351
402
352 @property
403 @property
353 def ipython_extension_dir(self):
404 def ipython_extension_dir(self):
354 return os.path.join(self.ipython_dir, 'extensions')
405 return os.path.join(self.ipython_dir, 'extensions')
355
406
356 @property
407 @property
357 def usable_screen_length(self):
408 def usable_screen_length(self):
358 if self.screen_length == 0:
409 if self.screen_length == 0:
359 return 0
410 return 0
360 else:
411 else:
361 num_lines_bot = self.separate_in.count('\n')+1
412 num_lines_bot = self.separate_in.count('\n')+1
362 return self.screen_length - num_lines_bot
413 return self.screen_length - num_lines_bot
363
414
364 def _term_title_changed(self, name, new_value):
415 def _term_title_changed(self, name, new_value):
365 self.init_term_title()
416 self.init_term_title()
366
417
367 def set_autoindent(self,value=None):
418 def set_autoindent(self,value=None):
368 """Set the autoindent flag, checking for readline support.
419 """Set the autoindent flag, checking for readline support.
369
420
370 If called with no arguments, it acts as a toggle."""
421 If called with no arguments, it acts as a toggle."""
371
422
372 if not self.has_readline:
423 if not self.has_readline:
373 if os.name == 'posix':
424 if os.name == 'posix':
374 warn("The auto-indent feature requires the readline library")
425 warn("The auto-indent feature requires the readline library")
375 self.autoindent = 0
426 self.autoindent = 0
376 return
427 return
377 if value is None:
428 if value is None:
378 self.autoindent = not self.autoindent
429 self.autoindent = not self.autoindent
379 else:
430 else:
380 self.autoindent = value
431 self.autoindent = value
381
432
382 #-------------------------------------------------------------------------
433 #-------------------------------------------------------------------------
383 # init_* methods called by __init__
434 # init_* methods called by __init__
384 #-------------------------------------------------------------------------
435 #-------------------------------------------------------------------------
385
436
386 def init_ipython_dir(self, ipython_dir):
437 def init_ipython_dir(self, ipython_dir):
387 if ipython_dir is not None:
438 if ipython_dir is not None:
388 self.ipython_dir = ipython_dir
439 self.ipython_dir = ipython_dir
389 self.config.Global.ipython_dir = self.ipython_dir
440 self.config.Global.ipython_dir = self.ipython_dir
390 return
441 return
391
442
392 if hasattr(self.config.Global, 'ipython_dir'):
443 if hasattr(self.config.Global, 'ipython_dir'):
393 self.ipython_dir = self.config.Global.ipython_dir
444 self.ipython_dir = self.config.Global.ipython_dir
394 else:
445 else:
395 self.ipython_dir = get_ipython_dir()
446 self.ipython_dir = get_ipython_dir()
396
447
397 # All children can just read this
448 # All children can just read this
398 self.config.Global.ipython_dir = self.ipython_dir
449 self.config.Global.ipython_dir = self.ipython_dir
399
450
400 def init_instance_attrs(self):
451 def init_instance_attrs(self):
401 self.jobs = BackgroundJobManager()
452 self.jobs = BackgroundJobManager()
402 self.more = False
453 self.more = False
403
454
404 # command compiler
455 # command compiler
405 self.compile = codeop.CommandCompiler()
456 self.compile = codeop.CommandCompiler()
406
457
407 # User input buffer
458 # User input buffer
408 self.buffer = []
459 self.buffer = []
409
460
410 # Make an empty namespace, which extension writers can rely on both
461 # Make an empty namespace, which extension writers can rely on both
411 # existing and NEVER being used by ipython itself. This gives them a
462 # existing and NEVER being used by ipython itself. This gives them a
412 # convenient location for storing additional information and state
463 # convenient location for storing additional information and state
413 # their extensions may require, without fear of collisions with other
464 # their extensions may require, without fear of collisions with other
414 # ipython names that may develop later.
465 # ipython names that may develop later.
415 self.meta = Struct()
466 self.meta = Struct()
416
467
417 # Object variable to store code object waiting execution. This is
468 # Object variable to store code object waiting execution. This is
418 # used mainly by the multithreaded shells, but it can come in handy in
469 # used mainly by the multithreaded shells, but it can come in handy in
419 # other situations. No need to use a Queue here, since it's a single
470 # other situations. No need to use a Queue here, since it's a single
420 # item which gets cleared once run.
471 # item which gets cleared once run.
421 self.code_to_run = None
472 self.code_to_run = None
422
473
423 # Flag to mark unconditional exit
474 # Flag to mark unconditional exit
424 self.exit_now = False
475 self.exit_now = False
425
476
426 # Temporary files used for various purposes. Deleted at exit.
477 # Temporary files used for various purposes. Deleted at exit.
427 self.tempfiles = []
478 self.tempfiles = []
428
479
429 # Keep track of readline usage (later set by init_readline)
480 # Keep track of readline usage (later set by init_readline)
430 self.has_readline = False
481 self.has_readline = False
431
482
432 # keep track of where we started running (mainly for crash post-mortem)
483 # keep track of where we started running (mainly for crash post-mortem)
433 # This is not being used anywhere currently.
484 # This is not being used anywhere currently.
434 self.starting_dir = os.getcwd()
485 self.starting_dir = os.getcwd()
435
486
436 # Indentation management
487 # Indentation management
437 self.indent_current_nsp = 0
488 self.indent_current_nsp = 0
438
489
439 def init_term_title(self):
490 def init_term_title(self):
440 # Enable or disable the terminal title.
491 # Enable or disable the terminal title.
441 if self.term_title:
492 if self.term_title:
442 toggle_set_term_title(True)
493 toggle_set_term_title(True)
443 set_term_title('IPython: ' + abbrev_cwd())
494 set_term_title('IPython: ' + abbrev_cwd())
444 else:
495 else:
445 toggle_set_term_title(False)
496 toggle_set_term_title(False)
446
497
447 def init_usage(self, usage=None):
498 def init_usage(self, usage=None):
448 if usage is None:
499 if usage is None:
449 self.usage = interactive_usage
500 self.usage = interactive_usage
450 else:
501 else:
451 self.usage = usage
502 self.usage = usage
452
503
453 def init_encoding(self):
504 def init_encoding(self):
454 # Get system encoding at startup time. Certain terminals (like Emacs
505 # Get system encoding at startup time. Certain terminals (like Emacs
455 # under Win32 have it set to None, and we need to have a known valid
506 # under Win32 have it set to None, and we need to have a known valid
456 # encoding to use in the raw_input() method
507 # encoding to use in the raw_input() method
457 try:
508 try:
458 self.stdin_encoding = sys.stdin.encoding or 'ascii'
509 self.stdin_encoding = sys.stdin.encoding or 'ascii'
459 except AttributeError:
510 except AttributeError:
460 self.stdin_encoding = 'ascii'
511 self.stdin_encoding = 'ascii'
461
512
462 def init_syntax_highlighting(self):
513 def init_syntax_highlighting(self):
463 # Python source parser/formatter for syntax highlighting
514 # Python source parser/formatter for syntax highlighting
464 pyformat = PyColorize.Parser().format
515 pyformat = PyColorize.Parser().format
465 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
516 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
466
517
467 def init_pushd_popd_magic(self):
518 def init_pushd_popd_magic(self):
468 # for pushd/popd management
519 # for pushd/popd management
469 try:
520 try:
470 self.home_dir = get_home_dir()
521 self.home_dir = get_home_dir()
471 except HomeDirError, msg:
522 except HomeDirError, msg:
472 fatal(msg)
523 fatal(msg)
473
524
474 self.dir_stack = []
525 self.dir_stack = []
475
526
476 def init_logger(self):
527 def init_logger(self):
477 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
528 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
478 # local shortcut, this is used a LOT
529 # local shortcut, this is used a LOT
479 self.log = self.logger.log
530 self.log = self.logger.log
480
531
481 def init_logstart(self):
532 def init_logstart(self):
482 if self.logappend:
533 if self.logappend:
483 self.magic_logstart(self.logappend + ' append')
534 self.magic_logstart(self.logappend + ' append')
484 elif self.logfile:
535 elif self.logfile:
485 self.magic_logstart(self.logfile)
536 self.magic_logstart(self.logfile)
486 elif self.logstart:
537 elif self.logstart:
487 self.magic_logstart()
538 self.magic_logstart()
488
539
489 def init_builtins(self):
540 def init_builtins(self):
490 self.builtin_trap = BuiltinTrap(self)
541 self.builtin_trap = BuiltinTrap(self)
491
542
492 def init_inspector(self):
543 def init_inspector(self):
493 # Object inspector
544 # Object inspector
494 self.inspector = oinspect.Inspector(oinspect.InspectColors,
545 self.inspector = oinspect.Inspector(oinspect.InspectColors,
495 PyColorize.ANSICodeColors,
546 PyColorize.ANSICodeColors,
496 'NoColor',
547 'NoColor',
497 self.object_info_string_level)
548 self.object_info_string_level)
498
549
499 def init_prompts(self):
550 def init_prompts(self):
500 # Initialize cache, set in/out prompts and printing system
551 # Initialize cache, set in/out prompts and printing system
501 self.outputcache = CachedOutput(self,
552 self.outputcache = CachedOutput(self,
502 self.cache_size,
553 self.cache_size,
503 self.pprint,
554 self.pprint,
504 input_sep = self.separate_in,
555 input_sep = self.separate_in,
505 output_sep = self.separate_out,
556 output_sep = self.separate_out,
506 output_sep2 = self.separate_out2,
557 output_sep2 = self.separate_out2,
507 ps1 = self.prompt_in1,
558 ps1 = self.prompt_in1,
508 ps2 = self.prompt_in2,
559 ps2 = self.prompt_in2,
509 ps_out = self.prompt_out,
560 ps_out = self.prompt_out,
510 pad_left = self.prompts_pad_left)
561 pad_left = self.prompts_pad_left)
511
562
512 # user may have over-ridden the default print hook:
563 # user may have over-ridden the default print hook:
513 try:
564 try:
514 self.outputcache.__class__.display = self.hooks.display
565 self.outputcache.__class__.display = self.hooks.display
515 except AttributeError:
566 except AttributeError:
516 pass
567 pass
517
568
518 def init_displayhook(self):
569 def init_displayhook(self):
519 self.display_trap = DisplayTrap(self, self.outputcache)
570 self.display_trap = DisplayTrap(self, self.outputcache)
520
571
521 def init_reload_doctest(self):
572 def init_reload_doctest(self):
522 # Do a proper resetting of doctest, including the necessary displayhook
573 # Do a proper resetting of doctest, including the necessary displayhook
523 # monkeypatching
574 # monkeypatching
524 try:
575 try:
525 doctest_reload()
576 doctest_reload()
526 except ImportError:
577 except ImportError:
527 warn("doctest module does not exist.")
578 warn("doctest module does not exist.")
528
579
529 #-------------------------------------------------------------------------
580 #-------------------------------------------------------------------------
530 # Things related to the banner
581 # Things related to the banner
531 #-------------------------------------------------------------------------
582 #-------------------------------------------------------------------------
532
583
533 def init_banner(self, banner1, banner2, display_banner):
584 def init_banner(self, banner1, banner2, display_banner):
534 if banner1 is not None:
585 if banner1 is not None:
535 self.banner1 = banner1
586 self.banner1 = banner1
536 if banner2 is not None:
587 if banner2 is not None:
537 self.banner2 = banner2
588 self.banner2 = banner2
538 if display_banner is not None:
589 if display_banner is not None:
539 self.display_banner = display_banner
590 self.display_banner = display_banner
540 self.compute_banner()
591 self.compute_banner()
541
592
542 def show_banner(self, banner=None):
593 def show_banner(self, banner=None):
543 if banner is None:
594 if banner is None:
544 banner = self.banner
595 banner = self.banner
545 self.write(banner)
596 self.write(banner)
546
597
547 def compute_banner(self):
598 def compute_banner(self):
548 self.banner = self.banner1 + '\n'
599 self.banner = self.banner1 + '\n'
549 if self.profile:
600 if self.profile:
550 self.banner += '\nIPython profile: %s\n' % self.profile
601 self.banner += '\nIPython profile: %s\n' % self.profile
551 if self.banner2:
602 if self.banner2:
552 self.banner += '\n' + self.banner2 + '\n'
603 self.banner += '\n' + self.banner2 + '\n'
553
604
554 #-------------------------------------------------------------------------
605 #-------------------------------------------------------------------------
555 # Things related to injections into the sys module
606 # Things related to injections into the sys module
556 #-------------------------------------------------------------------------
607 #-------------------------------------------------------------------------
557
608
558 def save_sys_module_state(self):
609 def save_sys_module_state(self):
559 """Save the state of hooks in the sys module.
610 """Save the state of hooks in the sys module.
560
611
561 This has to be called after self.user_ns is created.
612 This has to be called after self.user_ns is created.
562 """
613 """
563 self._orig_sys_module_state = {}
614 self._orig_sys_module_state = {}
564 self._orig_sys_module_state['stdin'] = sys.stdin
615 self._orig_sys_module_state['stdin'] = sys.stdin
565 self._orig_sys_module_state['stdout'] = sys.stdout
616 self._orig_sys_module_state['stdout'] = sys.stdout
566 self._orig_sys_module_state['stderr'] = sys.stderr
617 self._orig_sys_module_state['stderr'] = sys.stderr
567 self._orig_sys_module_state['excepthook'] = sys.excepthook
618 self._orig_sys_module_state['excepthook'] = sys.excepthook
568 try:
619 try:
569 self._orig_sys_modules_main_name = self.user_ns['__name__']
620 self._orig_sys_modules_main_name = self.user_ns['__name__']
570 except KeyError:
621 except KeyError:
571 pass
622 pass
572
623
573 def restore_sys_module_state(self):
624 def restore_sys_module_state(self):
574 """Restore the state of the sys module."""
625 """Restore the state of the sys module."""
575 try:
626 try:
576 for k, v in self._orig_sys_module_state.items():
627 for k, v in self._orig_sys_module_state.items():
577 setattr(sys, k, v)
628 setattr(sys, k, v)
578 except AttributeError:
629 except AttributeError:
579 pass
630 pass
580 try:
631 try:
581 delattr(sys, 'ipcompleter')
632 delattr(sys, 'ipcompleter')
582 except AttributeError:
633 except AttributeError:
583 pass
634 pass
584 # Reset what what done in self.init_sys_modules
635 # Reset what what done in self.init_sys_modules
585 try:
636 try:
586 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
637 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
587 except (AttributeError, KeyError):
638 except (AttributeError, KeyError):
588 pass
639 pass
589
640
590 #-------------------------------------------------------------------------
641 #-------------------------------------------------------------------------
591 # Things related to hooks
642 # Things related to hooks
592 #-------------------------------------------------------------------------
643 #-------------------------------------------------------------------------
593
644
594 def init_hooks(self):
645 def init_hooks(self):
595 # hooks holds pointers used for user-side customizations
646 # hooks holds pointers used for user-side customizations
596 self.hooks = Struct()
647 self.hooks = Struct()
597
648
598 self.strdispatchers = {}
649 self.strdispatchers = {}
599
650
600 # Set all default hooks, defined in the IPython.hooks module.
651 # Set all default hooks, defined in the IPython.hooks module.
601 import IPython.core.hooks
652 import IPython.core.hooks
602 hooks = IPython.core.hooks
653 hooks = IPython.core.hooks
603 for hook_name in hooks.__all__:
654 for hook_name in hooks.__all__:
604 # default hooks have priority 100, i.e. low; user hooks should have
655 # default hooks have priority 100, i.e. low; user hooks should have
605 # 0-100 priority
656 # 0-100 priority
606 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
657 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
607
658
608 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
659 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
609 """set_hook(name,hook) -> sets an internal IPython hook.
660 """set_hook(name,hook) -> sets an internal IPython hook.
610
661
611 IPython exposes some of its internal API as user-modifiable hooks. By
662 IPython exposes some of its internal API as user-modifiable hooks. By
612 adding your function to one of these hooks, you can modify IPython's
663 adding your function to one of these hooks, you can modify IPython's
613 behavior to call at runtime your own routines."""
664 behavior to call at runtime your own routines."""
614
665
615 # At some point in the future, this should validate the hook before it
666 # At some point in the future, this should validate the hook before it
616 # accepts it. Probably at least check that the hook takes the number
667 # accepts it. Probably at least check that the hook takes the number
617 # of args it's supposed to.
668 # of args it's supposed to.
618
669
619 f = new.instancemethod(hook,self,self.__class__)
670 f = new.instancemethod(hook,self,self.__class__)
620
671
621 # check if the hook is for strdispatcher first
672 # check if the hook is for strdispatcher first
622 if str_key is not None:
673 if str_key is not None:
623 sdp = self.strdispatchers.get(name, StrDispatch())
674 sdp = self.strdispatchers.get(name, StrDispatch())
624 sdp.add_s(str_key, f, priority )
675 sdp.add_s(str_key, f, priority )
625 self.strdispatchers[name] = sdp
676 self.strdispatchers[name] = sdp
626 return
677 return
627 if re_key is not None:
678 if re_key is not None:
628 sdp = self.strdispatchers.get(name, StrDispatch())
679 sdp = self.strdispatchers.get(name, StrDispatch())
629 sdp.add_re(re.compile(re_key), f, priority )
680 sdp.add_re(re.compile(re_key), f, priority )
630 self.strdispatchers[name] = sdp
681 self.strdispatchers[name] = sdp
631 return
682 return
632
683
633 dp = getattr(self.hooks, name, None)
684 dp = getattr(self.hooks, name, None)
634 if name not in IPython.core.hooks.__all__:
685 if name not in IPython.core.hooks.__all__:
635 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
686 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
636 if not dp:
687 if not dp:
637 dp = IPython.core.hooks.CommandChainDispatcher()
688 dp = IPython.core.hooks.CommandChainDispatcher()
638
689
639 try:
690 try:
640 dp.add(f,priority)
691 dp.add(f,priority)
641 except AttributeError:
692 except AttributeError:
642 # it was not commandchain, plain old func - replace
693 # it was not commandchain, plain old func - replace
643 dp = f
694 dp = f
644
695
645 setattr(self.hooks,name, dp)
696 setattr(self.hooks,name, dp)
646
697
647 #-------------------------------------------------------------------------
698 #-------------------------------------------------------------------------
648 # Things related to the "main" module
699 # Things related to the "main" module
649 #-------------------------------------------------------------------------
700 #-------------------------------------------------------------------------
650
701
651 def new_main_mod(self,ns=None):
702 def new_main_mod(self,ns=None):
652 """Return a new 'main' module object for user code execution.
703 """Return a new 'main' module object for user code execution.
653 """
704 """
654 main_mod = self._user_main_module
705 main_mod = self._user_main_module
655 init_fakemod_dict(main_mod,ns)
706 init_fakemod_dict(main_mod,ns)
656 return main_mod
707 return main_mod
657
708
658 def cache_main_mod(self,ns,fname):
709 def cache_main_mod(self,ns,fname):
659 """Cache a main module's namespace.
710 """Cache a main module's namespace.
660
711
661 When scripts are executed via %run, we must keep a reference to the
712 When scripts are executed via %run, we must keep a reference to the
662 namespace of their __main__ module (a FakeModule instance) around so
713 namespace of their __main__ module (a FakeModule instance) around so
663 that Python doesn't clear it, rendering objects defined therein
714 that Python doesn't clear it, rendering objects defined therein
664 useless.
715 useless.
665
716
666 This method keeps said reference in a private dict, keyed by the
717 This method keeps said reference in a private dict, keyed by the
667 absolute path of the module object (which corresponds to the script
718 absolute path of the module object (which corresponds to the script
668 path). This way, for multiple executions of the same script we only
719 path). This way, for multiple executions of the same script we only
669 keep one copy of the namespace (the last one), thus preventing memory
720 keep one copy of the namespace (the last one), thus preventing memory
670 leaks from old references while allowing the objects from the last
721 leaks from old references while allowing the objects from the last
671 execution to be accessible.
722 execution to be accessible.
672
723
673 Note: we can not allow the actual FakeModule instances to be deleted,
724 Note: we can not allow the actual FakeModule instances to be deleted,
674 because of how Python tears down modules (it hard-sets all their
725 because of how Python tears down modules (it hard-sets all their
675 references to None without regard for reference counts). This method
726 references to None without regard for reference counts). This method
676 must therefore make a *copy* of the given namespace, to allow the
727 must therefore make a *copy* of the given namespace, to allow the
677 original module's __dict__ to be cleared and reused.
728 original module's __dict__ to be cleared and reused.
678
729
679
730
680 Parameters
731 Parameters
681 ----------
732 ----------
682 ns : a namespace (a dict, typically)
733 ns : a namespace (a dict, typically)
683
734
684 fname : str
735 fname : str
685 Filename associated with the namespace.
736 Filename associated with the namespace.
686
737
687 Examples
738 Examples
688 --------
739 --------
689
740
690 In [10]: import IPython
741 In [10]: import IPython
691
742
692 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
743 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
693
744
694 In [12]: IPython.__file__ in _ip._main_ns_cache
745 In [12]: IPython.__file__ in _ip._main_ns_cache
695 Out[12]: True
746 Out[12]: True
696 """
747 """
697 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
748 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
698
749
699 def clear_main_mod_cache(self):
750 def clear_main_mod_cache(self):
700 """Clear the cache of main modules.
751 """Clear the cache of main modules.
701
752
702 Mainly for use by utilities like %reset.
753 Mainly for use by utilities like %reset.
703
754
704 Examples
755 Examples
705 --------
756 --------
706
757
707 In [15]: import IPython
758 In [15]: import IPython
708
759
709 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
760 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
710
761
711 In [17]: len(_ip._main_ns_cache) > 0
762 In [17]: len(_ip._main_ns_cache) > 0
712 Out[17]: True
763 Out[17]: True
713
764
714 In [18]: _ip.clear_main_mod_cache()
765 In [18]: _ip.clear_main_mod_cache()
715
766
716 In [19]: len(_ip._main_ns_cache) == 0
767 In [19]: len(_ip._main_ns_cache) == 0
717 Out[19]: True
768 Out[19]: True
718 """
769 """
719 self._main_ns_cache.clear()
770 self._main_ns_cache.clear()
720
771
721 #-------------------------------------------------------------------------
772 #-------------------------------------------------------------------------
722 # Things related to debugging
773 # Things related to debugging
723 #-------------------------------------------------------------------------
774 #-------------------------------------------------------------------------
724
775
725 def init_pdb(self):
776 def init_pdb(self):
726 # Set calling of pdb on exceptions
777 # Set calling of pdb on exceptions
727 # self.call_pdb is a property
778 # self.call_pdb is a property
728 self.call_pdb = self.pdb
779 self.call_pdb = self.pdb
729
780
730 def _get_call_pdb(self):
781 def _get_call_pdb(self):
731 return self._call_pdb
782 return self._call_pdb
732
783
733 def _set_call_pdb(self,val):
784 def _set_call_pdb(self,val):
734
785
735 if val not in (0,1,False,True):
786 if val not in (0,1,False,True):
736 raise ValueError,'new call_pdb value must be boolean'
787 raise ValueError,'new call_pdb value must be boolean'
737
788
738 # store value in instance
789 # store value in instance
739 self._call_pdb = val
790 self._call_pdb = val
740
791
741 # notify the actual exception handlers
792 # notify the actual exception handlers
742 self.InteractiveTB.call_pdb = val
793 self.InteractiveTB.call_pdb = val
743 if self.isthreaded:
794 if self.isthreaded:
744 try:
795 try:
745 self.sys_excepthook.call_pdb = val
796 self.sys_excepthook.call_pdb = val
746 except:
797 except:
747 warn('Failed to activate pdb for threaded exception handler')
798 warn('Failed to activate pdb for threaded exception handler')
748
799
749 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
800 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
750 'Control auto-activation of pdb at exceptions')
801 'Control auto-activation of pdb at exceptions')
751
802
752 def debugger(self,force=False):
803 def debugger(self,force=False):
753 """Call the pydb/pdb debugger.
804 """Call the pydb/pdb debugger.
754
805
755 Keywords:
806 Keywords:
756
807
757 - force(False): by default, this routine checks the instance call_pdb
808 - force(False): by default, this routine checks the instance call_pdb
758 flag and does not actually invoke the debugger if the flag is false.
809 flag and does not actually invoke the debugger if the flag is false.
759 The 'force' option forces the debugger to activate even if the flag
810 The 'force' option forces the debugger to activate even if the flag
760 is false.
811 is false.
761 """
812 """
762
813
763 if not (force or self.call_pdb):
814 if not (force or self.call_pdb):
764 return
815 return
765
816
766 if not hasattr(sys,'last_traceback'):
817 if not hasattr(sys,'last_traceback'):
767 error('No traceback has been produced, nothing to debug.')
818 error('No traceback has been produced, nothing to debug.')
768 return
819 return
769
820
770 # use pydb if available
821 # use pydb if available
771 if debugger.has_pydb:
822 if debugger.has_pydb:
772 from pydb import pm
823 from pydb import pm
773 else:
824 else:
774 # fallback to our internal debugger
825 # fallback to our internal debugger
775 pm = lambda : self.InteractiveTB.debugger(force=True)
826 pm = lambda : self.InteractiveTB.debugger(force=True)
776 self.history_saving_wrapper(pm)()
827 self.history_saving_wrapper(pm)()
777
828
778 #-------------------------------------------------------------------------
829 #-------------------------------------------------------------------------
779 # Things related to IPython's various namespaces
830 # Things related to IPython's various namespaces
780 #-------------------------------------------------------------------------
831 #-------------------------------------------------------------------------
781
832
782 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
833 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
783 # Create the namespace where the user will operate. user_ns is
834 # Create the namespace where the user will operate. user_ns is
784 # normally the only one used, and it is passed to the exec calls as
835 # normally the only one used, and it is passed to the exec calls as
785 # the locals argument. But we do carry a user_global_ns namespace
836 # the locals argument. But we do carry a user_global_ns namespace
786 # given as the exec 'globals' argument, This is useful in embedding
837 # given as the exec 'globals' argument, This is useful in embedding
787 # situations where the ipython shell opens in a context where the
838 # situations where the ipython shell opens in a context where the
788 # distinction between locals and globals is meaningful. For
839 # distinction between locals and globals is meaningful. For
789 # non-embedded contexts, it is just the same object as the user_ns dict.
840 # non-embedded contexts, it is just the same object as the user_ns dict.
790
841
791 # FIXME. For some strange reason, __builtins__ is showing up at user
842 # FIXME. For some strange reason, __builtins__ is showing up at user
792 # level as a dict instead of a module. This is a manual fix, but I
843 # level as a dict instead of a module. This is a manual fix, but I
793 # should really track down where the problem is coming from. Alex
844 # should really track down where the problem is coming from. Alex
794 # Schmolck reported this problem first.
845 # Schmolck reported this problem first.
795
846
796 # A useful post by Alex Martelli on this topic:
847 # A useful post by Alex Martelli on this topic:
797 # Re: inconsistent value from __builtins__
848 # Re: inconsistent value from __builtins__
798 # Von: Alex Martelli <aleaxit@yahoo.com>
849 # Von: Alex Martelli <aleaxit@yahoo.com>
799 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
850 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
800 # Gruppen: comp.lang.python
851 # Gruppen: comp.lang.python
801
852
802 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
853 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
803 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
854 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
804 # > <type 'dict'>
855 # > <type 'dict'>
805 # > >>> print type(__builtins__)
856 # > >>> print type(__builtins__)
806 # > <type 'module'>
857 # > <type 'module'>
807 # > Is this difference in return value intentional?
858 # > Is this difference in return value intentional?
808
859
809 # Well, it's documented that '__builtins__' can be either a dictionary
860 # Well, it's documented that '__builtins__' can be either a dictionary
810 # or a module, and it's been that way for a long time. Whether it's
861 # or a module, and it's been that way for a long time. Whether it's
811 # intentional (or sensible), I don't know. In any case, the idea is
862 # intentional (or sensible), I don't know. In any case, the idea is
812 # that if you need to access the built-in namespace directly, you
863 # that if you need to access the built-in namespace directly, you
813 # should start with "import __builtin__" (note, no 's') which will
864 # should start with "import __builtin__" (note, no 's') which will
814 # definitely give you a module. Yeah, it's somewhat confusing:-(.
865 # definitely give you a module. Yeah, it's somewhat confusing:-(.
815
866
816 # These routines return properly built dicts as needed by the rest of
867 # These routines return properly built dicts as needed by the rest of
817 # the code, and can also be used by extension writers to generate
868 # the code, and can also be used by extension writers to generate
818 # properly initialized namespaces.
869 # properly initialized namespaces.
819 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
870 user_ns, user_global_ns = make_user_namespaces(user_ns, user_global_ns)
820 user_global_ns)
821
871
822 # Assign namespaces
872 # Assign namespaces
823 # This is the namespace where all normal user variables live
873 # This is the namespace where all normal user variables live
824 self.user_ns = user_ns
874 self.user_ns = user_ns
825 self.user_global_ns = user_global_ns
875 self.user_global_ns = user_global_ns
826
876
827 # An auxiliary namespace that checks what parts of the user_ns were
877 # An auxiliary namespace that checks what parts of the user_ns were
828 # loaded at startup, so we can list later only variables defined in
878 # loaded at startup, so we can list later only variables defined in
829 # actual interactive use. Since it is always a subset of user_ns, it
879 # actual interactive use. Since it is always a subset of user_ns, it
830 # doesn't need to be separately tracked in the ns_table.
880 # doesn't need to be separately tracked in the ns_table.
831 self.user_config_ns = {}
881 self.user_config_ns = {}
832
882
833 # A namespace to keep track of internal data structures to prevent
883 # A namespace to keep track of internal data structures to prevent
834 # them from cluttering user-visible stuff. Will be updated later
884 # them from cluttering user-visible stuff. Will be updated later
835 self.internal_ns = {}
885 self.internal_ns = {}
836
886
837 # Now that FakeModule produces a real module, we've run into a nasty
887 # Now that FakeModule produces a real module, we've run into a nasty
838 # problem: after script execution (via %run), the module where the user
888 # problem: after script execution (via %run), the module where the user
839 # code ran is deleted. Now that this object is a true module (needed
889 # code ran is deleted. Now that this object is a true module (needed
840 # so docetst and other tools work correctly), the Python module
890 # so docetst and other tools work correctly), the Python module
841 # teardown mechanism runs over it, and sets to None every variable
891 # teardown mechanism runs over it, and sets to None every variable
842 # present in that module. Top-level references to objects from the
892 # present in that module. Top-level references to objects from the
843 # script survive, because the user_ns is updated with them. However,
893 # script survive, because the user_ns is updated with them. However,
844 # calling functions defined in the script that use other things from
894 # calling functions defined in the script that use other things from
845 # the script will fail, because the function's closure had references
895 # the script will fail, because the function's closure had references
846 # to the original objects, which are now all None. So we must protect
896 # to the original objects, which are now all None. So we must protect
847 # these modules from deletion by keeping a cache.
897 # these modules from deletion by keeping a cache.
848 #
898 #
849 # To avoid keeping stale modules around (we only need the one from the
899 # To avoid keeping stale modules around (we only need the one from the
850 # last run), we use a dict keyed with the full path to the script, so
900 # last run), we use a dict keyed with the full path to the script, so
851 # only the last version of the module is held in the cache. Note,
901 # only the last version of the module is held in the cache. Note,
852 # however, that we must cache the module *namespace contents* (their
902 # however, that we must cache the module *namespace contents* (their
853 # __dict__). Because if we try to cache the actual modules, old ones
903 # __dict__). Because if we try to cache the actual modules, old ones
854 # (uncached) could be destroyed while still holding references (such as
904 # (uncached) could be destroyed while still holding references (such as
855 # those held by GUI objects that tend to be long-lived)>
905 # those held by GUI objects that tend to be long-lived)>
856 #
906 #
857 # The %reset command will flush this cache. See the cache_main_mod()
907 # The %reset command will flush this cache. See the cache_main_mod()
858 # and clear_main_mod_cache() methods for details on use.
908 # and clear_main_mod_cache() methods for details on use.
859
909
860 # This is the cache used for 'main' namespaces
910 # This is the cache used for 'main' namespaces
861 self._main_ns_cache = {}
911 self._main_ns_cache = {}
862 # And this is the single instance of FakeModule whose __dict__ we keep
912 # And this is the single instance of FakeModule whose __dict__ we keep
863 # copying and clearing for reuse on each %run
913 # copying and clearing for reuse on each %run
864 self._user_main_module = FakeModule()
914 self._user_main_module = FakeModule()
865
915
866 # A table holding all the namespaces IPython deals with, so that
916 # A table holding all the namespaces IPython deals with, so that
867 # introspection facilities can search easily.
917 # introspection facilities can search easily.
868 self.ns_table = {'user':user_ns,
918 self.ns_table = {'user':user_ns,
869 'user_global':user_global_ns,
919 'user_global':user_global_ns,
870 'internal':self.internal_ns,
920 'internal':self.internal_ns,
871 'builtin':__builtin__.__dict__
921 'builtin':__builtin__.__dict__
872 }
922 }
873
923
874 # Similarly, track all namespaces where references can be held and that
924 # Similarly, track all namespaces where references can be held and that
875 # we can safely clear (so it can NOT include builtin). This one can be
925 # we can safely clear (so it can NOT include builtin). This one can be
876 # a simple list.
926 # a simple list.
877 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
927 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
878 self.internal_ns, self._main_ns_cache ]
928 self.internal_ns, self._main_ns_cache ]
879
929
880 def init_sys_modules(self):
930 def init_sys_modules(self):
881 # We need to insert into sys.modules something that looks like a
931 # We need to insert into sys.modules something that looks like a
882 # module but which accesses the IPython namespace, for shelve and
932 # module but which accesses the IPython namespace, for shelve and
883 # pickle to work interactively. Normally they rely on getting
933 # pickle to work interactively. Normally they rely on getting
884 # everything out of __main__, but for embedding purposes each IPython
934 # everything out of __main__, but for embedding purposes each IPython
885 # instance has its own private namespace, so we can't go shoving
935 # instance has its own private namespace, so we can't go shoving
886 # everything into __main__.
936 # everything into __main__.
887
937
888 # note, however, that we should only do this for non-embedded
938 # note, however, that we should only do this for non-embedded
889 # ipythons, which really mimic the __main__.__dict__ with their own
939 # ipythons, which really mimic the __main__.__dict__ with their own
890 # namespace. Embedded instances, on the other hand, should not do
940 # namespace. Embedded instances, on the other hand, should not do
891 # this because they need to manage the user local/global namespaces
941 # this because they need to manage the user local/global namespaces
892 # only, but they live within a 'normal' __main__ (meaning, they
942 # only, but they live within a 'normal' __main__ (meaning, they
893 # shouldn't overtake the execution environment of the script they're
943 # shouldn't overtake the execution environment of the script they're
894 # embedded in).
944 # embedded in).
895
945
896 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
946 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
897
947
898 try:
948 try:
899 main_name = self.user_ns['__name__']
949 main_name = self.user_ns['__name__']
900 except KeyError:
950 except KeyError:
901 raise KeyError('user_ns dictionary MUST have a "__name__" key')
951 raise KeyError('user_ns dictionary MUST have a "__name__" key')
902 else:
952 else:
903 sys.modules[main_name] = FakeModule(self.user_ns)
953 sys.modules[main_name] = FakeModule(self.user_ns)
904
954
905 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
906 """Return a valid local and global user interactive namespaces.
907
908 This builds a dict with the minimal information needed to operate as a
909 valid IPython user namespace, which you can pass to the various
910 embedding classes in ipython. The default implementation returns the
911 same dict for both the locals and the globals to allow functions to
912 refer to variables in the namespace. Customized implementations can
913 return different dicts. The locals dictionary can actually be anything
914 following the basic mapping protocol of a dict, but the globals dict
915 must be a true dict, not even a subclass. It is recommended that any
916 custom object for the locals namespace synchronize with the globals
917 dict somehow.
918
919 Raises TypeError if the provided globals namespace is not a true dict.
920
921 :Parameters:
922 user_ns : dict-like, optional
923 The current user namespace. The items in this namespace should
924 be included in the output. If None, an appropriate blank
925 namespace should be created.
926 user_global_ns : dict, optional
927 The current user global namespace. The items in this namespace
928 should be included in the output. If None, an appropriate
929 blank namespace should be created.
930
931 :Returns:
932 A tuple pair of dictionary-like object to be used as the local namespace
933 of the interpreter and a dict to be used as the global namespace.
934 """
935
936 if user_ns is None:
937 # Set __name__ to __main__ to better match the behavior of the
938 # normal interpreter.
939 user_ns = {'__name__' :'__main__',
940 '__builtins__' : __builtin__,
941 }
942 else:
943 user_ns.setdefault('__name__','__main__')
944 user_ns.setdefault('__builtins__',__builtin__)
945
946 if user_global_ns is None:
947 user_global_ns = user_ns
948 if type(user_global_ns) is not dict:
949 raise TypeError("user_global_ns must be a true dict; got %r"
950 % type(user_global_ns))
951
952 return user_ns, user_global_ns
953
954 def init_user_ns(self):
955 def init_user_ns(self):
955 """Initialize all user-visible namespaces to their minimum defaults.
956 """Initialize all user-visible namespaces to their minimum defaults.
956
957
957 Certain history lists are also initialized here, as they effectively
958 Certain history lists are also initialized here, as they effectively
958 act as user namespaces.
959 act as user namespaces.
959
960
960 Notes
961 Notes
961 -----
962 -----
962 All data structures here are only filled in, they are NOT reset by this
963 All data structures here are only filled in, they are NOT reset by this
963 method. If they were not empty before, data will simply be added to
964 method. If they were not empty before, data will simply be added to
964 therm.
965 therm.
965 """
966 """
966 # Store myself as the public api!!!
967 # Store myself as the public api!!!
967 self.user_ns['get_ipython'] = self.get_ipython
968 self.user_ns['get_ipython'] = self.get_ipython
968
969
969 # make global variables for user access to the histories
970 # make global variables for user access to the histories
970 self.user_ns['_ih'] = self.input_hist
971 self.user_ns['_ih'] = self.input_hist
971 self.user_ns['_oh'] = self.output_hist
972 self.user_ns['_oh'] = self.output_hist
972 self.user_ns['_dh'] = self.dir_hist
973 self.user_ns['_dh'] = self.dir_hist
973
974
974 # user aliases to input and output histories
975 # user aliases to input and output histories
975 self.user_ns['In'] = self.input_hist
976 self.user_ns['In'] = self.input_hist
976 self.user_ns['Out'] = self.output_hist
977 self.user_ns['Out'] = self.output_hist
977
978
978 self.user_ns['_sh'] = shadowns
979 self.user_ns['_sh'] = shadowns
979
980
980 # Put 'help' in the user namespace
981 # Put 'help' in the user namespace
981 try:
982 try:
982 from site import _Helper
983 from site import _Helper
983 self.user_ns['help'] = _Helper()
984 self.user_ns['help'] = _Helper()
984 except ImportError:
985 except ImportError:
985 warn('help() not available - check site.py')
986 warn('help() not available - check site.py')
986
987
987 def reset(self):
988 def reset(self):
988 """Clear all internal namespaces.
989 """Clear all internal namespaces.
989
990
990 Note that this is much more aggressive than %reset, since it clears
991 Note that this is much more aggressive than %reset, since it clears
991 fully all namespaces, as well as all input/output lists.
992 fully all namespaces, as well as all input/output lists.
992 """
993 """
993 for ns in self.ns_refs_table:
994 for ns in self.ns_refs_table:
994 ns.clear()
995 ns.clear()
995
996
996 self.alias_manager.clear_aliases()
997 self.alias_manager.clear_aliases()
997
998
998 # Clear input and output histories
999 # Clear input and output histories
999 self.input_hist[:] = []
1000 self.input_hist[:] = []
1000 self.input_hist_raw[:] = []
1001 self.input_hist_raw[:] = []
1001 self.output_hist.clear()
1002 self.output_hist.clear()
1002
1003
1003 # Restore the user namespaces to minimal usability
1004 # Restore the user namespaces to minimal usability
1004 self.init_user_ns()
1005 self.init_user_ns()
1005
1006
1006 # Restore the default and user aliases
1007 # Restore the default and user aliases
1007 self.alias_manager.init_aliases()
1008 self.alias_manager.init_aliases()
1008
1009
1009 def push(self, variables, interactive=True):
1010 def push(self, variables, interactive=True):
1010 """Inject a group of variables into the IPython user namespace.
1011 """Inject a group of variables into the IPython user namespace.
1011
1012
1012 Parameters
1013 Parameters
1013 ----------
1014 ----------
1014 variables : dict, str or list/tuple of str
1015 variables : dict, str or list/tuple of str
1015 The variables to inject into the user's namespace. If a dict,
1016 The variables to inject into the user's namespace. If a dict,
1016 a simple update is done. If a str, the string is assumed to
1017 a simple update is done. If a str, the string is assumed to
1017 have variable names separated by spaces. A list/tuple of str
1018 have variable names separated by spaces. A list/tuple of str
1018 can also be used to give the variable names. If just the variable
1019 can also be used to give the variable names. If just the variable
1019 names are give (list/tuple/str) then the variable values looked
1020 names are give (list/tuple/str) then the variable values looked
1020 up in the callers frame.
1021 up in the callers frame.
1021 interactive : bool
1022 interactive : bool
1022 If True (default), the variables will be listed with the ``who``
1023 If True (default), the variables will be listed with the ``who``
1023 magic.
1024 magic.
1024 """
1025 """
1025 vdict = None
1026 vdict = None
1026
1027
1027 # We need a dict of name/value pairs to do namespace updates.
1028 # We need a dict of name/value pairs to do namespace updates.
1028 if isinstance(variables, dict):
1029 if isinstance(variables, dict):
1029 vdict = variables
1030 vdict = variables
1030 elif isinstance(variables, (basestring, list, tuple)):
1031 elif isinstance(variables, (basestring, list, tuple)):
1031 if isinstance(variables, basestring):
1032 if isinstance(variables, basestring):
1032 vlist = variables.split()
1033 vlist = variables.split()
1033 else:
1034 else:
1034 vlist = variables
1035 vlist = variables
1035 vdict = {}
1036 vdict = {}
1036 cf = sys._getframe(1)
1037 cf = sys._getframe(1)
1037 for name in vlist:
1038 for name in vlist:
1038 try:
1039 try:
1039 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1040 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1040 except:
1041 except:
1041 print ('Could not get variable %s from %s' %
1042 print ('Could not get variable %s from %s' %
1042 (name,cf.f_code.co_name))
1043 (name,cf.f_code.co_name))
1043 else:
1044 else:
1044 raise ValueError('variables must be a dict/str/list/tuple')
1045 raise ValueError('variables must be a dict/str/list/tuple')
1045
1046
1046 # Propagate variables to user namespace
1047 # Propagate variables to user namespace
1047 self.user_ns.update(vdict)
1048 self.user_ns.update(vdict)
1048
1049
1049 # And configure interactive visibility
1050 # And configure interactive visibility
1050 config_ns = self.user_config_ns
1051 config_ns = self.user_config_ns
1051 if interactive:
1052 if interactive:
1052 for name, val in vdict.iteritems():
1053 for name, val in vdict.iteritems():
1053 config_ns.pop(name, None)
1054 config_ns.pop(name, None)
1054 else:
1055 else:
1055 for name,val in vdict.iteritems():
1056 for name,val in vdict.iteritems():
1056 config_ns[name] = val
1057 config_ns[name] = val
1057
1058
1058 #-------------------------------------------------------------------------
1059 #-------------------------------------------------------------------------
1059 # Things related to history management
1060 # Things related to history management
1060 #-------------------------------------------------------------------------
1061 #-------------------------------------------------------------------------
1061
1062
1062 def init_history(self):
1063 def init_history(self):
1063 # List of input with multi-line handling.
1064 # List of input with multi-line handling.
1064 self.input_hist = InputList()
1065 self.input_hist = InputList()
1065 # This one will hold the 'raw' input history, without any
1066 # This one will hold the 'raw' input history, without any
1066 # pre-processing. This will allow users to retrieve the input just as
1067 # pre-processing. This will allow users to retrieve the input just as
1067 # it was exactly typed in by the user, with %hist -r.
1068 # it was exactly typed in by the user, with %hist -r.
1068 self.input_hist_raw = InputList()
1069 self.input_hist_raw = InputList()
1069
1070
1070 # list of visited directories
1071 # list of visited directories
1071 try:
1072 try:
1072 self.dir_hist = [os.getcwd()]
1073 self.dir_hist = [os.getcwd()]
1073 except OSError:
1074 except OSError:
1074 self.dir_hist = []
1075 self.dir_hist = []
1075
1076
1076 # dict of output history
1077 # dict of output history
1077 self.output_hist = {}
1078 self.output_hist = {}
1078
1079
1079 # Now the history file
1080 # Now the history file
1080 if self.profile:
1081 if self.profile:
1081 histfname = 'history-%s' % self.profile
1082 histfname = 'history-%s' % self.profile
1082 else:
1083 else:
1083 histfname = 'history'
1084 histfname = 'history'
1084 self.histfile = os.path.join(self.ipython_dir, histfname)
1085 self.histfile = os.path.join(self.ipython_dir, histfname)
1085
1086
1086 # Fill the history zero entry, user counter starts at 1
1087 # Fill the history zero entry, user counter starts at 1
1087 self.input_hist.append('\n')
1088 self.input_hist.append('\n')
1088 self.input_hist_raw.append('\n')
1089 self.input_hist_raw.append('\n')
1089
1090
1090 def init_shadow_hist(self):
1091 def init_shadow_hist(self):
1091 try:
1092 try:
1092 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1093 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1093 except exceptions.UnicodeDecodeError:
1094 except exceptions.UnicodeDecodeError:
1094 print "Your ipython_dir can't be decoded to unicode!"
1095 print "Your ipython_dir can't be decoded to unicode!"
1095 print "Please set HOME environment variable to something that"
1096 print "Please set HOME environment variable to something that"
1096 print r"only has ASCII characters, e.g. c:\home"
1097 print r"only has ASCII characters, e.g. c:\home"
1097 print "Now it is", self.ipython_dir
1098 print "Now it is", self.ipython_dir
1098 sys.exit()
1099 sys.exit()
1099 self.shadowhist = ipcorehist.ShadowHist(self.db)
1100 self.shadowhist = ipcorehist.ShadowHist(self.db)
1100
1101
1101 def savehist(self):
1102 def savehist(self):
1102 """Save input history to a file (via readline library)."""
1103 """Save input history to a file (via readline library)."""
1103
1104
1104 try:
1105 try:
1105 self.readline.write_history_file(self.histfile)
1106 self.readline.write_history_file(self.histfile)
1106 except:
1107 except:
1107 print 'Unable to save IPython command history to file: ' + \
1108 print 'Unable to save IPython command history to file: ' + \
1108 `self.histfile`
1109 `self.histfile`
1109
1110
1110 def reloadhist(self):
1111 def reloadhist(self):
1111 """Reload the input history from disk file."""
1112 """Reload the input history from disk file."""
1112
1113
1113 try:
1114 try:
1114 self.readline.clear_history()
1115 self.readline.clear_history()
1115 self.readline.read_history_file(self.shell.histfile)
1116 self.readline.read_history_file(self.shell.histfile)
1116 except AttributeError:
1117 except AttributeError:
1117 pass
1118 pass
1118
1119
1119 def history_saving_wrapper(self, func):
1120 def history_saving_wrapper(self, func):
1120 """ Wrap func for readline history saving
1121 """ Wrap func for readline history saving
1121
1122
1122 Convert func into callable that saves & restores
1123 Convert func into callable that saves & restores
1123 history around the call """
1124 history around the call """
1124
1125
1125 if not self.has_readline:
1126 if not self.has_readline:
1126 return func
1127 return func
1127
1128
1128 def wrapper():
1129 def wrapper():
1129 self.savehist()
1130 self.savehist()
1130 try:
1131 try:
1131 func()
1132 func()
1132 finally:
1133 finally:
1133 readline.read_history_file(self.histfile)
1134 readline.read_history_file(self.histfile)
1134 return wrapper
1135 return wrapper
1135
1136
1136 #-------------------------------------------------------------------------
1137 #-------------------------------------------------------------------------
1137 # Things related to exception handling and tracebacks (not debugging)
1138 # Things related to exception handling and tracebacks (not debugging)
1138 #-------------------------------------------------------------------------
1139 #-------------------------------------------------------------------------
1139
1140
1140 def init_traceback_handlers(self, custom_exceptions):
1141 def init_traceback_handlers(self, custom_exceptions):
1141 # Syntax error handler.
1142 # Syntax error handler.
1142 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1143 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1143
1144
1144 # The interactive one is initialized with an offset, meaning we always
1145 # The interactive one is initialized with an offset, meaning we always
1145 # want to remove the topmost item in the traceback, which is our own
1146 # want to remove the topmost item in the traceback, which is our own
1146 # internal code. Valid modes: ['Plain','Context','Verbose']
1147 # internal code. Valid modes: ['Plain','Context','Verbose']
1147 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1148 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1148 color_scheme='NoColor',
1149 color_scheme='NoColor',
1149 tb_offset = 1)
1150 tb_offset = 1)
1150
1151
1151 # IPython itself shouldn't crash. This will produce a detailed
1152 # IPython itself shouldn't crash. This will produce a detailed
1152 # post-mortem if it does. But we only install the crash handler for
1153 # post-mortem if it does. But we only install the crash handler for
1153 # non-threaded shells, the threaded ones use a normal verbose reporter
1154 # non-threaded shells, the threaded ones use a normal verbose reporter
1154 # and lose the crash handler. This is because exceptions in the main
1155 # and lose the crash handler. This is because exceptions in the main
1155 # thread (such as in GUI code) propagate directly to sys.excepthook,
1156 # thread (such as in GUI code) propagate directly to sys.excepthook,
1156 # and there's no point in printing crash dumps for every user exception.
1157 # and there's no point in printing crash dumps for every user exception.
1157 if self.isthreaded:
1158 if self.isthreaded:
1158 ipCrashHandler = ultratb.FormattedTB()
1159 ipCrashHandler = ultratb.FormattedTB()
1159 else:
1160 else:
1160 from IPython.core import crashhandler
1161 from IPython.core import crashhandler
1161 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1162 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1162 self.set_crash_handler(ipCrashHandler)
1163 self.set_crash_handler(ipCrashHandler)
1163
1164
1164 # and add any custom exception handlers the user may have specified
1165 # and add any custom exception handlers the user may have specified
1165 self.set_custom_exc(*custom_exceptions)
1166 self.set_custom_exc(*custom_exceptions)
1166
1167
1167 def set_crash_handler(self, crashHandler):
1168 def set_crash_handler(self, crashHandler):
1168 """Set the IPython crash handler.
1169 """Set the IPython crash handler.
1169
1170
1170 This must be a callable with a signature suitable for use as
1171 This must be a callable with a signature suitable for use as
1171 sys.excepthook."""
1172 sys.excepthook."""
1172
1173
1173 # Install the given crash handler as the Python exception hook
1174 # Install the given crash handler as the Python exception hook
1174 sys.excepthook = crashHandler
1175 sys.excepthook = crashHandler
1175
1176
1176 # The instance will store a pointer to this, so that runtime code
1177 # The instance will store a pointer to this, so that runtime code
1177 # (such as magics) can access it. This is because during the
1178 # (such as magics) can access it. This is because during the
1178 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1179 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1179 # frameworks).
1180 # frameworks).
1180 self.sys_excepthook = sys.excepthook
1181 self.sys_excepthook = sys.excepthook
1181
1182
1182 def set_custom_exc(self,exc_tuple,handler):
1183 def set_custom_exc(self,exc_tuple,handler):
1183 """set_custom_exc(exc_tuple,handler)
1184 """set_custom_exc(exc_tuple,handler)
1184
1185
1185 Set a custom exception handler, which will be called if any of the
1186 Set a custom exception handler, which will be called if any of the
1186 exceptions in exc_tuple occur in the mainloop (specifically, in the
1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1187 runcode() method.
1188 runcode() method.
1188
1189
1189 Inputs:
1190 Inputs:
1190
1191
1191 - exc_tuple: a *tuple* of valid exceptions to call the defined
1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1192 handler for. It is very important that you use a tuple, and NOT A
1193 handler for. It is very important that you use a tuple, and NOT A
1193 LIST here, because of the way Python's except statement works. If
1194 LIST here, because of the way Python's except statement works. If
1194 you only want to trap a single exception, use a singleton tuple:
1195 you only want to trap a single exception, use a singleton tuple:
1195
1196
1196 exc_tuple == (MyCustomException,)
1197 exc_tuple == (MyCustomException,)
1197
1198
1198 - handler: this must be defined as a function with the following
1199 - handler: this must be defined as a function with the following
1199 basic interface: def my_handler(self,etype,value,tb).
1200 basic interface: def my_handler(self,etype,value,tb).
1200
1201
1201 This will be made into an instance method (via new.instancemethod)
1202 This will be made into an instance method (via new.instancemethod)
1202 of IPython itself, and it will be called if any of the exceptions
1203 of IPython itself, and it will be called if any of the exceptions
1203 listed in the exc_tuple are caught. If the handler is None, an
1204 listed in the exc_tuple are caught. If the handler is None, an
1204 internal basic one is used, which just prints basic info.
1205 internal basic one is used, which just prints basic info.
1205
1206
1206 WARNING: by putting in your own exception handler into IPython's main
1207 WARNING: by putting in your own exception handler into IPython's main
1207 execution loop, you run a very good chance of nasty crashes. This
1208 execution loop, you run a very good chance of nasty crashes. This
1208 facility should only be used if you really know what you are doing."""
1209 facility should only be used if you really know what you are doing."""
1209
1210
1210 assert type(exc_tuple)==type(()) , \
1211 assert type(exc_tuple)==type(()) , \
1211 "The custom exceptions must be given AS A TUPLE."
1212 "The custom exceptions must be given AS A TUPLE."
1212
1213
1213 def dummy_handler(self,etype,value,tb):
1214 def dummy_handler(self,etype,value,tb):
1214 print '*** Simple custom exception handler ***'
1215 print '*** Simple custom exception handler ***'
1215 print 'Exception type :',etype
1216 print 'Exception type :',etype
1216 print 'Exception value:',value
1217 print 'Exception value:',value
1217 print 'Traceback :',tb
1218 print 'Traceback :',tb
1218 print 'Source code :','\n'.join(self.buffer)
1219 print 'Source code :','\n'.join(self.buffer)
1219
1220
1220 if handler is None: handler = dummy_handler
1221 if handler is None: handler = dummy_handler
1221
1222
1222 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1223 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1223 self.custom_exceptions = exc_tuple
1224 self.custom_exceptions = exc_tuple
1224
1225
1225 def excepthook(self, etype, value, tb):
1226 def excepthook(self, etype, value, tb):
1226 """One more defense for GUI apps that call sys.excepthook.
1227 """One more defense for GUI apps that call sys.excepthook.
1227
1228
1228 GUI frameworks like wxPython trap exceptions and call
1229 GUI frameworks like wxPython trap exceptions and call
1229 sys.excepthook themselves. I guess this is a feature that
1230 sys.excepthook themselves. I guess this is a feature that
1230 enables them to keep running after exceptions that would
1231 enables them to keep running after exceptions that would
1231 otherwise kill their mainloop. This is a bother for IPython
1232 otherwise kill their mainloop. This is a bother for IPython
1232 which excepts to catch all of the program exceptions with a try:
1233 which excepts to catch all of the program exceptions with a try:
1233 except: statement.
1234 except: statement.
1234
1235
1235 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1236 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1236 any app directly invokes sys.excepthook, it will look to the user like
1237 any app directly invokes sys.excepthook, it will look to the user like
1237 IPython crashed. In order to work around this, we can disable the
1238 IPython crashed. In order to work around this, we can disable the
1238 CrashHandler and replace it with this excepthook instead, which prints a
1239 CrashHandler and replace it with this excepthook instead, which prints a
1239 regular traceback using our InteractiveTB. In this fashion, apps which
1240 regular traceback using our InteractiveTB. In this fashion, apps which
1240 call sys.excepthook will generate a regular-looking exception from
1241 call sys.excepthook will generate a regular-looking exception from
1241 IPython, and the CrashHandler will only be triggered by real IPython
1242 IPython, and the CrashHandler will only be triggered by real IPython
1242 crashes.
1243 crashes.
1243
1244
1244 This hook should be used sparingly, only in places which are not likely
1245 This hook should be used sparingly, only in places which are not likely
1245 to be true IPython errors.
1246 to be true IPython errors.
1246 """
1247 """
1247 self.showtraceback((etype,value,tb),tb_offset=0)
1248 self.showtraceback((etype,value,tb),tb_offset=0)
1248
1249
1249 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1250 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1250 """Display the exception that just occurred.
1251 """Display the exception that just occurred.
1251
1252
1252 If nothing is known about the exception, this is the method which
1253 If nothing is known about the exception, this is the method which
1253 should be used throughout the code for presenting user tracebacks,
1254 should be used throughout the code for presenting user tracebacks,
1254 rather than directly invoking the InteractiveTB object.
1255 rather than directly invoking the InteractiveTB object.
1255
1256
1256 A specific showsyntaxerror() also exists, but this method can take
1257 A specific showsyntaxerror() also exists, but this method can take
1257 care of calling it if needed, so unless you are explicitly catching a
1258 care of calling it if needed, so unless you are explicitly catching a
1258 SyntaxError exception, don't try to analyze the stack manually and
1259 SyntaxError exception, don't try to analyze the stack manually and
1259 simply call this method."""
1260 simply call this method."""
1260
1261
1261
1262
1262 # Though this won't be called by syntax errors in the input line,
1263 # Though this won't be called by syntax errors in the input line,
1263 # there may be SyntaxError cases whith imported code.
1264 # there may be SyntaxError cases whith imported code.
1264
1265
1265 try:
1266 try:
1266 if exc_tuple is None:
1267 if exc_tuple is None:
1267 etype, value, tb = sys.exc_info()
1268 etype, value, tb = sys.exc_info()
1268 else:
1269 else:
1269 etype, value, tb = exc_tuple
1270 etype, value, tb = exc_tuple
1270
1271
1271 if etype is SyntaxError:
1272 if etype is SyntaxError:
1272 self.showsyntaxerror(filename)
1273 self.showsyntaxerror(filename)
1273 elif etype is UsageError:
1274 elif etype is UsageError:
1274 print "UsageError:", value
1275 print "UsageError:", value
1275 else:
1276 else:
1276 # WARNING: these variables are somewhat deprecated and not
1277 # WARNING: these variables are somewhat deprecated and not
1277 # necessarily safe to use in a threaded environment, but tools
1278 # necessarily safe to use in a threaded environment, but tools
1278 # like pdb depend on their existence, so let's set them. If we
1279 # like pdb depend on their existence, so let's set them. If we
1279 # find problems in the field, we'll need to revisit their use.
1280 # find problems in the field, we'll need to revisit their use.
1280 sys.last_type = etype
1281 sys.last_type = etype
1281 sys.last_value = value
1282 sys.last_value = value
1282 sys.last_traceback = tb
1283 sys.last_traceback = tb
1283
1284
1284 if etype in self.custom_exceptions:
1285 if etype in self.custom_exceptions:
1285 self.CustomTB(etype,value,tb)
1286 self.CustomTB(etype,value,tb)
1286 else:
1287 else:
1287 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1288 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1288 if self.InteractiveTB.call_pdb:
1289 if self.InteractiveTB.call_pdb:
1289 # pdb mucks up readline, fix it back
1290 # pdb mucks up readline, fix it back
1290 self.set_completer()
1291 self.set_completer()
1291 except KeyboardInterrupt:
1292 except KeyboardInterrupt:
1292 self.write("\nKeyboardInterrupt\n")
1293 self.write("\nKeyboardInterrupt\n")
1293
1294
1294 def showsyntaxerror(self, filename=None):
1295 def showsyntaxerror(self, filename=None):
1295 """Display the syntax error that just occurred.
1296 """Display the syntax error that just occurred.
1296
1297
1297 This doesn't display a stack trace because there isn't one.
1298 This doesn't display a stack trace because there isn't one.
1298
1299
1299 If a filename is given, it is stuffed in the exception instead
1300 If a filename is given, it is stuffed in the exception instead
1300 of what was there before (because Python's parser always uses
1301 of what was there before (because Python's parser always uses
1301 "<string>" when reading from a string).
1302 "<string>" when reading from a string).
1302 """
1303 """
1303 etype, value, last_traceback = sys.exc_info()
1304 etype, value, last_traceback = sys.exc_info()
1304
1305
1305 # See note about these variables in showtraceback() below
1306 # See note about these variables in showtraceback() below
1306 sys.last_type = etype
1307 sys.last_type = etype
1307 sys.last_value = value
1308 sys.last_value = value
1308 sys.last_traceback = last_traceback
1309 sys.last_traceback = last_traceback
1309
1310
1310 if filename and etype is SyntaxError:
1311 if filename and etype is SyntaxError:
1311 # Work hard to stuff the correct filename in the exception
1312 # Work hard to stuff the correct filename in the exception
1312 try:
1313 try:
1313 msg, (dummy_filename, lineno, offset, line) = value
1314 msg, (dummy_filename, lineno, offset, line) = value
1314 except:
1315 except:
1315 # Not the format we expect; leave it alone
1316 # Not the format we expect; leave it alone
1316 pass
1317 pass
1317 else:
1318 else:
1318 # Stuff in the right filename
1319 # Stuff in the right filename
1319 try:
1320 try:
1320 # Assume SyntaxError is a class exception
1321 # Assume SyntaxError is a class exception
1321 value = SyntaxError(msg, (filename, lineno, offset, line))
1322 value = SyntaxError(msg, (filename, lineno, offset, line))
1322 except:
1323 except:
1323 # If that failed, assume SyntaxError is a string
1324 # If that failed, assume SyntaxError is a string
1324 value = msg, (filename, lineno, offset, line)
1325 value = msg, (filename, lineno, offset, line)
1325 self.SyntaxTB(etype,value,[])
1326 self.SyntaxTB(etype,value,[])
1326
1327
1327 def edit_syntax_error(self):
1328 def edit_syntax_error(self):
1328 """The bottom half of the syntax error handler called in the main loop.
1329 """The bottom half of the syntax error handler called in the main loop.
1329
1330
1330 Loop until syntax error is fixed or user cancels.
1331 Loop until syntax error is fixed or user cancels.
1331 """
1332 """
1332
1333
1333 while self.SyntaxTB.last_syntax_error:
1334 while self.SyntaxTB.last_syntax_error:
1334 # copy and clear last_syntax_error
1335 # copy and clear last_syntax_error
1335 err = self.SyntaxTB.clear_err_state()
1336 err = self.SyntaxTB.clear_err_state()
1336 if not self._should_recompile(err):
1337 if not self._should_recompile(err):
1337 return
1338 return
1338 try:
1339 try:
1339 # may set last_syntax_error again if a SyntaxError is raised
1340 # may set last_syntax_error again if a SyntaxError is raised
1340 self.safe_execfile(err.filename,self.user_ns)
1341 self.safe_execfile(err.filename,self.user_ns)
1341 except:
1342 except:
1342 self.showtraceback()
1343 self.showtraceback()
1343 else:
1344 else:
1344 try:
1345 try:
1345 f = file(err.filename)
1346 f = file(err.filename)
1346 try:
1347 try:
1347 # This should be inside a display_trap block and I
1348 # This should be inside a display_trap block and I
1348 # think it is.
1349 # think it is.
1349 sys.displayhook(f.read())
1350 sys.displayhook(f.read())
1350 finally:
1351 finally:
1351 f.close()
1352 f.close()
1352 except:
1353 except:
1353 self.showtraceback()
1354 self.showtraceback()
1354
1355
1355 def _should_recompile(self,e):
1356 def _should_recompile(self,e):
1356 """Utility routine for edit_syntax_error"""
1357 """Utility routine for edit_syntax_error"""
1357
1358
1358 if e.filename in ('<ipython console>','<input>','<string>',
1359 if e.filename in ('<ipython console>','<input>','<string>',
1359 '<console>','<BackgroundJob compilation>',
1360 '<console>','<BackgroundJob compilation>',
1360 None):
1361 None):
1361
1362
1362 return False
1363 return False
1363 try:
1364 try:
1364 if (self.autoedit_syntax and
1365 if (self.autoedit_syntax and
1365 not self.ask_yes_no('Return to editor to correct syntax error? '
1366 not self.ask_yes_no('Return to editor to correct syntax error? '
1366 '[Y/n] ','y')):
1367 '[Y/n] ','y')):
1367 return False
1368 return False
1368 except EOFError:
1369 except EOFError:
1369 return False
1370 return False
1370
1371
1371 def int0(x):
1372 def int0(x):
1372 try:
1373 try:
1373 return int(x)
1374 return int(x)
1374 except TypeError:
1375 except TypeError:
1375 return 0
1376 return 0
1376 # always pass integer line and offset values to editor hook
1377 # always pass integer line and offset values to editor hook
1377 try:
1378 try:
1378 self.hooks.fix_error_editor(e.filename,
1379 self.hooks.fix_error_editor(e.filename,
1379 int0(e.lineno),int0(e.offset),e.msg)
1380 int0(e.lineno),int0(e.offset),e.msg)
1380 except TryNext:
1381 except TryNext:
1381 warn('Could not open editor')
1382 warn('Could not open editor')
1382 return False
1383 return False
1383 return True
1384 return True
1384
1385
1385 #-------------------------------------------------------------------------
1386 #-------------------------------------------------------------------------
1386 # Things related to tab completion
1387 # Things related to tab completion
1387 #-------------------------------------------------------------------------
1388 #-------------------------------------------------------------------------
1388
1389
1389 def complete(self, text):
1390 def complete(self, text):
1390 """Return a sorted list of all possible completions on text.
1391 """Return a sorted list of all possible completions on text.
1391
1392
1392 Inputs:
1393 Inputs:
1393
1394
1394 - text: a string of text to be completed on.
1395 - text: a string of text to be completed on.
1395
1396
1396 This is a wrapper around the completion mechanism, similar to what
1397 This is a wrapper around the completion mechanism, similar to what
1397 readline does at the command line when the TAB key is hit. By
1398 readline does at the command line when the TAB key is hit. By
1398 exposing it as a method, it can be used by other non-readline
1399 exposing it as a method, it can be used by other non-readline
1399 environments (such as GUIs) for text completion.
1400 environments (such as GUIs) for text completion.
1400
1401
1401 Simple usage example:
1402 Simple usage example:
1402
1403
1403 In [7]: x = 'hello'
1404 In [7]: x = 'hello'
1404
1405
1405 In [8]: x
1406 In [8]: x
1406 Out[8]: 'hello'
1407 Out[8]: 'hello'
1407
1408
1408 In [9]: print x
1409 In [9]: print x
1409 hello
1410 hello
1410
1411
1411 In [10]: _ip.complete('x.l')
1412 In [10]: _ip.complete('x.l')
1412 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1413 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1413 """
1414 """
1414
1415
1415 # Inject names into __builtin__ so we can complete on the added names.
1416 # Inject names into __builtin__ so we can complete on the added names.
1416 with self.builtin_trap:
1417 with self.builtin_trap:
1417 complete = self.Completer.complete
1418 complete = self.Completer.complete
1418 state = 0
1419 state = 0
1419 # use a dict so we get unique keys, since ipyhton's multiple
1420 # use a dict so we get unique keys, since ipyhton's multiple
1420 # completers can return duplicates. When we make 2.4 a requirement,
1421 # completers can return duplicates. When we make 2.4 a requirement,
1421 # start using sets instead, which are faster.
1422 # start using sets instead, which are faster.
1422 comps = {}
1423 comps = {}
1423 while True:
1424 while True:
1424 newcomp = complete(text,state,line_buffer=text)
1425 newcomp = complete(text,state,line_buffer=text)
1425 if newcomp is None:
1426 if newcomp is None:
1426 break
1427 break
1427 comps[newcomp] = 1
1428 comps[newcomp] = 1
1428 state += 1
1429 state += 1
1429 outcomps = comps.keys()
1430 outcomps = comps.keys()
1430 outcomps.sort()
1431 outcomps.sort()
1431 #print "T:",text,"OC:",outcomps # dbg
1432 #print "T:",text,"OC:",outcomps # dbg
1432 #print "vars:",self.user_ns.keys()
1433 #print "vars:",self.user_ns.keys()
1433 return outcomps
1434 return outcomps
1434
1435
1435 def set_custom_completer(self,completer,pos=0):
1436 def set_custom_completer(self,completer,pos=0):
1436 """Adds a new custom completer function.
1437 """Adds a new custom completer function.
1437
1438
1438 The position argument (defaults to 0) is the index in the completers
1439 The position argument (defaults to 0) is the index in the completers
1439 list where you want the completer to be inserted."""
1440 list where you want the completer to be inserted."""
1440
1441
1441 newcomp = new.instancemethod(completer,self.Completer,
1442 newcomp = new.instancemethod(completer,self.Completer,
1442 self.Completer.__class__)
1443 self.Completer.__class__)
1443 self.Completer.matchers.insert(pos,newcomp)
1444 self.Completer.matchers.insert(pos,newcomp)
1444
1445
1445 def set_completer(self):
1446 def set_completer(self):
1446 """Reset readline's completer to be our own."""
1447 """Reset readline's completer to be our own."""
1447 self.readline.set_completer(self.Completer.complete)
1448 self.readline.set_completer(self.Completer.complete)
1448
1449
1449 def set_completer_frame(self, frame=None):
1450 def set_completer_frame(self, frame=None):
1450 """Set the frame of the completer."""
1451 """Set the frame of the completer."""
1451 if frame:
1452 if frame:
1452 self.Completer.namespace = frame.f_locals
1453 self.Completer.namespace = frame.f_locals
1453 self.Completer.global_namespace = frame.f_globals
1454 self.Completer.global_namespace = frame.f_globals
1454 else:
1455 else:
1455 self.Completer.namespace = self.user_ns
1456 self.Completer.namespace = self.user_ns
1456 self.Completer.global_namespace = self.user_global_ns
1457 self.Completer.global_namespace = self.user_global_ns
1457
1458
1458 #-------------------------------------------------------------------------
1459 #-------------------------------------------------------------------------
1459 # Things related to readline
1460 # Things related to readline
1460 #-------------------------------------------------------------------------
1461 #-------------------------------------------------------------------------
1461
1462
1462 def init_readline(self):
1463 def init_readline(self):
1463 """Command history completion/saving/reloading."""
1464 """Command history completion/saving/reloading."""
1464
1465
1465 if self.readline_use:
1466 if self.readline_use:
1466 import IPython.utils.rlineimpl as readline
1467 import IPython.utils.rlineimpl as readline
1467
1468
1468 self.rl_next_input = None
1469 self.rl_next_input = None
1469 self.rl_do_indent = False
1470 self.rl_do_indent = False
1470
1471
1471 if not self.readline_use or not readline.have_readline:
1472 if not self.readline_use or not readline.have_readline:
1472 self.has_readline = False
1473 self.has_readline = False
1473 self.readline = None
1474 self.readline = None
1474 # Set a number of methods that depend on readline to be no-op
1475 # Set a number of methods that depend on readline to be no-op
1475 self.savehist = no_op
1476 self.savehist = no_op
1476 self.reloadhist = no_op
1477 self.reloadhist = no_op
1477 self.set_completer = no_op
1478 self.set_completer = no_op
1478 self.set_custom_completer = no_op
1479 self.set_custom_completer = no_op
1479 self.set_completer_frame = no_op
1480 self.set_completer_frame = no_op
1480 warn('Readline services not available or not loaded.')
1481 warn('Readline services not available or not loaded.')
1481 else:
1482 else:
1482 self.has_readline = True
1483 self.has_readline = True
1483 self.readline = readline
1484 self.readline = readline
1484 sys.modules['readline'] = readline
1485 sys.modules['readline'] = readline
1485 import atexit
1486 import atexit
1486 from IPython.core.completer import IPCompleter
1487 from IPython.core.completer import IPCompleter
1487 self.Completer = IPCompleter(self,
1488 self.Completer = IPCompleter(self,
1488 self.user_ns,
1489 self.user_ns,
1489 self.user_global_ns,
1490 self.user_global_ns,
1490 self.readline_omit__names,
1491 self.readline_omit__names,
1491 self.alias_manager.alias_table)
1492 self.alias_manager.alias_table)
1492 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1493 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1493 self.strdispatchers['complete_command'] = sdisp
1494 self.strdispatchers['complete_command'] = sdisp
1494 self.Completer.custom_completers = sdisp
1495 self.Completer.custom_completers = sdisp
1495 # Platform-specific configuration
1496 # Platform-specific configuration
1496 if os.name == 'nt':
1497 if os.name == 'nt':
1497 self.readline_startup_hook = readline.set_pre_input_hook
1498 self.readline_startup_hook = readline.set_pre_input_hook
1498 else:
1499 else:
1499 self.readline_startup_hook = readline.set_startup_hook
1500 self.readline_startup_hook = readline.set_startup_hook
1500
1501
1501 # Load user's initrc file (readline config)
1502 # Load user's initrc file (readline config)
1502 # Or if libedit is used, load editrc.
1503 # Or if libedit is used, load editrc.
1503 inputrc_name = os.environ.get('INPUTRC')
1504 inputrc_name = os.environ.get('INPUTRC')
1504 if inputrc_name is None:
1505 if inputrc_name is None:
1505 home_dir = get_home_dir()
1506 home_dir = get_home_dir()
1506 if home_dir is not None:
1507 if home_dir is not None:
1507 inputrc_name = '.inputrc'
1508 inputrc_name = '.inputrc'
1508 if readline.uses_libedit:
1509 if readline.uses_libedit:
1509 inputrc_name = '.editrc'
1510 inputrc_name = '.editrc'
1510 inputrc_name = os.path.join(home_dir, inputrc_name)
1511 inputrc_name = os.path.join(home_dir, inputrc_name)
1511 if os.path.isfile(inputrc_name):
1512 if os.path.isfile(inputrc_name):
1512 try:
1513 try:
1513 readline.read_init_file(inputrc_name)
1514 readline.read_init_file(inputrc_name)
1514 except:
1515 except:
1515 warn('Problems reading readline initialization file <%s>'
1516 warn('Problems reading readline initialization file <%s>'
1516 % inputrc_name)
1517 % inputrc_name)
1517
1518
1518 # save this in sys so embedded copies can restore it properly
1519 # save this in sys so embedded copies can restore it properly
1519 sys.ipcompleter = self.Completer.complete
1520 sys.ipcompleter = self.Completer.complete
1520 self.set_completer()
1521 self.set_completer()
1521
1522
1522 # Configure readline according to user's prefs
1523 # Configure readline according to user's prefs
1523 # This is only done if GNU readline is being used. If libedit
1524 # This is only done if GNU readline is being used. If libedit
1524 # is being used (as on Leopard) the readline config is
1525 # is being used (as on Leopard) the readline config is
1525 # not run as the syntax for libedit is different.
1526 # not run as the syntax for libedit is different.
1526 if not readline.uses_libedit:
1527 if not readline.uses_libedit:
1527 for rlcommand in self.readline_parse_and_bind:
1528 for rlcommand in self.readline_parse_and_bind:
1528 #print "loading rl:",rlcommand # dbg
1529 #print "loading rl:",rlcommand # dbg
1529 readline.parse_and_bind(rlcommand)
1530 readline.parse_and_bind(rlcommand)
1530
1531
1531 # Remove some chars from the delimiters list. If we encounter
1532 # Remove some chars from the delimiters list. If we encounter
1532 # unicode chars, discard them.
1533 # unicode chars, discard them.
1533 delims = readline.get_completer_delims().encode("ascii", "ignore")
1534 delims = readline.get_completer_delims().encode("ascii", "ignore")
1534 delims = delims.translate(string._idmap,
1535 delims = delims.translate(string._idmap,
1535 self.readline_remove_delims)
1536 self.readline_remove_delims)
1536 readline.set_completer_delims(delims)
1537 readline.set_completer_delims(delims)
1537 # otherwise we end up with a monster history after a while:
1538 # otherwise we end up with a monster history after a while:
1538 readline.set_history_length(1000)
1539 readline.set_history_length(1000)
1539 try:
1540 try:
1540 #print '*** Reading readline history' # dbg
1541 #print '*** Reading readline history' # dbg
1541 readline.read_history_file(self.histfile)
1542 readline.read_history_file(self.histfile)
1542 except IOError:
1543 except IOError:
1543 pass # It doesn't exist yet.
1544 pass # It doesn't exist yet.
1544
1545
1545 atexit.register(self.atexit_operations)
1546 atexit.register(self.atexit_operations)
1546 del atexit
1547 del atexit
1547
1548
1548 # Configure auto-indent for all platforms
1549 # Configure auto-indent for all platforms
1549 self.set_autoindent(self.autoindent)
1550 self.set_autoindent(self.autoindent)
1550
1551
1551 def set_next_input(self, s):
1552 def set_next_input(self, s):
1552 """ Sets the 'default' input string for the next command line.
1553 """ Sets the 'default' input string for the next command line.
1553
1554
1554 Requires readline.
1555 Requires readline.
1555
1556
1556 Example:
1557 Example:
1557
1558
1558 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1559 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1559 [D:\ipython]|2> Hello Word_ # cursor is here
1560 [D:\ipython]|2> Hello Word_ # cursor is here
1560 """
1561 """
1561
1562
1562 self.rl_next_input = s
1563 self.rl_next_input = s
1563
1564
1564 def pre_readline(self):
1565 def pre_readline(self):
1565 """readline hook to be used at the start of each line.
1566 """readline hook to be used at the start of each line.
1566
1567
1567 Currently it handles auto-indent only."""
1568 Currently it handles auto-indent only."""
1568
1569
1569 #debugx('self.indent_current_nsp','pre_readline:')
1570 #debugx('self.indent_current_nsp','pre_readline:')
1570
1571
1571 if self.rl_do_indent:
1572 if self.rl_do_indent:
1572 self.readline.insert_text(self._indent_current_str())
1573 self.readline.insert_text(self._indent_current_str())
1573 if self.rl_next_input is not None:
1574 if self.rl_next_input is not None:
1574 self.readline.insert_text(self.rl_next_input)
1575 self.readline.insert_text(self.rl_next_input)
1575 self.rl_next_input = None
1576 self.rl_next_input = None
1576
1577
1577 def _indent_current_str(self):
1578 def _indent_current_str(self):
1578 """return the current level of indentation as a string"""
1579 """return the current level of indentation as a string"""
1579 return self.indent_current_nsp * ' '
1580 return self.indent_current_nsp * ' '
1580
1581
1581 #-------------------------------------------------------------------------
1582 #-------------------------------------------------------------------------
1582 # Things related to magics
1583 # Things related to magics
1583 #-------------------------------------------------------------------------
1584 #-------------------------------------------------------------------------
1584
1585
1585 def init_magics(self):
1586 def init_magics(self):
1586 # Set user colors (don't do it in the constructor above so that it
1587 # Set user colors (don't do it in the constructor above so that it
1587 # doesn't crash if colors option is invalid)
1588 # doesn't crash if colors option is invalid)
1588 self.magic_colors(self.colors)
1589 self.magic_colors(self.colors)
1589
1590
1590 def magic(self,arg_s):
1591 def magic(self,arg_s):
1591 """Call a magic function by name.
1592 """Call a magic function by name.
1592
1593
1593 Input: a string containing the name of the magic function to call and any
1594 Input: a string containing the name of the magic function to call and any
1594 additional arguments to be passed to the magic.
1595 additional arguments to be passed to the magic.
1595
1596
1596 magic('name -opt foo bar') is equivalent to typing at the ipython
1597 magic('name -opt foo bar') is equivalent to typing at the ipython
1597 prompt:
1598 prompt:
1598
1599
1599 In[1]: %name -opt foo bar
1600 In[1]: %name -opt foo bar
1600
1601
1601 To call a magic without arguments, simply use magic('name').
1602 To call a magic without arguments, simply use magic('name').
1602
1603
1603 This provides a proper Python function to call IPython's magics in any
1604 This provides a proper Python function to call IPython's magics in any
1604 valid Python code you can type at the interpreter, including loops and
1605 valid Python code you can type at the interpreter, including loops and
1605 compound statements.
1606 compound statements.
1606 """
1607 """
1607
1608
1608 args = arg_s.split(' ',1)
1609 args = arg_s.split(' ',1)
1609 magic_name = args[0]
1610 magic_name = args[0]
1610 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1611 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1611
1612
1612 try:
1613 try:
1613 magic_args = args[1]
1614 magic_args = args[1]
1614 except IndexError:
1615 except IndexError:
1615 magic_args = ''
1616 magic_args = ''
1616 fn = getattr(self,'magic_'+magic_name,None)
1617 fn = getattr(self,'magic_'+magic_name,None)
1617 if fn is None:
1618 if fn is None:
1618 error("Magic function `%s` not found." % magic_name)
1619 error("Magic function `%s` not found." % magic_name)
1619 else:
1620 else:
1620 magic_args = self.var_expand(magic_args,1)
1621 magic_args = self.var_expand(magic_args,1)
1621 with nested(self.builtin_trap,):
1622 with nested(self.builtin_trap,):
1622 result = fn(magic_args)
1623 result = fn(magic_args)
1623 return result
1624 return result
1624
1625
1625 def define_magic(self, magicname, func):
1626 def define_magic(self, magicname, func):
1626 """Expose own function as magic function for ipython
1627 """Expose own function as magic function for ipython
1627
1628
1628 def foo_impl(self,parameter_s=''):
1629 def foo_impl(self,parameter_s=''):
1629 'My very own magic!. (Use docstrings, IPython reads them).'
1630 'My very own magic!. (Use docstrings, IPython reads them).'
1630 print 'Magic function. Passed parameter is between < >:'
1631 print 'Magic function. Passed parameter is between < >:'
1631 print '<%s>' % parameter_s
1632 print '<%s>' % parameter_s
1632 print 'The self object is:',self
1633 print 'The self object is:',self
1633
1634
1634 self.define_magic('foo',foo_impl)
1635 self.define_magic('foo',foo_impl)
1635 """
1636 """
1636
1637
1637 import new
1638 import new
1638 im = new.instancemethod(func,self, self.__class__)
1639 im = new.instancemethod(func,self, self.__class__)
1639 old = getattr(self, "magic_" + magicname, None)
1640 old = getattr(self, "magic_" + magicname, None)
1640 setattr(self, "magic_" + magicname, im)
1641 setattr(self, "magic_" + magicname, im)
1641 return old
1642 return old
1642
1643
1643 #-------------------------------------------------------------------------
1644 #-------------------------------------------------------------------------
1644 # Things related to macros
1645 # Things related to macros
1645 #-------------------------------------------------------------------------
1646 #-------------------------------------------------------------------------
1646
1647
1647 def define_macro(self, name, themacro):
1648 def define_macro(self, name, themacro):
1648 """Define a new macro
1649 """Define a new macro
1649
1650
1650 Parameters
1651 Parameters
1651 ----------
1652 ----------
1652 name : str
1653 name : str
1653 The name of the macro.
1654 The name of the macro.
1654 themacro : str or Macro
1655 themacro : str or Macro
1655 The action to do upon invoking the macro. If a string, a new
1656 The action to do upon invoking the macro. If a string, a new
1656 Macro object is created by passing the string to it.
1657 Macro object is created by passing the string to it.
1657 """
1658 """
1658
1659
1659 from IPython.core import macro
1660 from IPython.core import macro
1660
1661
1661 if isinstance(themacro, basestring):
1662 if isinstance(themacro, basestring):
1662 themacro = macro.Macro(themacro)
1663 themacro = macro.Macro(themacro)
1663 if not isinstance(themacro, macro.Macro):
1664 if not isinstance(themacro, macro.Macro):
1664 raise ValueError('A macro must be a string or a Macro instance.')
1665 raise ValueError('A macro must be a string or a Macro instance.')
1665 self.user_ns[name] = themacro
1666 self.user_ns[name] = themacro
1666
1667
1667 #-------------------------------------------------------------------------
1668 #-------------------------------------------------------------------------
1668 # Things related to the running of system commands
1669 # Things related to the running of system commands
1669 #-------------------------------------------------------------------------
1670 #-------------------------------------------------------------------------
1670
1671
1671 def system(self, cmd):
1672 def system(self, cmd):
1672 """Make a system call, using IPython."""
1673 """Make a system call, using IPython."""
1673 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1674 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1674
1675
1675 #-------------------------------------------------------------------------
1676 #-------------------------------------------------------------------------
1676 # Things related to aliases
1677 # Things related to aliases
1677 #-------------------------------------------------------------------------
1678 #-------------------------------------------------------------------------
1678
1679
1679 def init_alias(self):
1680 def init_alias(self):
1680 self.alias_manager = AliasManager(self, config=self.config)
1681 self.alias_manager = AliasManager(self, config=self.config)
1681 self.ns_table['alias'] = self.alias_manager.alias_table,
1682 self.ns_table['alias'] = self.alias_manager.alias_table,
1682
1683
1683 #-------------------------------------------------------------------------
1684 #-------------------------------------------------------------------------
1684 # Things related to the running of code
1685 # Things related to the running of code
1685 #-------------------------------------------------------------------------
1686 #-------------------------------------------------------------------------
1686
1687
1687 def ex(self, cmd):
1688 def ex(self, cmd):
1688 """Execute a normal python statement in user namespace."""
1689 """Execute a normal python statement in user namespace."""
1689 with nested(self.builtin_trap,):
1690 with nested(self.builtin_trap,):
1690 exec cmd in self.user_global_ns, self.user_ns
1691 exec cmd in self.user_global_ns, self.user_ns
1691
1692
1692 def ev(self, expr):
1693 def ev(self, expr):
1693 """Evaluate python expression expr in user namespace.
1694 """Evaluate python expression expr in user namespace.
1694
1695
1695 Returns the result of evaluation
1696 Returns the result of evaluation
1696 """
1697 """
1697 with nested(self.builtin_trap,):
1698 with nested(self.builtin_trap,):
1698 return eval(expr, self.user_global_ns, self.user_ns)
1699 return eval(expr, self.user_global_ns, self.user_ns)
1699
1700
1700 def mainloop(self, display_banner=None):
1701 def mainloop(self, display_banner=None):
1701 """Start the mainloop.
1702 """Start the mainloop.
1702
1703
1703 If an optional banner argument is given, it will override the
1704 If an optional banner argument is given, it will override the
1704 internally created default banner.
1705 internally created default banner.
1705 """
1706 """
1706
1707
1707 with nested(self.builtin_trap, self.display_trap):
1708 with nested(self.builtin_trap, self.display_trap):
1708
1709
1709 # if you run stuff with -c <cmd>, raw hist is not updated
1710 # if you run stuff with -c <cmd>, raw hist is not updated
1710 # ensure that it's in sync
1711 # ensure that it's in sync
1711 if len(self.input_hist) != len (self.input_hist_raw):
1712 if len(self.input_hist) != len (self.input_hist_raw):
1712 self.input_hist_raw = InputList(self.input_hist)
1713 self.input_hist_raw = InputList(self.input_hist)
1713
1714
1714 while 1:
1715 while 1:
1715 try:
1716 try:
1716 self.interact(display_banner=display_banner)
1717 self.interact(display_banner=display_banner)
1717 #self.interact_with_readline()
1718 #self.interact_with_readline()
1718 # XXX for testing of a readline-decoupled repl loop, call
1719 # XXX for testing of a readline-decoupled repl loop, call
1719 # interact_with_readline above
1720 # interact_with_readline above
1720 break
1721 break
1721 except KeyboardInterrupt:
1722 except KeyboardInterrupt:
1722 # this should not be necessary, but KeyboardInterrupt
1723 # this should not be necessary, but KeyboardInterrupt
1723 # handling seems rather unpredictable...
1724 # handling seems rather unpredictable...
1724 self.write("\nKeyboardInterrupt in interact()\n")
1725 self.write("\nKeyboardInterrupt in interact()\n")
1725
1726
1726 def interact_prompt(self):
1727 def interact_prompt(self):
1727 """ Print the prompt (in read-eval-print loop)
1728 """ Print the prompt (in read-eval-print loop)
1728
1729
1729 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1730 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1730 used in standard IPython flow.
1731 used in standard IPython flow.
1731 """
1732 """
1732 if self.more:
1733 if self.more:
1733 try:
1734 try:
1734 prompt = self.hooks.generate_prompt(True)
1735 prompt = self.hooks.generate_prompt(True)
1735 except:
1736 except:
1736 self.showtraceback()
1737 self.showtraceback()
1737 if self.autoindent:
1738 if self.autoindent:
1738 self.rl_do_indent = True
1739 self.rl_do_indent = True
1739
1740
1740 else:
1741 else:
1741 try:
1742 try:
1742 prompt = self.hooks.generate_prompt(False)
1743 prompt = self.hooks.generate_prompt(False)
1743 except:
1744 except:
1744 self.showtraceback()
1745 self.showtraceback()
1745 self.write(prompt)
1746 self.write(prompt)
1746
1747
1747 def interact_handle_input(self,line):
1748 def interact_handle_input(self,line):
1748 """ Handle the input line (in read-eval-print loop)
1749 """ Handle the input line (in read-eval-print loop)
1749
1750
1750 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1751 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1751 used in standard IPython flow.
1752 used in standard IPython flow.
1752 """
1753 """
1753 if line.lstrip() == line:
1754 if line.lstrip() == line:
1754 self.shadowhist.add(line.strip())
1755 self.shadowhist.add(line.strip())
1755 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1756 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1756
1757
1757 if line.strip():
1758 if line.strip():
1758 if self.more:
1759 if self.more:
1759 self.input_hist_raw[-1] += '%s\n' % line
1760 self.input_hist_raw[-1] += '%s\n' % line
1760 else:
1761 else:
1761 self.input_hist_raw.append('%s\n' % line)
1762 self.input_hist_raw.append('%s\n' % line)
1762
1763
1763
1764
1764 self.more = self.push_line(lineout)
1765 self.more = self.push_line(lineout)
1765 if (self.SyntaxTB.last_syntax_error and
1766 if (self.SyntaxTB.last_syntax_error and
1766 self.autoedit_syntax):
1767 self.autoedit_syntax):
1767 self.edit_syntax_error()
1768 self.edit_syntax_error()
1768
1769
1769 def interact_with_readline(self):
1770 def interact_with_readline(self):
1770 """ Demo of using interact_handle_input, interact_prompt
1771 """ Demo of using interact_handle_input, interact_prompt
1771
1772
1772 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1773 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1773 it should work like this.
1774 it should work like this.
1774 """
1775 """
1775 self.readline_startup_hook(self.pre_readline)
1776 self.readline_startup_hook(self.pre_readline)
1776 while not self.exit_now:
1777 while not self.exit_now:
1777 self.interact_prompt()
1778 self.interact_prompt()
1778 if self.more:
1779 if self.more:
1779 self.rl_do_indent = True
1780 self.rl_do_indent = True
1780 else:
1781 else:
1781 self.rl_do_indent = False
1782 self.rl_do_indent = False
1782 line = raw_input_original().decode(self.stdin_encoding)
1783 line = raw_input_original().decode(self.stdin_encoding)
1783 self.interact_handle_input(line)
1784 self.interact_handle_input(line)
1784
1785
1785 def interact(self, display_banner=None):
1786 def interact(self, display_banner=None):
1786 """Closely emulate the interactive Python console."""
1787 """Closely emulate the interactive Python console."""
1787
1788
1788 # batch run -> do not interact
1789 # batch run -> do not interact
1789 if self.exit_now:
1790 if self.exit_now:
1790 return
1791 return
1791
1792
1792 if display_banner is None:
1793 if display_banner is None:
1793 display_banner = self.display_banner
1794 display_banner = self.display_banner
1794 if display_banner:
1795 if display_banner:
1795 self.show_banner()
1796 self.show_banner()
1796
1797
1797 more = 0
1798 more = 0
1798
1799
1799 # Mark activity in the builtins
1800 # Mark activity in the builtins
1800 __builtin__.__dict__['__IPYTHON__active'] += 1
1801 __builtin__.__dict__['__IPYTHON__active'] += 1
1801
1802
1802 if self.has_readline:
1803 if self.has_readline:
1803 self.readline_startup_hook(self.pre_readline)
1804 self.readline_startup_hook(self.pre_readline)
1804 # exit_now is set by a call to %Exit or %Quit, through the
1805 # exit_now is set by a call to %Exit or %Quit, through the
1805 # ask_exit callback.
1806 # ask_exit callback.
1806
1807
1807 while not self.exit_now:
1808 while not self.exit_now:
1808 self.hooks.pre_prompt_hook()
1809 self.hooks.pre_prompt_hook()
1809 if more:
1810 if more:
1810 try:
1811 try:
1811 prompt = self.hooks.generate_prompt(True)
1812 prompt = self.hooks.generate_prompt(True)
1812 except:
1813 except:
1813 self.showtraceback()
1814 self.showtraceback()
1814 if self.autoindent:
1815 if self.autoindent:
1815 self.rl_do_indent = True
1816 self.rl_do_indent = True
1816
1817
1817 else:
1818 else:
1818 try:
1819 try:
1819 prompt = self.hooks.generate_prompt(False)
1820 prompt = self.hooks.generate_prompt(False)
1820 except:
1821 except:
1821 self.showtraceback()
1822 self.showtraceback()
1822 try:
1823 try:
1823 line = self.raw_input(prompt, more)
1824 line = self.raw_input(prompt, more)
1824 if self.exit_now:
1825 if self.exit_now:
1825 # quick exit on sys.std[in|out] close
1826 # quick exit on sys.std[in|out] close
1826 break
1827 break
1827 if self.autoindent:
1828 if self.autoindent:
1828 self.rl_do_indent = False
1829 self.rl_do_indent = False
1829
1830
1830 except KeyboardInterrupt:
1831 except KeyboardInterrupt:
1831 #double-guard against keyboardinterrupts during kbdint handling
1832 #double-guard against keyboardinterrupts during kbdint handling
1832 try:
1833 try:
1833 self.write('\nKeyboardInterrupt\n')
1834 self.write('\nKeyboardInterrupt\n')
1834 self.resetbuffer()
1835 self.resetbuffer()
1835 # keep cache in sync with the prompt counter:
1836 # keep cache in sync with the prompt counter:
1836 self.outputcache.prompt_count -= 1
1837 self.outputcache.prompt_count -= 1
1837
1838
1838 if self.autoindent:
1839 if self.autoindent:
1839 self.indent_current_nsp = 0
1840 self.indent_current_nsp = 0
1840 more = 0
1841 more = 0
1841 except KeyboardInterrupt:
1842 except KeyboardInterrupt:
1842 pass
1843 pass
1843 except EOFError:
1844 except EOFError:
1844 if self.autoindent:
1845 if self.autoindent:
1845 self.rl_do_indent = False
1846 self.rl_do_indent = False
1846 if self.has_readline:
1847 if self.has_readline:
1847 self.readline_startup_hook(None)
1848 self.readline_startup_hook(None)
1848 self.write('\n')
1849 self.write('\n')
1849 self.exit()
1850 self.exit()
1850 except bdb.BdbQuit:
1851 except bdb.BdbQuit:
1851 warn('The Python debugger has exited with a BdbQuit exception.\n'
1852 warn('The Python debugger has exited with a BdbQuit exception.\n'
1852 'Because of how pdb handles the stack, it is impossible\n'
1853 'Because of how pdb handles the stack, it is impossible\n'
1853 'for IPython to properly format this particular exception.\n'
1854 'for IPython to properly format this particular exception.\n'
1854 'IPython will resume normal operation.')
1855 'IPython will resume normal operation.')
1855 except:
1856 except:
1856 # exceptions here are VERY RARE, but they can be triggered
1857 # exceptions here are VERY RARE, but they can be triggered
1857 # asynchronously by signal handlers, for example.
1858 # asynchronously by signal handlers, for example.
1858 self.showtraceback()
1859 self.showtraceback()
1859 else:
1860 else:
1860 more = self.push_line(line)
1861 more = self.push_line(line)
1861 if (self.SyntaxTB.last_syntax_error and
1862 if (self.SyntaxTB.last_syntax_error and
1862 self.autoedit_syntax):
1863 self.autoedit_syntax):
1863 self.edit_syntax_error()
1864 self.edit_syntax_error()
1864
1865
1865 # We are off again...
1866 # We are off again...
1866 __builtin__.__dict__['__IPYTHON__active'] -= 1
1867 __builtin__.__dict__['__IPYTHON__active'] -= 1
1867
1868
1868 def safe_execfile(self, fname, *where, **kw):
1869 def safe_execfile(self, fname, *where, **kw):
1869 """A safe version of the builtin execfile().
1870 """A safe version of the builtin execfile().
1870
1871
1871 This version will never throw an exception, but instead print
1872 This version will never throw an exception, but instead print
1872 helpful error messages to the screen. This only works on pure
1873 helpful error messages to the screen. This only works on pure
1873 Python files with the .py extension.
1874 Python files with the .py extension.
1874
1875
1875 Parameters
1876 Parameters
1876 ----------
1877 ----------
1877 fname : string
1878 fname : string
1878 The name of the file to be executed.
1879 The name of the file to be executed.
1879 where : tuple
1880 where : tuple
1880 One or two namespaces, passed to execfile() as (globals,locals).
1881 One or two namespaces, passed to execfile() as (globals,locals).
1881 If only one is given, it is passed as both.
1882 If only one is given, it is passed as both.
1882 exit_ignore : bool (False)
1883 exit_ignore : bool (False)
1883 If True, then don't print errors for non-zero exit statuses.
1884 If True, then don't print errors for non-zero exit statuses.
1884 """
1885 """
1885 kw.setdefault('exit_ignore', False)
1886 kw.setdefault('exit_ignore', False)
1886
1887
1887 fname = os.path.abspath(os.path.expanduser(fname))
1888 fname = os.path.abspath(os.path.expanduser(fname))
1888
1889
1889 # Make sure we have a .py file
1890 # Make sure we have a .py file
1890 if not fname.endswith('.py'):
1891 if not fname.endswith('.py'):
1891 warn('File must end with .py to be run using execfile: <%s>' % fname)
1892 warn('File must end with .py to be run using execfile: <%s>' % fname)
1892
1893
1893 # Make sure we can open the file
1894 # Make sure we can open the file
1894 try:
1895 try:
1895 with open(fname) as thefile:
1896 with open(fname) as thefile:
1896 pass
1897 pass
1897 except:
1898 except:
1898 warn('Could not open file <%s> for safe execution.' % fname)
1899 warn('Could not open file <%s> for safe execution.' % fname)
1899 return
1900 return
1900
1901
1901 # Find things also in current directory. This is needed to mimic the
1902 # Find things also in current directory. This is needed to mimic the
1902 # behavior of running a script from the system command line, where
1903 # behavior of running a script from the system command line, where
1903 # Python inserts the script's directory into sys.path
1904 # Python inserts the script's directory into sys.path
1904 dname = os.path.dirname(fname)
1905 dname = os.path.dirname(fname)
1905
1906
1906 with prepended_to_syspath(dname):
1907 with prepended_to_syspath(dname):
1907 try:
1908 try:
1908 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1909 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1909 # Work around a bug in Python for Windows. The bug was
1910 # Work around a bug in Python for Windows. The bug was
1910 # fixed in in Python 2.5 r54159 and 54158, but that's still
1911 # fixed in in Python 2.5 r54159 and 54158, but that's still
1911 # SVN Python as of March/07. For details, see:
1912 # SVN Python as of March/07. For details, see:
1912 # http://projects.scipy.org/ipython/ipython/ticket/123
1913 # http://projects.scipy.org/ipython/ipython/ticket/123
1913 try:
1914 try:
1914 globs,locs = where[0:2]
1915 globs,locs = where[0:2]
1915 except:
1916 except:
1916 try:
1917 try:
1917 globs = locs = where[0]
1918 globs = locs = where[0]
1918 except:
1919 except:
1919 globs = locs = globals()
1920 globs = locs = globals()
1920 exec file(fname) in globs,locs
1921 exec file(fname) in globs,locs
1921 else:
1922 else:
1922 execfile(fname,*where)
1923 execfile(fname,*where)
1923 except SyntaxError:
1924 except SyntaxError:
1924 self.showsyntaxerror()
1925 self.showsyntaxerror()
1925 warn('Failure executing file: <%s>' % fname)
1926 warn('Failure executing file: <%s>' % fname)
1926 except SystemExit, status:
1927 except SystemExit, status:
1927 # Code that correctly sets the exit status flag to success (0)
1928 # Code that correctly sets the exit status flag to success (0)
1928 # shouldn't be bothered with a traceback. Note that a plain
1929 # shouldn't be bothered with a traceback. Note that a plain
1929 # sys.exit() does NOT set the message to 0 (it's empty) so that
1930 # sys.exit() does NOT set the message to 0 (it's empty) so that
1930 # will still get a traceback. Note that the structure of the
1931 # will still get a traceback. Note that the structure of the
1931 # SystemExit exception changed between Python 2.4 and 2.5, so
1932 # SystemExit exception changed between Python 2.4 and 2.5, so
1932 # the checks must be done in a version-dependent way.
1933 # the checks must be done in a version-dependent way.
1933 show = False
1934 show = False
1934 if status.args[0]==0 and not kw['exit_ignore']:
1935 if status.args[0]==0 and not kw['exit_ignore']:
1935 show = True
1936 show = True
1936 if show:
1937 if show:
1937 self.showtraceback()
1938 self.showtraceback()
1938 warn('Failure executing file: <%s>' % fname)
1939 warn('Failure executing file: <%s>' % fname)
1939 except:
1940 except:
1940 self.showtraceback()
1941 self.showtraceback()
1941 warn('Failure executing file: <%s>' % fname)
1942 warn('Failure executing file: <%s>' % fname)
1942
1943
1943 def safe_execfile_ipy(self, fname):
1944 def safe_execfile_ipy(self, fname):
1944 """Like safe_execfile, but for .ipy files with IPython syntax.
1945 """Like safe_execfile, but for .ipy files with IPython syntax.
1945
1946
1946 Parameters
1947 Parameters
1947 ----------
1948 ----------
1948 fname : str
1949 fname : str
1949 The name of the file to execute. The filename must have a
1950 The name of the file to execute. The filename must have a
1950 .ipy extension.
1951 .ipy extension.
1951 """
1952 """
1952 fname = os.path.abspath(os.path.expanduser(fname))
1953 fname = os.path.abspath(os.path.expanduser(fname))
1953
1954
1954 # Make sure we have a .py file
1955 # Make sure we have a .py file
1955 if not fname.endswith('.ipy'):
1956 if not fname.endswith('.ipy'):
1956 warn('File must end with .py to be run using execfile: <%s>' % fname)
1957 warn('File must end with .py to be run using execfile: <%s>' % fname)
1957
1958
1958 # Make sure we can open the file
1959 # Make sure we can open the file
1959 try:
1960 try:
1960 with open(fname) as thefile:
1961 with open(fname) as thefile:
1961 pass
1962 pass
1962 except:
1963 except:
1963 warn('Could not open file <%s> for safe execution.' % fname)
1964 warn('Could not open file <%s> for safe execution.' % fname)
1964 return
1965 return
1965
1966
1966 # Find things also in current directory. This is needed to mimic the
1967 # Find things also in current directory. This is needed to mimic the
1967 # behavior of running a script from the system command line, where
1968 # behavior of running a script from the system command line, where
1968 # Python inserts the script's directory into sys.path
1969 # Python inserts the script's directory into sys.path
1969 dname = os.path.dirname(fname)
1970 dname = os.path.dirname(fname)
1970
1971
1971 with prepended_to_syspath(dname):
1972 with prepended_to_syspath(dname):
1972 try:
1973 try:
1973 with open(fname) as thefile:
1974 with open(fname) as thefile:
1974 script = thefile.read()
1975 script = thefile.read()
1975 # self.runlines currently captures all exceptions
1976 # self.runlines currently captures all exceptions
1976 # raise in user code. It would be nice if there were
1977 # raise in user code. It would be nice if there were
1977 # versions of runlines, execfile that did raise, so
1978 # versions of runlines, execfile that did raise, so
1978 # we could catch the errors.
1979 # we could catch the errors.
1979 self.runlines(script, clean=True)
1980 self.runlines(script, clean=True)
1980 except:
1981 except:
1981 self.showtraceback()
1982 self.showtraceback()
1982 warn('Unknown failure executing file: <%s>' % fname)
1983 warn('Unknown failure executing file: <%s>' % fname)
1983
1984
1984 def _is_secondary_block_start(self, s):
1985 def _is_secondary_block_start(self, s):
1985 if not s.endswith(':'):
1986 if not s.endswith(':'):
1986 return False
1987 return False
1987 if (s.startswith('elif') or
1988 if (s.startswith('elif') or
1988 s.startswith('else') or
1989 s.startswith('else') or
1989 s.startswith('except') or
1990 s.startswith('except') or
1990 s.startswith('finally')):
1991 s.startswith('finally')):
1991 return True
1992 return True
1992
1993
1993 def cleanup_ipy_script(self, script):
1994 def cleanup_ipy_script(self, script):
1994 """Make a script safe for self.runlines()
1995 """Make a script safe for self.runlines()
1995
1996
1996 Currently, IPython is lines based, with blocks being detected by
1997 Currently, IPython is lines based, with blocks being detected by
1997 empty lines. This is a problem for block based scripts that may
1998 empty lines. This is a problem for block based scripts that may
1998 not have empty lines after blocks. This script adds those empty
1999 not have empty lines after blocks. This script adds those empty
1999 lines to make scripts safe for running in the current line based
2000 lines to make scripts safe for running in the current line based
2000 IPython.
2001 IPython.
2001 """
2002 """
2002 res = []
2003 res = []
2003 lines = script.splitlines()
2004 lines = script.splitlines()
2004 level = 0
2005 level = 0
2005
2006
2006 for l in lines:
2007 for l in lines:
2007 lstripped = l.lstrip()
2008 lstripped = l.lstrip()
2008 stripped = l.strip()
2009 stripped = l.strip()
2009 if not stripped:
2010 if not stripped:
2010 continue
2011 continue
2011 newlevel = len(l) - len(lstripped)
2012 newlevel = len(l) - len(lstripped)
2012 if level > 0 and newlevel == 0 and \
2013 if level > 0 and newlevel == 0 and \
2013 not self._is_secondary_block_start(stripped):
2014 not self._is_secondary_block_start(stripped):
2014 # add empty line
2015 # add empty line
2015 res.append('')
2016 res.append('')
2016 res.append(l)
2017 res.append(l)
2017 level = newlevel
2018 level = newlevel
2018
2019
2019 return '\n'.join(res) + '\n'
2020 return '\n'.join(res) + '\n'
2020
2021
2021 def runlines(self, lines, clean=False):
2022 def runlines(self, lines, clean=False):
2022 """Run a string of one or more lines of source.
2023 """Run a string of one or more lines of source.
2023
2024
2024 This method is capable of running a string containing multiple source
2025 This method is capable of running a string containing multiple source
2025 lines, as if they had been entered at the IPython prompt. Since it
2026 lines, as if they had been entered at the IPython prompt. Since it
2026 exposes IPython's processing machinery, the given strings can contain
2027 exposes IPython's processing machinery, the given strings can contain
2027 magic calls (%magic), special shell access (!cmd), etc.
2028 magic calls (%magic), special shell access (!cmd), etc.
2028 """
2029 """
2029
2030
2030 if isinstance(lines, (list, tuple)):
2031 if isinstance(lines, (list, tuple)):
2031 lines = '\n'.join(lines)
2032 lines = '\n'.join(lines)
2032
2033
2033 if clean:
2034 if clean:
2034 lines = self.cleanup_ipy_script(lines)
2035 lines = self.cleanup_ipy_script(lines)
2035
2036
2036 # We must start with a clean buffer, in case this is run from an
2037 # We must start with a clean buffer, in case this is run from an
2037 # interactive IPython session (via a magic, for example).
2038 # interactive IPython session (via a magic, for example).
2038 self.resetbuffer()
2039 self.resetbuffer()
2039 lines = lines.splitlines()
2040 lines = lines.splitlines()
2040 more = 0
2041 more = 0
2041
2042
2042 with nested(self.builtin_trap, self.display_trap):
2043 with nested(self.builtin_trap, self.display_trap):
2043 for line in lines:
2044 for line in lines:
2044 # skip blank lines so we don't mess up the prompt counter, but do
2045 # skip blank lines so we don't mess up the prompt counter, but do
2045 # NOT skip even a blank line if we are in a code block (more is
2046 # NOT skip even a blank line if we are in a code block (more is
2046 # true)
2047 # true)
2047
2048
2048 if line or more:
2049 if line or more:
2049 # push to raw history, so hist line numbers stay in sync
2050 # push to raw history, so hist line numbers stay in sync
2050 self.input_hist_raw.append("# " + line + "\n")
2051 self.input_hist_raw.append("# " + line + "\n")
2051 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2052 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2052 more = self.push_line(prefiltered)
2053 more = self.push_line(prefiltered)
2053 # IPython's runsource returns None if there was an error
2054 # IPython's runsource returns None if there was an error
2054 # compiling the code. This allows us to stop processing right
2055 # compiling the code. This allows us to stop processing right
2055 # away, so the user gets the error message at the right place.
2056 # away, so the user gets the error message at the right place.
2056 if more is None:
2057 if more is None:
2057 break
2058 break
2058 else:
2059 else:
2059 self.input_hist_raw.append("\n")
2060 self.input_hist_raw.append("\n")
2060 # final newline in case the input didn't have it, so that the code
2061 # final newline in case the input didn't have it, so that the code
2061 # actually does get executed
2062 # actually does get executed
2062 if more:
2063 if more:
2063 self.push_line('\n')
2064 self.push_line('\n')
2064
2065
2065 def runsource(self, source, filename='<input>', symbol='single'):
2066 def runsource(self, source, filename='<input>', symbol='single'):
2066 """Compile and run some source in the interpreter.
2067 """Compile and run some source in the interpreter.
2067
2068
2068 Arguments are as for compile_command().
2069 Arguments are as for compile_command().
2069
2070
2070 One several things can happen:
2071 One several things can happen:
2071
2072
2072 1) The input is incorrect; compile_command() raised an
2073 1) The input is incorrect; compile_command() raised an
2073 exception (SyntaxError or OverflowError). A syntax traceback
2074 exception (SyntaxError or OverflowError). A syntax traceback
2074 will be printed by calling the showsyntaxerror() method.
2075 will be printed by calling the showsyntaxerror() method.
2075
2076
2076 2) The input is incomplete, and more input is required;
2077 2) The input is incomplete, and more input is required;
2077 compile_command() returned None. Nothing happens.
2078 compile_command() returned None. Nothing happens.
2078
2079
2079 3) The input is complete; compile_command() returned a code
2080 3) The input is complete; compile_command() returned a code
2080 object. The code is executed by calling self.runcode() (which
2081 object. The code is executed by calling self.runcode() (which
2081 also handles run-time exceptions, except for SystemExit).
2082 also handles run-time exceptions, except for SystemExit).
2082
2083
2083 The return value is:
2084 The return value is:
2084
2085
2085 - True in case 2
2086 - True in case 2
2086
2087
2087 - False in the other cases, unless an exception is raised, where
2088 - False in the other cases, unless an exception is raised, where
2088 None is returned instead. This can be used by external callers to
2089 None is returned instead. This can be used by external callers to
2089 know whether to continue feeding input or not.
2090 know whether to continue feeding input or not.
2090
2091
2091 The return value can be used to decide whether to use sys.ps1 or
2092 The return value can be used to decide whether to use sys.ps1 or
2092 sys.ps2 to prompt the next line."""
2093 sys.ps2 to prompt the next line."""
2093
2094
2094 # if the source code has leading blanks, add 'if 1:\n' to it
2095 # if the source code has leading blanks, add 'if 1:\n' to it
2095 # this allows execution of indented pasted code. It is tempting
2096 # this allows execution of indented pasted code. It is tempting
2096 # to add '\n' at the end of source to run commands like ' a=1'
2097 # to add '\n' at the end of source to run commands like ' a=1'
2097 # directly, but this fails for more complicated scenarios
2098 # directly, but this fails for more complicated scenarios
2098 source=source.encode(self.stdin_encoding)
2099 source=source.encode(self.stdin_encoding)
2099 if source[:1] in [' ', '\t']:
2100 if source[:1] in [' ', '\t']:
2100 source = 'if 1:\n%s' % source
2101 source = 'if 1:\n%s' % source
2101
2102
2102 try:
2103 try:
2103 code = self.compile(source,filename,symbol)
2104 code = self.compile(source,filename,symbol)
2104 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2105 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2105 # Case 1
2106 # Case 1
2106 self.showsyntaxerror(filename)
2107 self.showsyntaxerror(filename)
2107 return None
2108 return None
2108
2109
2109 if code is None:
2110 if code is None:
2110 # Case 2
2111 # Case 2
2111 return True
2112 return True
2112
2113
2113 # Case 3
2114 # Case 3
2114 # We store the code object so that threaded shells and
2115 # We store the code object so that threaded shells and
2115 # custom exception handlers can access all this info if needed.
2116 # custom exception handlers can access all this info if needed.
2116 # The source corresponding to this can be obtained from the
2117 # The source corresponding to this can be obtained from the
2117 # buffer attribute as '\n'.join(self.buffer).
2118 # buffer attribute as '\n'.join(self.buffer).
2118 self.code_to_run = code
2119 self.code_to_run = code
2119 # now actually execute the code object
2120 # now actually execute the code object
2120 if self.runcode(code) == 0:
2121 if self.runcode(code) == 0:
2121 return False
2122 return False
2122 else:
2123 else:
2123 return None
2124 return None
2124
2125
2125 def runcode(self,code_obj):
2126 def runcode(self,code_obj):
2126 """Execute a code object.
2127 """Execute a code object.
2127
2128
2128 When an exception occurs, self.showtraceback() is called to display a
2129 When an exception occurs, self.showtraceback() is called to display a
2129 traceback.
2130 traceback.
2130
2131
2131 Return value: a flag indicating whether the code to be run completed
2132 Return value: a flag indicating whether the code to be run completed
2132 successfully:
2133 successfully:
2133
2134
2134 - 0: successful execution.
2135 - 0: successful execution.
2135 - 1: an error occurred.
2136 - 1: an error occurred.
2136 """
2137 """
2137
2138
2138 # Set our own excepthook in case the user code tries to call it
2139 # Set our own excepthook in case the user code tries to call it
2139 # directly, so that the IPython crash handler doesn't get triggered
2140 # directly, so that the IPython crash handler doesn't get triggered
2140 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2141 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2141
2142
2142 # we save the original sys.excepthook in the instance, in case config
2143 # we save the original sys.excepthook in the instance, in case config
2143 # code (such as magics) needs access to it.
2144 # code (such as magics) needs access to it.
2144 self.sys_excepthook = old_excepthook
2145 self.sys_excepthook = old_excepthook
2145 outflag = 1 # happens in more places, so it's easier as default
2146 outflag = 1 # happens in more places, so it's easier as default
2146 try:
2147 try:
2147 try:
2148 try:
2148 self.hooks.pre_runcode_hook()
2149 self.hooks.pre_runcode_hook()
2149 exec code_obj in self.user_global_ns, self.user_ns
2150 exec code_obj in self.user_global_ns, self.user_ns
2150 finally:
2151 finally:
2151 # Reset our crash handler in place
2152 # Reset our crash handler in place
2152 sys.excepthook = old_excepthook
2153 sys.excepthook = old_excepthook
2153 except SystemExit:
2154 except SystemExit:
2154 self.resetbuffer()
2155 self.resetbuffer()
2155 self.showtraceback()
2156 self.showtraceback()
2156 warn("Type %exit or %quit to exit IPython "
2157 warn("Type %exit or %quit to exit IPython "
2157 "(%Exit or %Quit do so unconditionally).",level=1)
2158 "(%Exit or %Quit do so unconditionally).",level=1)
2158 except self.custom_exceptions:
2159 except self.custom_exceptions:
2159 etype,value,tb = sys.exc_info()
2160 etype,value,tb = sys.exc_info()
2160 self.CustomTB(etype,value,tb)
2161 self.CustomTB(etype,value,tb)
2161 except:
2162 except:
2162 self.showtraceback()
2163 self.showtraceback()
2163 else:
2164 else:
2164 outflag = 0
2165 outflag = 0
2165 if softspace(sys.stdout, 0):
2166 if softspace(sys.stdout, 0):
2166 print
2167 print
2167 # Flush out code object which has been run (and source)
2168 # Flush out code object which has been run (and source)
2168 self.code_to_run = None
2169 self.code_to_run = None
2169 return outflag
2170 return outflag
2170
2171
2171 def push_line(self, line):
2172 def push_line(self, line):
2172 """Push a line to the interpreter.
2173 """Push a line to the interpreter.
2173
2174
2174 The line should not have a trailing newline; it may have
2175 The line should not have a trailing newline; it may have
2175 internal newlines. The line is appended to a buffer and the
2176 internal newlines. The line is appended to a buffer and the
2176 interpreter's runsource() method is called with the
2177 interpreter's runsource() method is called with the
2177 concatenated contents of the buffer as source. If this
2178 concatenated contents of the buffer as source. If this
2178 indicates that the command was executed or invalid, the buffer
2179 indicates that the command was executed or invalid, the buffer
2179 is reset; otherwise, the command is incomplete, and the buffer
2180 is reset; otherwise, the command is incomplete, and the buffer
2180 is left as it was after the line was appended. The return
2181 is left as it was after the line was appended. The return
2181 value is 1 if more input is required, 0 if the line was dealt
2182 value is 1 if more input is required, 0 if the line was dealt
2182 with in some way (this is the same as runsource()).
2183 with in some way (this is the same as runsource()).
2183 """
2184 """
2184
2185
2185 # autoindent management should be done here, and not in the
2186 # autoindent management should be done here, and not in the
2186 # interactive loop, since that one is only seen by keyboard input. We
2187 # interactive loop, since that one is only seen by keyboard input. We
2187 # need this done correctly even for code run via runlines (which uses
2188 # need this done correctly even for code run via runlines (which uses
2188 # push).
2189 # push).
2189
2190
2190 #print 'push line: <%s>' % line # dbg
2191 #print 'push line: <%s>' % line # dbg
2191 for subline in line.splitlines():
2192 for subline in line.splitlines():
2192 self._autoindent_update(subline)
2193 self._autoindent_update(subline)
2193 self.buffer.append(line)
2194 self.buffer.append(line)
2194 more = self.runsource('\n'.join(self.buffer), self.filename)
2195 more = self.runsource('\n'.join(self.buffer), self.filename)
2195 if not more:
2196 if not more:
2196 self.resetbuffer()
2197 self.resetbuffer()
2197 return more
2198 return more
2198
2199
2199 def _autoindent_update(self,line):
2200 def _autoindent_update(self,line):
2200 """Keep track of the indent level."""
2201 """Keep track of the indent level."""
2201
2202
2202 #debugx('line')
2203 #debugx('line')
2203 #debugx('self.indent_current_nsp')
2204 #debugx('self.indent_current_nsp')
2204 if self.autoindent:
2205 if self.autoindent:
2205 if line:
2206 if line:
2206 inisp = num_ini_spaces(line)
2207 inisp = num_ini_spaces(line)
2207 if inisp < self.indent_current_nsp:
2208 if inisp < self.indent_current_nsp:
2208 self.indent_current_nsp = inisp
2209 self.indent_current_nsp = inisp
2209
2210
2210 if line[-1] == ':':
2211 if line[-1] == ':':
2211 self.indent_current_nsp += 4
2212 self.indent_current_nsp += 4
2212 elif dedent_re.match(line):
2213 elif dedent_re.match(line):
2213 self.indent_current_nsp -= 4
2214 self.indent_current_nsp -= 4
2214 else:
2215 else:
2215 self.indent_current_nsp = 0
2216 self.indent_current_nsp = 0
2216
2217
2217 def resetbuffer(self):
2218 def resetbuffer(self):
2218 """Reset the input buffer."""
2219 """Reset the input buffer."""
2219 self.buffer[:] = []
2220 self.buffer[:] = []
2220
2221
2221 def raw_input(self,prompt='',continue_prompt=False):
2222 def raw_input(self,prompt='',continue_prompt=False):
2222 """Write a prompt and read a line.
2223 """Write a prompt and read a line.
2223
2224
2224 The returned line does not include the trailing newline.
2225 The returned line does not include the trailing newline.
2225 When the user enters the EOF key sequence, EOFError is raised.
2226 When the user enters the EOF key sequence, EOFError is raised.
2226
2227
2227 Optional inputs:
2228 Optional inputs:
2228
2229
2229 - prompt(''): a string to be printed to prompt the user.
2230 - prompt(''): a string to be printed to prompt the user.
2230
2231
2231 - continue_prompt(False): whether this line is the first one or a
2232 - continue_prompt(False): whether this line is the first one or a
2232 continuation in a sequence of inputs.
2233 continuation in a sequence of inputs.
2233 """
2234 """
2234 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2235 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2235
2236
2236 # Code run by the user may have modified the readline completer state.
2237 # Code run by the user may have modified the readline completer state.
2237 # We must ensure that our completer is back in place.
2238 # We must ensure that our completer is back in place.
2238
2239
2239 if self.has_readline:
2240 if self.has_readline:
2240 self.set_completer()
2241 self.set_completer()
2241
2242
2242 try:
2243 try:
2243 line = raw_input_original(prompt).decode(self.stdin_encoding)
2244 line = raw_input_original(prompt).decode(self.stdin_encoding)
2244 except ValueError:
2245 except ValueError:
2245 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2246 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2246 " or sys.stdout.close()!\nExiting IPython!")
2247 " or sys.stdout.close()!\nExiting IPython!")
2247 self.ask_exit()
2248 self.ask_exit()
2248 return ""
2249 return ""
2249
2250
2250 # Try to be reasonably smart about not re-indenting pasted input more
2251 # Try to be reasonably smart about not re-indenting pasted input more
2251 # than necessary. We do this by trimming out the auto-indent initial
2252 # than necessary. We do this by trimming out the auto-indent initial
2252 # spaces, if the user's actual input started itself with whitespace.
2253 # spaces, if the user's actual input started itself with whitespace.
2253 #debugx('self.buffer[-1]')
2254 #debugx('self.buffer[-1]')
2254
2255
2255 if self.autoindent:
2256 if self.autoindent:
2256 if num_ini_spaces(line) > self.indent_current_nsp:
2257 if num_ini_spaces(line) > self.indent_current_nsp:
2257 line = line[self.indent_current_nsp:]
2258 line = line[self.indent_current_nsp:]
2258 self.indent_current_nsp = 0
2259 self.indent_current_nsp = 0
2259
2260
2260 # store the unfiltered input before the user has any chance to modify
2261 # store the unfiltered input before the user has any chance to modify
2261 # it.
2262 # it.
2262 if line.strip():
2263 if line.strip():
2263 if continue_prompt:
2264 if continue_prompt:
2264 self.input_hist_raw[-1] += '%s\n' % line
2265 self.input_hist_raw[-1] += '%s\n' % line
2265 if self.has_readline and self.readline_use:
2266 if self.has_readline and self.readline_use:
2266 try:
2267 try:
2267 histlen = self.readline.get_current_history_length()
2268 histlen = self.readline.get_current_history_length()
2268 if histlen > 1:
2269 if histlen > 1:
2269 newhist = self.input_hist_raw[-1].rstrip()
2270 newhist = self.input_hist_raw[-1].rstrip()
2270 self.readline.remove_history_item(histlen-1)
2271 self.readline.remove_history_item(histlen-1)
2271 self.readline.replace_history_item(histlen-2,
2272 self.readline.replace_history_item(histlen-2,
2272 newhist.encode(self.stdin_encoding))
2273 newhist.encode(self.stdin_encoding))
2273 except AttributeError:
2274 except AttributeError:
2274 pass # re{move,place}_history_item are new in 2.4.
2275 pass # re{move,place}_history_item are new in 2.4.
2275 else:
2276 else:
2276 self.input_hist_raw.append('%s\n' % line)
2277 self.input_hist_raw.append('%s\n' % line)
2277 # only entries starting at first column go to shadow history
2278 # only entries starting at first column go to shadow history
2278 if line.lstrip() == line:
2279 if line.lstrip() == line:
2279 self.shadowhist.add(line.strip())
2280 self.shadowhist.add(line.strip())
2280 elif not continue_prompt:
2281 elif not continue_prompt:
2281 self.input_hist_raw.append('\n')
2282 self.input_hist_raw.append('\n')
2282 try:
2283 try:
2283 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2284 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2284 except:
2285 except:
2285 # blanket except, in case a user-defined prefilter crashes, so it
2286 # blanket except, in case a user-defined prefilter crashes, so it
2286 # can't take all of ipython with it.
2287 # can't take all of ipython with it.
2287 self.showtraceback()
2288 self.showtraceback()
2288 return ''
2289 return ''
2289 else:
2290 else:
2290 return lineout
2291 return lineout
2291
2292
2292 #-------------------------------------------------------------------------
2293 #-------------------------------------------------------------------------
2293 # Working with components
2294 # Working with components
2294 #-------------------------------------------------------------------------
2295 #-------------------------------------------------------------------------
2295
2296
2296 def get_component(self, name=None, klass=None):
2297 def get_component(self, name=None, klass=None):
2297 """Fetch a component by name and klass in my tree."""
2298 """Fetch a component by name and klass in my tree."""
2298 c = Component.get_instances(root=self, name=name, klass=klass)
2299 c = Component.get_instances(root=self, name=name, klass=klass)
2299 if len(c) == 0:
2300 if len(c) == 0:
2300 return None
2301 return None
2301 if len(c) == 1:
2302 if len(c) == 1:
2302 return c[0]
2303 return c[0]
2303 else:
2304 else:
2304 return c
2305 return c
2305
2306
2306 #-------------------------------------------------------------------------
2307 #-------------------------------------------------------------------------
2307 # IPython extensions
2308 # IPython extensions
2308 #-------------------------------------------------------------------------
2309 #-------------------------------------------------------------------------
2309
2310
2310 def load_extension(self, module_str):
2311 def load_extension(self, module_str):
2311 """Load an IPython extension by its module name.
2312 """Load an IPython extension by its module name.
2312
2313
2313 An IPython extension is an importable Python module that has
2314 An IPython extension is an importable Python module that has
2314 a function with the signature::
2315 a function with the signature::
2315
2316
2316 def load_ipython_extension(ipython):
2317 def load_ipython_extension(ipython):
2317 # Do things with ipython
2318 # Do things with ipython
2318
2319
2319 This function is called after your extension is imported and the
2320 This function is called after your extension is imported and the
2320 currently active :class:`InteractiveShell` instance is passed as
2321 currently active :class:`InteractiveShell` instance is passed as
2321 the only argument. You can do anything you want with IPython at
2322 the only argument. You can do anything you want with IPython at
2322 that point, including defining new magic and aliases, adding new
2323 that point, including defining new magic and aliases, adding new
2323 components, etc.
2324 components, etc.
2324
2325
2325 The :func:`load_ipython_extension` will be called again is you
2326 The :func:`load_ipython_extension` will be called again is you
2326 load or reload the extension again. It is up to the extension
2327 load or reload the extension again. It is up to the extension
2327 author to add code to manage that.
2328 author to add code to manage that.
2328
2329
2329 You can put your extension modules anywhere you want, as long as
2330 You can put your extension modules anywhere you want, as long as
2330 they can be imported by Python's standard import mechanism. However,
2331 they can be imported by Python's standard import mechanism. However,
2331 to make it easy to write extensions, you can also put your extensions
2332 to make it easy to write extensions, you can also put your extensions
2332 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2333 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2333 is added to ``sys.path`` automatically.
2334 is added to ``sys.path`` automatically.
2334 """
2335 """
2335 from IPython.utils.syspathcontext import prepended_to_syspath
2336 from IPython.utils.syspathcontext import prepended_to_syspath
2336
2337
2337 if module_str not in sys.modules:
2338 if module_str not in sys.modules:
2338 with prepended_to_syspath(self.ipython_extension_dir):
2339 with prepended_to_syspath(self.ipython_extension_dir):
2339 __import__(module_str)
2340 __import__(module_str)
2340 mod = sys.modules[module_str]
2341 mod = sys.modules[module_str]
2341 self._call_load_ipython_extension(mod)
2342 self._call_load_ipython_extension(mod)
2342
2343
2343 def unload_extension(self, module_str):
2344 def unload_extension(self, module_str):
2344 """Unload an IPython extension by its module name.
2345 """Unload an IPython extension by its module name.
2345
2346
2346 This function looks up the extension's name in ``sys.modules`` and
2347 This function looks up the extension's name in ``sys.modules`` and
2347 simply calls ``mod.unload_ipython_extension(self)``.
2348 simply calls ``mod.unload_ipython_extension(self)``.
2348 """
2349 """
2349 if module_str in sys.modules:
2350 if module_str in sys.modules:
2350 mod = sys.modules[module_str]
2351 mod = sys.modules[module_str]
2351 self._call_unload_ipython_extension(mod)
2352 self._call_unload_ipython_extension(mod)
2352
2353
2353 def reload_extension(self, module_str):
2354 def reload_extension(self, module_str):
2354 """Reload an IPython extension by calling reload.
2355 """Reload an IPython extension by calling reload.
2355
2356
2356 If the module has not been loaded before,
2357 If the module has not been loaded before,
2357 :meth:`InteractiveShell.load_extension` is called. Otherwise
2358 :meth:`InteractiveShell.load_extension` is called. Otherwise
2358 :func:`reload` is called and then the :func:`load_ipython_extension`
2359 :func:`reload` is called and then the :func:`load_ipython_extension`
2359 function of the module, if it exists is called.
2360 function of the module, if it exists is called.
2360 """
2361 """
2361 from IPython.utils.syspathcontext import prepended_to_syspath
2362 from IPython.utils.syspathcontext import prepended_to_syspath
2362
2363
2363 with prepended_to_syspath(self.ipython_extension_dir):
2364 with prepended_to_syspath(self.ipython_extension_dir):
2364 if module_str in sys.modules:
2365 if module_str in sys.modules:
2365 mod = sys.modules[module_str]
2366 mod = sys.modules[module_str]
2366 reload(mod)
2367 reload(mod)
2367 self._call_load_ipython_extension(mod)
2368 self._call_load_ipython_extension(mod)
2368 else:
2369 else:
2369 self.load_extension(module_str)
2370 self.load_extension(module_str)
2370
2371
2371 def _call_load_ipython_extension(self, mod):
2372 def _call_load_ipython_extension(self, mod):
2372 if hasattr(mod, 'load_ipython_extension'):
2373 if hasattr(mod, 'load_ipython_extension'):
2373 mod.load_ipython_extension(self)
2374 mod.load_ipython_extension(self)
2374
2375
2375 def _call_unload_ipython_extension(self, mod):
2376 def _call_unload_ipython_extension(self, mod):
2376 if hasattr(mod, 'unload_ipython_extension'):
2377 if hasattr(mod, 'unload_ipython_extension'):
2377 mod.unload_ipython_extension(self)
2378 mod.unload_ipython_extension(self)
2378
2379
2379 #-------------------------------------------------------------------------
2380 #-------------------------------------------------------------------------
2380 # Things related to the prefilter
2381 # Things related to the prefilter
2381 #-------------------------------------------------------------------------
2382 #-------------------------------------------------------------------------
2382
2383
2383 def init_prefilter(self):
2384 def init_prefilter(self):
2384 self.prefilter_manager = PrefilterManager(self, config=self.config)
2385 self.prefilter_manager = PrefilterManager(self, config=self.config)
2385
2386
2386 #-------------------------------------------------------------------------
2387 #-------------------------------------------------------------------------
2387 # Utilities
2388 # Utilities
2388 #-------------------------------------------------------------------------
2389 #-------------------------------------------------------------------------
2389
2390
2390 def getoutput(self, cmd):
2391 def getoutput(self, cmd):
2391 return getoutput(self.var_expand(cmd,depth=2),
2392 return getoutput(self.var_expand(cmd,depth=2),
2392 header=self.system_header,
2393 header=self.system_header,
2393 verbose=self.system_verbose)
2394 verbose=self.system_verbose)
2394
2395
2395 def getoutputerror(self, cmd):
2396 def getoutputerror(self, cmd):
2396 return getoutputerror(self.var_expand(cmd,depth=2),
2397 return getoutputerror(self.var_expand(cmd,depth=2),
2397 header=self.system_header,
2398 header=self.system_header,
2398 verbose=self.system_verbose)
2399 verbose=self.system_verbose)
2399
2400
2400 def var_expand(self,cmd,depth=0):
2401 def var_expand(self,cmd,depth=0):
2401 """Expand python variables in a string.
2402 """Expand python variables in a string.
2402
2403
2403 The depth argument indicates how many frames above the caller should
2404 The depth argument indicates how many frames above the caller should
2404 be walked to look for the local namespace where to expand variables.
2405 be walked to look for the local namespace where to expand variables.
2405
2406
2406 The global namespace for expansion is always the user's interactive
2407 The global namespace for expansion is always the user's interactive
2407 namespace.
2408 namespace.
2408 """
2409 """
2409
2410
2410 return str(ItplNS(cmd,
2411 return str(ItplNS(cmd,
2411 self.user_ns, # globals
2412 self.user_ns, # globals
2412 # Skip our own frame in searching for locals:
2413 # Skip our own frame in searching for locals:
2413 sys._getframe(depth+1).f_locals # locals
2414 sys._getframe(depth+1).f_locals # locals
2414 ))
2415 ))
2415
2416
2416 def mktempfile(self,data=None):
2417 def mktempfile(self,data=None):
2417 """Make a new tempfile and return its filename.
2418 """Make a new tempfile and return its filename.
2418
2419
2419 This makes a call to tempfile.mktemp, but it registers the created
2420 This makes a call to tempfile.mktemp, but it registers the created
2420 filename internally so ipython cleans it up at exit time.
2421 filename internally so ipython cleans it up at exit time.
2421
2422
2422 Optional inputs:
2423 Optional inputs:
2423
2424
2424 - data(None): if data is given, it gets written out to the temp file
2425 - data(None): if data is given, it gets written out to the temp file
2425 immediately, and the file is closed again."""
2426 immediately, and the file is closed again."""
2426
2427
2427 filename = tempfile.mktemp('.py','ipython_edit_')
2428 filename = tempfile.mktemp('.py','ipython_edit_')
2428 self.tempfiles.append(filename)
2429 self.tempfiles.append(filename)
2429
2430
2430 if data:
2431 if data:
2431 tmp_file = open(filename,'w')
2432 tmp_file = open(filename,'w')
2432 tmp_file.write(data)
2433 tmp_file.write(data)
2433 tmp_file.close()
2434 tmp_file.close()
2434 return filename
2435 return filename
2435
2436
2436 def write(self,data):
2437 def write(self,data):
2437 """Write a string to the default output"""
2438 """Write a string to the default output"""
2438 Term.cout.write(data)
2439 Term.cout.write(data)
2439
2440
2440 def write_err(self,data):
2441 def write_err(self,data):
2441 """Write a string to the default error output"""
2442 """Write a string to the default error output"""
2442 Term.cerr.write(data)
2443 Term.cerr.write(data)
2443
2444
2444 def ask_yes_no(self,prompt,default=True):
2445 def ask_yes_no(self,prompt,default=True):
2445 if self.quiet:
2446 if self.quiet:
2446 return True
2447 return True
2447 return ask_yes_no(prompt,default)
2448 return ask_yes_no(prompt,default)
2448
2449
2449 #-------------------------------------------------------------------------
2450 #-------------------------------------------------------------------------
2450 # Things related to GUI support and pylab
2451 # Things related to GUI support and pylab
2451 #-------------------------------------------------------------------------
2452 #-------------------------------------------------------------------------
2452
2453
2453 def enable_pylab(self, gui=None):
2454 def enable_pylab(self, gui=None):
2454 """Activate pylab support at runtime.
2455 """Activate pylab support at runtime.
2455
2456
2456 This turns on support for matplotlib, preloads into the interactive
2457 This turns on support for matplotlib, preloads into the interactive
2457 namespace all of numpy and pylab, and configures IPython to correcdtly
2458 namespace all of numpy and pylab, and configures IPython to correcdtly
2458 interact with the GUI event loop. The GUI backend to be used can be
2459 interact with the GUI event loop. The GUI backend to be used can be
2459 optionally selected with the optional :param:`gui` argument.
2460 optionally selected with the optional :param:`gui` argument.
2460
2461
2461 Parameters
2462 Parameters
2462 ----------
2463 ----------
2463 gui : optional, string
2464 gui : optional, string
2464
2465
2465 If given, dictates the choice of matplotlib GUI backend to use
2466 If given, dictates the choice of matplotlib GUI backend to use
2466 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
2467 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
2467 'gtk'), otherwise we use the default chosen by matplotlib (as
2468 'gtk'), otherwise we use the default chosen by matplotlib (as
2468 dictated by the matplotlib build-time options plus the user's
2469 dictated by the matplotlib build-time options plus the user's
2469 matplotlibrc configuration file).
2470 matplotlibrc configuration file).
2470 """
2471 """
2471 # We want to prevent the loading of pylab to pollute the user's
2472 # We want to prevent the loading of pylab to pollute the user's
2472 # namespace as shown by the %who* magics, so we execute the activation
2473 # namespace as shown by the %who* magics, so we execute the activation
2473 # code in an empty namespace, and we update *both* user_ns and
2474 # code in an empty namespace, and we update *both* user_ns and
2474 # user_config_ns with this information.
2475 # user_config_ns with this information.
2475 ns = {}
2476 ns = {}
2476 gui = pylab_activate(ns, gui)
2477 gui = pylab_activate(ns, gui)
2477 self.user_ns.update(ns)
2478 self.user_ns.update(ns)
2478 self.user_config_ns.update(ns)
2479 self.user_config_ns.update(ns)
2479 # Now we must activate the gui pylab wants to use, and fix %run to take
2480 # Now we must activate the gui pylab wants to use, and fix %run to take
2480 # plot updates into account
2481 # plot updates into account
2481 enable_gui(gui)
2482 enable_gui(gui)
2482 self.magic_run = self._pylab_magic_run
2483 self.magic_run = self._pylab_magic_run
2483
2484
2484 #-------------------------------------------------------------------------
2485 #-------------------------------------------------------------------------
2485 # Things related to IPython exiting
2486 # Things related to IPython exiting
2486 #-------------------------------------------------------------------------
2487 #-------------------------------------------------------------------------
2487
2488
2488 def ask_exit(self):
2489 def ask_exit(self):
2489 """ Ask the shell to exit. Can be overiden and used as a callback. """
2490 """ Ask the shell to exit. Can be overiden and used as a callback. """
2490 self.exit_now = True
2491 self.exit_now = True
2491
2492
2492 def exit(self):
2493 def exit(self):
2493 """Handle interactive exit.
2494 """Handle interactive exit.
2494
2495
2495 This method calls the ask_exit callback."""
2496 This method calls the ask_exit callback."""
2496 if self.confirm_exit:
2497 if self.confirm_exit:
2497 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2498 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2498 self.ask_exit()
2499 self.ask_exit()
2499 else:
2500 else:
2500 self.ask_exit()
2501 self.ask_exit()
2501
2502
2502 def atexit_operations(self):
2503 def atexit_operations(self):
2503 """This will be executed at the time of exit.
2504 """This will be executed at the time of exit.
2504
2505
2505 Saving of persistent data should be performed here.
2506 Saving of persistent data should be performed here.
2506 """
2507 """
2507 self.savehist()
2508 self.savehist()
2508
2509
2509 # Cleanup all tempfiles left around
2510 # Cleanup all tempfiles left around
2510 for tfile in self.tempfiles:
2511 for tfile in self.tempfiles:
2511 try:
2512 try:
2512 os.unlink(tfile)
2513 os.unlink(tfile)
2513 except OSError:
2514 except OSError:
2514 pass
2515 pass
2515
2516
2516 # Clear all user namespaces to release all references cleanly.
2517 # Clear all user namespaces to release all references cleanly.
2517 self.reset()
2518 self.reset()
2518
2519
2519 # Run user hooks
2520 # Run user hooks
2520 self.hooks.shutdown_hook()
2521 self.hooks.shutdown_hook()
2521
2522
2522 def cleanup(self):
2523 def cleanup(self):
2523 self.restore_sys_module_state()
2524 self.restore_sys_module_state()
2524
2525
2525
2526
@@ -1,332 +1,336 b''
1 """Tests for various magic functions.
1 """Tests for various magic functions.
2
2
3 Needs to be run by nose (to make ipython session available).
3 Needs to be run by nose (to make ipython session available).
4 """
4 """
5
5
6 import os
6 import os
7 import sys
7 import sys
8 import tempfile
8 import tempfile
9 import types
9 import types
10 from cStringIO import StringIO
10 from cStringIO import StringIO
11
11
12 import nose.tools as nt
12 import nose.tools as nt
13
13
14 from IPython.core.iplib import get_ipython
14 #from IPython.core.iplib import get_ipython
15 from IPython.utils.platutils import find_cmd, get_long_path_name
15 from IPython.utils.platutils import find_cmd, get_long_path_name
16 from IPython.testing import decorators as dec
16 from IPython.testing import decorators as dec
17 from IPython.testing import tools as tt
17 from IPython.testing import tools as tt
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Test functions begin
20 # Test functions begin
21
21
22 def test_rehashx():
22 def test_rehashx():
23 # clear up everything
23 # clear up everything
24 _ip = get_ipython()
24 _ip = get_ipython()
25 _ip.alias_manager.alias_table.clear()
25 _ip.alias_manager.alias_table.clear()
26 del _ip.db['syscmdlist']
26 del _ip.db['syscmdlist']
27
27
28 _ip.magic('rehashx')
28 _ip.magic('rehashx')
29 # Practically ALL ipython development systems will have more than 10 aliases
29 # Practically ALL ipython development systems will have more than 10 aliases
30
30
31 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
31 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
32 for key, val in _ip.alias_manager.alias_table.items():
32 for key, val in _ip.alias_manager.alias_table.items():
33 # we must strip dots from alias names
33 # we must strip dots from alias names
34 nt.assert_true('.' not in key)
34 nt.assert_true('.' not in key)
35
35
36 # rehashx must fill up syscmdlist
36 # rehashx must fill up syscmdlist
37 scoms = _ip.db['syscmdlist']
37 scoms = _ip.db['syscmdlist']
38 yield (nt.assert_true, len(scoms) > 10)
38 yield (nt.assert_true, len(scoms) > 10)
39
39
40
40
41 def doctest_hist_f():
41 def doctest_hist_f():
42 """Test %hist -f with temporary filename.
42 """Test %hist -f with temporary filename.
43
43
44 In [9]: import tempfile
44 In [9]: import tempfile
45
45
46 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
46 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
47
47
48 In [11]: %hist -n -f $tfile 3
48 In [11]: %hist -n -f $tfile 3
49 """
49 """
50
50
51
51
52 def doctest_hist_r():
52 def doctest_hist_r():
53 """Test %hist -r
53 """Test %hist -r
54
54
55 XXX - This test is not recording the output correctly. Not sure why...
55 XXX - This test is not recording the output correctly. Not sure why...
56
56
57 In [20]: 'hist' in _ip.lsmagic()
57 In [20]: 'hist' in _ip.lsmagic()
58 Out[20]: True
58 Out[20]: True
59
59
60 In [6]: x=1
60 In [6]: x=1
61
61
62 In [7]: %hist -n -r 2
62 In [7]: %hist -n -r 2
63 x=1 # random
63 x=1 # random
64 hist -n -r 2 # random
64 hist -n -r 2 # random
65 """
65 """
66
66
67 # This test is known to fail on win32.
67 # This test is known to fail on win32.
68 # See ticket https://bugs.launchpad.net/bugs/366334
68 # See ticket https://bugs.launchpad.net/bugs/366334
69 def test_obj_del():
69 def test_obj_del():
70 _ip = get_ipython()
70 _ip = get_ipython()
71 """Test that object's __del__ methods are called on exit."""
71 """Test that object's __del__ methods are called on exit."""
72 test_dir = os.path.dirname(__file__)
72 test_dir = os.path.dirname(__file__)
73 del_file = os.path.join(test_dir,'obj_del.py')
73 del_file = os.path.join(test_dir,'obj_del.py')
74 ipython_cmd = find_cmd('ipython')
74 ipython_cmd = find_cmd('ipython')
75 out = _ip.getoutput('%s %s' % (ipython_cmd, del_file))
75 out = _ip.getoutput('%s %s' % (ipython_cmd, del_file))
76 nt.assert_equals(out,'obj_del.py: object A deleted')
76 nt.assert_equals(out,'obj_del.py: object A deleted')
77
77
78
78
79 def test_shist():
79 def test_shist():
80 # Simple tests of ShadowHist class - test generator.
80 # Simple tests of ShadowHist class - test generator.
81 import os, shutil, tempfile
81 import os, shutil, tempfile
82
82
83 from IPython.utils import pickleshare
83 from IPython.utils import pickleshare
84 from IPython.core.history import ShadowHist
84 from IPython.core.history import ShadowHist
85
85
86 tfile = tempfile.mktemp('','tmp-ipython-')
86 tfile = tempfile.mktemp('','tmp-ipython-')
87
87
88 db = pickleshare.PickleShareDB(tfile)
88 db = pickleshare.PickleShareDB(tfile)
89 s = ShadowHist(db)
89 s = ShadowHist(db)
90 s.add('hello')
90 s.add('hello')
91 s.add('world')
91 s.add('world')
92 s.add('hello')
92 s.add('hello')
93 s.add('hello')
93 s.add('hello')
94 s.add('karhu')
94 s.add('karhu')
95
95
96 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
96 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
97
97
98 yield nt.assert_equal,s.get(2),'world'
98 yield nt.assert_equal,s.get(2),'world'
99
99
100 shutil.rmtree(tfile)
100 shutil.rmtree(tfile)
101
101
102
102 @dec.skipif_not_numpy
103 # XXX failing for now, until we get clearcmd out of quarantine. But we should
104 # fix this and revert the skip to happen only if numpy is not around.
105 #@dec.skipif_not_numpy
106 @dec.skipknownfailure
103 def test_numpy_clear_array_undec():
107 def test_numpy_clear_array_undec():
104 from IPython.extensions import clearcmd
108 from IPython.extensions import clearcmd
105
109
106 _ip.ex('import numpy as np')
110 _ip.ex('import numpy as np')
107 _ip.ex('a = np.empty(2)')
111 _ip.ex('a = np.empty(2)')
108 yield (nt.assert_true, 'a' in _ip.user_ns)
112 yield (nt.assert_true, 'a' in _ip.user_ns)
109 _ip.magic('clear array')
113 _ip.magic('clear array')
110 yield (nt.assert_false, 'a' in _ip.user_ns)
114 yield (nt.assert_false, 'a' in _ip.user_ns)
111
115
112
116
113 @dec.skip()
117 @dec.skip()
114 def test_fail_dec(*a,**k):
118 def test_fail_dec(*a,**k):
115 yield nt.assert_true, False
119 yield nt.assert_true, False
116
120
117 @dec.skip('This one shouldn not run')
121 @dec.skip('This one shouldn not run')
118 def test_fail_dec2(*a,**k):
122 def test_fail_dec2(*a,**k):
119 yield nt.assert_true, False
123 yield nt.assert_true, False
120
124
121 @dec.skipknownfailure
125 @dec.skipknownfailure
122 def test_fail_dec3(*a,**k):
126 def test_fail_dec3(*a,**k):
123 yield nt.assert_true, False
127 yield nt.assert_true, False
124
128
125
129
126 def doctest_refbug():
130 def doctest_refbug():
127 """Very nasty problem with references held by multiple runs of a script.
131 """Very nasty problem with references held by multiple runs of a script.
128 See: https://bugs.launchpad.net/ipython/+bug/269966
132 See: https://bugs.launchpad.net/ipython/+bug/269966
129
133
130 In [1]: _ip.clear_main_mod_cache()
134 In [1]: _ip.clear_main_mod_cache()
131
135
132 In [2]: run refbug
136 In [2]: run refbug
133
137
134 In [3]: call_f()
138 In [3]: call_f()
135 lowercased: hello
139 lowercased: hello
136
140
137 In [4]: run refbug
141 In [4]: run refbug
138
142
139 In [5]: call_f()
143 In [5]: call_f()
140 lowercased: hello
144 lowercased: hello
141 lowercased: hello
145 lowercased: hello
142 """
146 """
143
147
144 #-----------------------------------------------------------------------------
148 #-----------------------------------------------------------------------------
145 # Tests for %run
149 # Tests for %run
146 #-----------------------------------------------------------------------------
150 #-----------------------------------------------------------------------------
147
151
148 # %run is critical enough that it's a good idea to have a solid collection of
152 # %run is critical enough that it's a good idea to have a solid collection of
149 # tests for it, some as doctests and some as normal tests.
153 # tests for it, some as doctests and some as normal tests.
150
154
151 def doctest_run_ns():
155 def doctest_run_ns():
152 """Classes declared %run scripts must be instantiable afterwards.
156 """Classes declared %run scripts must be instantiable afterwards.
153
157
154 In [11]: run tclass foo
158 In [11]: run tclass foo
155
159
156 In [12]: isinstance(f(),foo)
160 In [12]: isinstance(f(),foo)
157 Out[12]: True
161 Out[12]: True
158 """
162 """
159
163
160
164
161 def doctest_run_ns2():
165 def doctest_run_ns2():
162 """Classes declared %run scripts must be instantiable afterwards.
166 """Classes declared %run scripts must be instantiable afterwards.
163
167
164 In [4]: run tclass C-first_pass
168 In [4]: run tclass C-first_pass
165
169
166 In [5]: run tclass C-second_pass
170 In [5]: run tclass C-second_pass
167 tclass.py: deleting object: C-first_pass
171 tclass.py: deleting object: C-first_pass
168 """
172 """
169
173
170 def doctest_run_builtins():
174 def doctest_run_builtins():
171 """Check that %run doesn't damage __builtins__ via a doctest.
175 """Check that %run doesn't damage __builtins__ via a doctest.
172
176
173 This is similar to the test_run_builtins, but I want *both* forms of the
177 This is similar to the test_run_builtins, but I want *both* forms of the
174 test to catch any possible glitches in our testing machinery, since that
178 test to catch any possible glitches in our testing machinery, since that
175 modifies %run somewhat. So for this, we have both a normal test (below)
179 modifies %run somewhat. So for this, we have both a normal test (below)
176 and a doctest (this one).
180 and a doctest (this one).
177
181
178 In [1]: import tempfile
182 In [1]: import tempfile
179
183
180 In [2]: bid1 = id(__builtins__)
184 In [2]: bid1 = id(__builtins__)
181
185
182 In [3]: fname = tempfile.mkstemp()[1]
186 In [3]: fname = tempfile.mkstemp()[1]
183
187
184 In [3]: f = open(fname,'w')
188 In [3]: f = open(fname,'w')
185
189
186 In [4]: f.write('pass\\n')
190 In [4]: f.write('pass\\n')
187
191
188 In [5]: f.flush()
192 In [5]: f.flush()
189
193
190 In [6]: print type(__builtins__)
194 In [6]: print type(__builtins__)
191 <type 'module'>
195 <type 'module'>
192
196
193 In [7]: %run "$fname"
197 In [7]: %run "$fname"
194
198
195 In [7]: f.close()
199 In [7]: f.close()
196
200
197 In [8]: bid2 = id(__builtins__)
201 In [8]: bid2 = id(__builtins__)
198
202
199 In [9]: print type(__builtins__)
203 In [9]: print type(__builtins__)
200 <type 'module'>
204 <type 'module'>
201
205
202 In [10]: bid1 == bid2
206 In [10]: bid1 == bid2
203 Out[10]: True
207 Out[10]: True
204
208
205 In [12]: try:
209 In [12]: try:
206 ....: os.unlink(fname)
210 ....: os.unlink(fname)
207 ....: except:
211 ....: except:
208 ....: pass
212 ....: pass
209 ....:
213 ....:
210 """
214 """
211
215
212 # For some tests, it will be handy to organize them in a class with a common
216 # For some tests, it will be handy to organize them in a class with a common
213 # setup that makes a temp file
217 # setup that makes a temp file
214
218
215 class TestMagicRun(object):
219 class TestMagicRun(object):
216
220
217 def setup(self):
221 def setup(self):
218 """Make a valid python temp file."""
222 """Make a valid python temp file."""
219 fname = tempfile.mkstemp()[1]
223 fname = tempfile.mkstemp('.py')[1]
220 f = open(fname,'w')
224 f = open(fname,'w')
221 f.write('pass\n')
225 f.write('pass\n')
222 f.flush()
226 f.flush()
223 self.tmpfile = f
227 self.tmpfile = f
224 self.fname = fname
228 self.fname = fname
225
229
226 def run_tmpfile(self):
230 def run_tmpfile(self):
227 _ip = get_ipython()
231 _ip = get_ipython()
228 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
232 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
229 # See below and ticket https://bugs.launchpad.net/bugs/366353
233 # See below and ticket https://bugs.launchpad.net/bugs/366353
230 _ip.magic('run "%s"' % self.fname)
234 _ip.magic('run "%s"' % self.fname)
231
235
232 def test_builtins_id(self):
236 def test_builtins_id(self):
233 """Check that %run doesn't damage __builtins__ """
237 """Check that %run doesn't damage __builtins__ """
234 _ip = get_ipython()
238 _ip = get_ipython()
235 # Test that the id of __builtins__ is not modified by %run
239 # Test that the id of __builtins__ is not modified by %run
236 bid1 = id(_ip.user_ns['__builtins__'])
240 bid1 = id(_ip.user_ns['__builtins__'])
237 self.run_tmpfile()
241 self.run_tmpfile()
238 bid2 = id(_ip.user_ns['__builtins__'])
242 bid2 = id(_ip.user_ns['__builtins__'])
239 tt.assert_equals(bid1, bid2)
243 tt.assert_equals(bid1, bid2)
240
244
241 def test_builtins_type(self):
245 def test_builtins_type(self):
242 """Check that the type of __builtins__ doesn't change with %run.
246 """Check that the type of __builtins__ doesn't change with %run.
243
247
244 However, the above could pass if __builtins__ was already modified to
248 However, the above could pass if __builtins__ was already modified to
245 be a dict (it should be a module) by a previous use of %run. So we
249 be a dict (it should be a module) by a previous use of %run. So we
246 also check explicitly that it really is a module:
250 also check explicitly that it really is a module:
247 """
251 """
248 _ip = get_ipython()
252 _ip = get_ipython()
249 self.run_tmpfile()
253 self.run_tmpfile()
250 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
254 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
251
255
252 def test_prompts(self):
256 def test_prompts(self):
253 """Test that prompts correctly generate after %run"""
257 """Test that prompts correctly generate after %run"""
254 self.run_tmpfile()
258 self.run_tmpfile()
255 _ip = get_ipython()
259 _ip = get_ipython()
256 p2 = str(_ip.outputcache.prompt2).strip()
260 p2 = str(_ip.outputcache.prompt2).strip()
257 nt.assert_equals(p2[:3], '...')
261 nt.assert_equals(p2[:3], '...')
258
262
259 def teardown(self):
263 def teardown(self):
260 self.tmpfile.close()
264 self.tmpfile.close()
261 try:
265 try:
262 os.unlink(self.fname)
266 os.unlink(self.fname)
263 except:
267 except:
264 # On Windows, even though we close the file, we still can't delete
268 # On Windows, even though we close the file, we still can't delete
265 # it. I have no clue why
269 # it. I have no clue why
266 pass
270 pass
267
271
268 # Multiple tests for clipboard pasting
272 # Multiple tests for clipboard pasting
269 def test_paste():
273 def test_paste():
270 _ip = get_ipython()
274 _ip = get_ipython()
271 def paste(txt, flags='-q'):
275 def paste(txt, flags='-q'):
272 """Paste input text, by default in quiet mode"""
276 """Paste input text, by default in quiet mode"""
273 hooks.clipboard_get = lambda : txt
277 hooks.clipboard_get = lambda : txt
274 _ip.magic('paste '+flags)
278 _ip.magic('paste '+flags)
275
279
276 # Inject fake clipboard hook but save original so we can restore it later
280 # Inject fake clipboard hook but save original so we can restore it later
277 hooks = _ip.hooks
281 hooks = _ip.hooks
278 user_ns = _ip.user_ns
282 user_ns = _ip.user_ns
279 original_clip = hooks.clipboard_get
283 original_clip = hooks.clipboard_get
280
284
281 try:
285 try:
282 # This try/except with an emtpy except clause is here only because
286 # This try/except with an emtpy except clause is here only because
283 # try/yield/finally is invalid syntax in Python 2.4. This will be
287 # try/yield/finally is invalid syntax in Python 2.4. This will be
284 # removed when we drop 2.4-compatibility, and the emtpy except below
288 # removed when we drop 2.4-compatibility, and the emtpy except below
285 # will be changed to a finally.
289 # will be changed to a finally.
286
290
287 # Run tests with fake clipboard function
291 # Run tests with fake clipboard function
288 user_ns.pop('x', None)
292 user_ns.pop('x', None)
289 paste('x=1')
293 paste('x=1')
290 yield (nt.assert_equal, user_ns['x'], 1)
294 yield (nt.assert_equal, user_ns['x'], 1)
291
295
292 user_ns.pop('x', None)
296 user_ns.pop('x', None)
293 paste('>>> x=2')
297 paste('>>> x=2')
294 yield (nt.assert_equal, user_ns['x'], 2)
298 yield (nt.assert_equal, user_ns['x'], 2)
295
299
296 paste("""
300 paste("""
297 >>> x = [1,2,3]
301 >>> x = [1,2,3]
298 >>> y = []
302 >>> y = []
299 >>> for i in x:
303 >>> for i in x:
300 ... y.append(i**2)
304 ... y.append(i**2)
301 ...
305 ...
302 """)
306 """)
303 yield (nt.assert_equal, user_ns['x'], [1,2,3])
307 yield (nt.assert_equal, user_ns['x'], [1,2,3])
304 yield (nt.assert_equal, user_ns['y'], [1,4,9])
308 yield (nt.assert_equal, user_ns['y'], [1,4,9])
305
309
306 # Now, test that paste -r works
310 # Now, test that paste -r works
307 user_ns.pop('x', None)
311 user_ns.pop('x', None)
308 yield (nt.assert_false, 'x' in user_ns)
312 yield (nt.assert_false, 'x' in user_ns)
309 _ip.magic('paste -r')
313 _ip.magic('paste -r')
310 yield (nt.assert_equal, user_ns['x'], [1,2,3])
314 yield (nt.assert_equal, user_ns['x'], [1,2,3])
311
315
312 # Also test paste echoing, by temporarily faking the writer
316 # Also test paste echoing, by temporarily faking the writer
313 w = StringIO()
317 w = StringIO()
314 writer = _ip.write
318 writer = _ip.write
315 _ip.write = w.write
319 _ip.write = w.write
316 code = """
320 code = """
317 a = 100
321 a = 100
318 b = 200"""
322 b = 200"""
319 try:
323 try:
320 paste(code,'')
324 paste(code,'')
321 out = w.getvalue()
325 out = w.getvalue()
322 finally:
326 finally:
323 _ip.write = writer
327 _ip.write = writer
324 yield (nt.assert_equal, user_ns['a'], 100)
328 yield (nt.assert_equal, user_ns['a'], 100)
325 yield (nt.assert_equal, user_ns['b'], 200)
329 yield (nt.assert_equal, user_ns['b'], 200)
326 yield (nt.assert_equal, out, code+"\n## -- End pasted text --\n")
330 yield (nt.assert_equal, out, code+"\n## -- End pasted text --\n")
327
331
328 finally:
332 finally:
329 # This should be in a finally clause, instead of the bare except above.
333 # This should be in a finally clause, instead of the bare except above.
330 # Restore original hook
334 # Restore original hook
331 hooks.clipboard_get = original_clip
335 hooks.clipboard_get = original_clip
332
336
@@ -1,322 +1,327 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Test Suite Runner.
2 """IPython Test Suite Runner.
3
3
4 This module provides a main entry point to a user script to test IPython
4 This module provides a main entry point to a user script to test IPython
5 itself from the command line. There are two ways of running this script:
5 itself from the command line. There are two ways of running this script:
6
6
7 1. With the syntax `iptest all`. This runs our entire test suite by
7 1. With the syntax `iptest all`. This runs our entire test suite by
8 calling this script (with different arguments) or trial recursively. This
8 calling this script (with different arguments) or trial recursively. This
9 causes modules and package to be tested in different processes, using nose
9 causes modules and package to be tested in different processes, using nose
10 or trial where appropriate.
10 or trial where appropriate.
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 the script simply calls nose, but with special command line flags and
12 the script simply calls nose, but with special command line flags and
13 plugins loaded.
13 plugins loaded.
14
14
15 For now, this script requires that both nose and twisted are installed. This
15 For now, this script requires that both nose and twisted are installed. This
16 will change in the future.
16 will change in the future.
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Module imports
20 # Module imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import os.path as path
24 import os.path as path
25 import sys
25 import sys
26 import subprocess
26 import subprocess
27 import tempfile
27 import tempfile
28 import time
28 import time
29 import warnings
29 import warnings
30
30
31 import nose.plugins.builtin
31 import nose.plugins.builtin
32 from nose.core import TestProgram
32 from nose.core import TestProgram
33
33
34 from IPython.utils.platutils import find_cmd
34 from IPython.utils.platutils import find_cmd
35 # from IPython.testing.plugin.ipdoctest import IPythonDoctest
35 # from IPython.testing.plugin.ipdoctest import IPythonDoctest
36
36
37 pjoin = path.join
37 pjoin = path.join
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Logic for skipping doctests
40 # Logic for skipping doctests
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 def test_for(mod):
43 def test_for(mod):
44 """Test to see if mod is importable."""
44 """Test to see if mod is importable."""
45 try:
45 try:
46 __import__(mod)
46 __import__(mod)
47 except ImportError:
47 except ImportError:
48 return False
48 return False
49 else:
49 else:
50 return True
50 return True
51
51
52 have_curses = test_for('_curses')
52 have_curses = test_for('_curses')
53 have_wx = test_for('wx')
53 have_wx = test_for('wx')
54 have_wx_aui = test_for('wx.aui')
54 have_wx_aui = test_for('wx.aui')
55 have_zi = test_for('zope.interface')
55 have_zi = test_for('zope.interface')
56 have_twisted = test_for('twisted')
56 have_twisted = test_for('twisted')
57 have_foolscap = test_for('foolscap')
57 have_foolscap = test_for('foolscap')
58 have_objc = test_for('objc')
58 have_objc = test_for('objc')
59 have_pexpect = test_for('pexpect')
59 have_pexpect = test_for('pexpect')
60 have_gtk = test_for('gtk')
60 have_gtk = test_for('gtk')
61 have_gobject = test_for('gobject')
61 have_gobject = test_for('gobject')
62
62
63
63
64 def make_exclude():
64 def make_exclude():
65
65
66 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
66 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
67 # testing problems. We should strive to minimize the number of skipped
67 # testing problems. We should strive to minimize the number of skipped
68 # modules, since this means untested code. As the testing machinery
68 # modules, since this means untested code. As the testing machinery
69 # solidifies, this list should eventually become empty.
69 # solidifies, this list should eventually become empty.
70 EXCLUDE = [pjoin('IPython', 'external'),
70 EXCLUDE = [pjoin('IPython', 'external'),
71 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
71 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
72 pjoin('IPython_doctest_plugin'),
72 pjoin('IPython_doctest_plugin'),
73 pjoin('IPython', 'quarantine'),
73 pjoin('IPython', 'quarantine'),
74 pjoin('IPython', 'deathrow'),
74 pjoin('IPython', 'deathrow'),
75 pjoin('IPython', 'testing', 'attic'),
75 pjoin('IPython', 'testing', 'attic'),
76 pjoin('IPython', 'testing', 'tools'),
76 pjoin('IPython', 'testing', 'tools'),
77 pjoin('IPython', 'testing', 'mkdoctests'),
77 pjoin('IPython', 'testing', 'mkdoctests'),
78 pjoin('IPython', 'lib', 'inputhook')
78 pjoin('IPython', 'lib', 'inputhook')
79 ]
79 ]
80
80
81 if not have_wx:
81 if not have_wx:
82 EXCLUDE.append(pjoin('IPython', 'gui'))
82 EXCLUDE.append(pjoin('IPython', 'gui'))
83 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
83 EXCLUDE.append(pjoin('IPython', 'frontend', 'wx'))
84 EXCLUDE.append(pjoin('IPython', 'lib', 'inputhookwx'))
84 EXCLUDE.append(pjoin('IPython', 'lib', 'inputhookwx'))
85
85
86 if not have_gtk or not have_gobject:
86 if not have_gtk or not have_gobject:
87 EXCLUDE.append(pjoin('IPython', 'lib', 'inputhookgtk'))
87 EXCLUDE.append(pjoin('IPython', 'lib', 'inputhookgtk'))
88
88
89 if not have_wx_aui:
89 if not have_wx_aui:
90 EXCLUDE.append(pjoin('IPython', 'gui', 'wx', 'wxIPython'))
90 EXCLUDE.append(pjoin('IPython', 'gui', 'wx', 'wxIPython'))
91
91
92 if not have_objc:
92 if not have_objc:
93 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
93 EXCLUDE.append(pjoin('IPython', 'frontend', 'cocoa'))
94
94
95 if not sys.platform == 'win32':
95 if not sys.platform == 'win32':
96 EXCLUDE.append(pjoin('IPython', 'utils', 'platutils_win32'))
96 EXCLUDE.append(pjoin('IPython', 'utils', 'platutils_win32'))
97
97
98 # These have to be skipped on win32 because the use echo, rm, cd, etc.
98 # These have to be skipped on win32 because the use echo, rm, cd, etc.
99 # See ticket https://bugs.launchpad.net/bugs/366982
99 # See ticket https://bugs.launchpad.net/bugs/366982
100 if sys.platform == 'win32':
100 if sys.platform == 'win32':
101 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'test_exampleip'))
101 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'test_exampleip'))
102 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'dtexample'))
102 EXCLUDE.append(pjoin('IPython', 'testing', 'plugin', 'dtexample'))
103
103
104 if not os.name == 'posix':
104 if not os.name == 'posix':
105 EXCLUDE.append(pjoin('IPython', 'utils', 'platutils_posix'))
105 EXCLUDE.append(pjoin('IPython', 'utils', 'platutils_posix'))
106
106
107 if not have_pexpect:
107 if not have_pexpect:
108 EXCLUDE.append(pjoin('IPython', 'scripts', 'irunner'))
108 EXCLUDE.append(pjoin('IPython', 'scripts', 'irunner'))
109
109
110 # This is scary. We still have things in frontend and testing that
110 # This is scary. We still have things in frontend and testing that
111 # are being tested by nose that use twisted. We need to rethink
111 # are being tested by nose that use twisted. We need to rethink
112 # how we are isolating dependencies in testing.
112 # how we are isolating dependencies in testing.
113 if not (have_twisted and have_zi and have_foolscap):
113 if not (have_twisted and have_zi and have_foolscap):
114 EXCLUDE.append(pjoin('IPython', 'frontend', 'asyncfrontendbase'))
114 EXCLUDE.append(pjoin('IPython', 'frontend', 'asyncfrontendbase'))
115 EXCLUDE.append(pjoin('IPython', 'frontend', 'prefilterfrontend'))
115 EXCLUDE.append(pjoin('IPython', 'frontend', 'prefilterfrontend'))
116 EXCLUDE.append(pjoin('IPython', 'frontend', 'frontendbase'))
116 EXCLUDE.append(pjoin('IPython', 'frontend', 'frontendbase'))
117 EXCLUDE.append(pjoin('IPython', 'frontend', 'linefrontendbase'))
117 EXCLUDE.append(pjoin('IPython', 'frontend', 'linefrontendbase'))
118 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
118 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
119 'test_linefrontend'))
119 'test_linefrontend'))
120 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
120 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
121 'test_frontendbase'))
121 'test_frontendbase'))
122 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
122 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
123 'test_prefilterfrontend'))
123 'test_prefilterfrontend'))
124 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
124 EXCLUDE.append(pjoin('IPython', 'frontend', 'tests',
125 'test_asyncfrontendbase')),
125 'test_asyncfrontendbase')),
126 EXCLUDE.append(pjoin('IPython', 'testing', 'parametric'))
126 EXCLUDE.append(pjoin('IPython', 'testing', 'parametric'))
127 EXCLUDE.append(pjoin('IPython', 'testing', 'util'))
127 EXCLUDE.append(pjoin('IPython', 'testing', 'util'))
128
128
129 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
129 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
130 if sys.platform == 'win32':
130 if sys.platform == 'win32':
131 EXCLUDE = [s.replace('\\','\\\\') for s in EXCLUDE]
131 EXCLUDE = [s.replace('\\','\\\\') for s in EXCLUDE]
132
132
133 return EXCLUDE
133 return EXCLUDE
134
134
135
135
136 #-----------------------------------------------------------------------------
136 #-----------------------------------------------------------------------------
137 # Functions and classes
137 # Functions and classes
138 #-----------------------------------------------------------------------------
138 #-----------------------------------------------------------------------------
139
139
140 def run_iptest():
140 def run_iptest():
141 """Run the IPython test suite using nose.
141 """Run the IPython test suite using nose.
142
142
143 This function is called when this script is **not** called with the form
143 This function is called when this script is **not** called with the form
144 `iptest all`. It simply calls nose with appropriate command line flags
144 `iptest all`. It simply calls nose with appropriate command line flags
145 and accepts all of the standard nose arguments.
145 and accepts all of the standard nose arguments.
146 """
146 """
147
147
148 warnings.filterwarnings('ignore',
148 warnings.filterwarnings('ignore',
149 'This will be removed soon. Use IPython.testing.util instead')
149 'This will be removed soon. Use IPython.testing.util instead')
150
150
151 argv = sys.argv + [
151 argv = sys.argv + [
152 # Loading ipdoctest causes problems with Twisted.
152 # Loading ipdoctest causes problems with Twisted.
153 # I am removing this as a temporary fix to get the
153 # I am removing this as a temporary fix to get the
154 # test suite back into working shape. Our nose
154 # test suite back into working shape. Our nose
155 # plugin needs to be gone through with a fine
155 # plugin needs to be gone through with a fine
156 # toothed comb to find what is causing the problem.
156 # toothed comb to find what is causing the problem.
157 # '--with-ipdoctest',
157 # '--with-ipdoctest',
158 # '--ipdoctest-tests','--ipdoctest-extension=txt',
158 # '--ipdoctest-tests','--ipdoctest-extension=txt',
159 # '--detailed-errors',
159 # '--detailed-errors',
160
160
161 # We add --exe because of setuptools' imbecility (it
161 # We add --exe because of setuptools' imbecility (it
162 # blindly does chmod +x on ALL files). Nose does the
162 # blindly does chmod +x on ALL files). Nose does the
163 # right thing and it tries to avoid executables,
163 # right thing and it tries to avoid executables,
164 # setuptools unfortunately forces our hand here. This
164 # setuptools unfortunately forces our hand here. This
165 # has been discussed on the distutils list and the
165 # has been discussed on the distutils list and the
166 # setuptools devs refuse to fix this problem!
166 # setuptools devs refuse to fix this problem!
167 '--exe',
167 '--exe',
168 ]
168 ]
169
169
170 # Detect if any tests were required by explicitly calling an IPython
170 # Detect if any tests were required by explicitly calling an IPython
171 # submodule or giving a specific path
171 # submodule or giving a specific path
172 has_tests = False
172 has_tests = False
173 for arg in sys.argv:
173 for arg in sys.argv:
174 if 'IPython' in arg or arg.endswith('.py') or \
174 if 'IPython' in arg or arg.endswith('.py') or \
175 (':' in arg and '.py' in arg):
175 (':' in arg and '.py' in arg):
176 has_tests = True
176 has_tests = True
177 break
177 break
178
178
179 # If nothing was specifically requested, test full IPython
179 # If nothing was specifically requested, test full IPython
180 if not has_tests:
180 if not has_tests:
181 argv.append('IPython')
181 argv.append('IPython')
182
182
183 # Construct list of plugins, omitting the existing doctest plugin, which
183 # Construct list of plugins, omitting the existing doctest plugin, which
184 # ours replaces (and extends).
184 # ours replaces (and extends).
185 EXCLUDE = make_exclude()
185 EXCLUDE = make_exclude()
186 plugins = []
186 plugins = []
187 # plugins = [IPythonDoctest(EXCLUDE)]
187 # plugins = [IPythonDoctest(EXCLUDE)]
188 for p in nose.plugins.builtin.plugins:
188 for p in nose.plugins.builtin.plugins:
189 plug = p()
189 plug = p()
190 if plug.name == 'doctest':
190 if plug.name == 'doctest':
191 continue
191 continue
192 plugins.append(plug)
192 plugins.append(plug)
193
193
194 TestProgram(argv=argv,plugins=plugins)
194 TestProgram(argv=argv,plugins=plugins)
195
195
196
196
197 class IPTester(object):
197 class IPTester(object):
198 """Call that calls iptest or trial in a subprocess.
198 """Call that calls iptest or trial in a subprocess.
199 """
199 """
200 def __init__(self,runner='iptest',params=None):
200 def __init__(self,runner='iptest',params=None):
201 """ """
201 """ """
202 if runner == 'iptest':
202 if runner == 'iptest':
203 self.runner = ['iptest','-v']
203 self.runner = ['iptest','-v']
204 else:
204 else:
205 self.runner = [find_cmd('trial')]
205 self.runner = [find_cmd('trial')]
206 if params is None:
206 if params is None:
207 params = []
207 params = []
208 if isinstance(params,str):
208 if isinstance(params,str):
209 params = [params]
209 params = [params]
210 self.params = params
210 self.params = params
211
211
212 # Assemble call
212 # Assemble call
213 self.call_args = self.runner+self.params
213 self.call_args = self.runner+self.params
214
214
215 if sys.platform == 'win32':
215 if sys.platform == 'win32':
216 def run(self):
216 def run(self):
217 """Run the stored commands"""
217 """Run the stored commands"""
218 # On Windows, cd to temporary directory to run tests. Otherwise,
218 # On Windows, cd to temporary directory to run tests. Otherwise,
219 # Twisted's trial may not be able to execute 'trial IPython', since
219 # Twisted's trial may not be able to execute 'trial IPython', since
220 # it will confuse the IPython module name with the ipython
220 # it will confuse the IPython module name with the ipython
221 # execution scripts, because the windows file system isn't case
221 # execution scripts, because the windows file system isn't case
222 # sensitive.
222 # sensitive.
223 # We also use os.system instead of subprocess.call, because I was
223 # We also use os.system instead of subprocess.call, because I was
224 # having problems with subprocess and I just don't know enough
224 # having problems with subprocess and I just don't know enough
225 # about win32 to debug this reliably. Os.system may be the 'old
225 # about win32 to debug this reliably. Os.system may be the 'old
226 # fashioned' way to do it, but it works just fine. If someone
226 # fashioned' way to do it, but it works just fine. If someone
227 # later can clean this up that's fine, as long as the tests run
227 # later can clean this up that's fine, as long as the tests run
228 # reliably in win32.
228 # reliably in win32.
229 curdir = os.getcwd()
229 curdir = os.getcwd()
230 os.chdir(tempfile.gettempdir())
230 os.chdir(tempfile.gettempdir())
231 stat = os.system(' '.join(self.call_args))
231 stat = os.system(' '.join(self.call_args))
232 os.chdir(curdir)
232 os.chdir(curdir)
233 return stat
233 return stat
234 else:
234 else:
235 def run(self):
235 def run(self):
236 """Run the stored commands"""
236 """Run the stored commands"""
237 return subprocess.call(self.call_args)
237 try:
238 return subprocess.call(self.call_args)
239 except:
240 import traceback
241 traceback.print_exc()
242 return 1 # signal failure
238
243
239
244
240 def make_runners():
245 def make_runners():
241 """Define the top-level packages that need to be tested.
246 """Define the top-level packages that need to be tested.
242 """
247 """
243
248
244 nose_packages = ['config', 'core', 'extensions',
249 nose_packages = ['config', 'core', 'extensions',
245 'frontend', 'lib',
250 'frontend', 'lib',
246 'scripts', 'testing', 'utils']
251 'scripts', 'testing', 'utils']
247 trial_packages = ['kernel']
252 trial_packages = ['kernel']
248
253
249 if have_wx:
254 if have_wx:
250 nose_packages.append('gui')
255 nose_packages.append('gui')
251
256
252 nose_packages = ['IPython.%s' % m for m in nose_packages ]
257 nose_packages = ['IPython.%s' % m for m in nose_packages ]
253 trial_packages = ['IPython.%s' % m for m in trial_packages ]
258 trial_packages = ['IPython.%s' % m for m in trial_packages ]
254
259
255 # Make runners
260 # Make runners
256 runners = dict()
261 runners = dict()
257
262
258 nose_runners = dict(zip(nose_packages, [IPTester(params=v) for v in nose_packages]))
263 nose_runners = dict(zip(nose_packages, [IPTester(params=v) for v in nose_packages]))
259 if have_zi and have_twisted and have_foolscap:
264 if have_zi and have_twisted and have_foolscap:
260 trial_runners = dict(zip(trial_packages, [IPTester('trial',params=v) for v in trial_packages]))
265 trial_runners = dict(zip(trial_packages, [IPTester('trial',params=v) for v in trial_packages]))
261 runners.update(nose_runners)
266 runners.update(nose_runners)
262 runners.update(trial_runners)
267 runners.update(trial_runners)
263
268
264 return runners
269 return runners
265
270
266
271
267 def run_iptestall():
272 def run_iptestall():
268 """Run the entire IPython test suite by calling nose and trial.
273 """Run the entire IPython test suite by calling nose and trial.
269
274
270 This function constructs :class:`IPTester` instances for all IPython
275 This function constructs :class:`IPTester` instances for all IPython
271 modules and package and then runs each of them. This causes the modules
276 modules and package and then runs each of them. This causes the modules
272 and packages of IPython to be tested each in their own subprocess using
277 and packages of IPython to be tested each in their own subprocess using
273 nose or twisted.trial appropriately.
278 nose or twisted.trial appropriately.
274 """
279 """
275
280
276 runners = make_runners()
281 runners = make_runners()
277
282
278 # Run all test runners, tracking execution time
283 # Run all test runners, tracking execution time
279 failed = {}
284 failed = {}
280 t_start = time.time()
285 t_start = time.time()
281 for name,runner in runners.iteritems():
286 for name,runner in runners.iteritems():
282 print '*'*77
287 print '*'*77
283 print 'IPython test group:',name
288 print 'IPython test group:',name
284 res = runner.run()
289 res = runner.run()
285 if res:
290 if res:
286 failed[name] = res
291 failed[name] = res
287 t_end = time.time()
292 t_end = time.time()
288 t_tests = t_end - t_start
293 t_tests = t_end - t_start
289 nrunners = len(runners)
294 nrunners = len(runners)
290 nfail = len(failed)
295 nfail = len(failed)
291 # summarize results
296 # summarize results
292 print
297 print
293 print '*'*77
298 print '*'*77
294 print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
299 print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
295 print
300 print
296 if not failed:
301 if not failed:
297 print 'OK'
302 print 'OK'
298 else:
303 else:
299 # If anything went wrong, point out what command to rerun manually to
304 # If anything went wrong, point out what command to rerun manually to
300 # see the actual errors and individual summary
305 # see the actual errors and individual summary
301 print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners)
306 print 'ERROR - %s out of %s test groups failed.' % (nfail, nrunners)
302 for name in failed:
307 for name in failed:
303 failed_runner = runners[name]
308 failed_runner = runners[name]
304 print '-'*40
309 print '-'*40
305 print 'Runner failed:',name
310 print 'Runner failed:',name
306 print 'You may wish to rerun this one individually, with:'
311 print 'You may wish to rerun this one individually, with:'
307 print ' '.join(failed_runner.call_args)
312 print ' '.join(failed_runner.call_args)
308 print
313 print
309
314
310
315
311 def main():
316 def main():
312 if len(sys.argv) == 1:
317 if len(sys.argv) == 1:
313 run_iptestall()
318 run_iptestall()
314 else:
319 else:
315 if sys.argv[1] == 'all':
320 if sys.argv[1] == 'all':
316 run_iptestall()
321 run_iptestall()
317 else:
322 else:
318 run_iptest()
323 run_iptest()
319
324
320
325
321 if __name__ == '__main__':
326 if __name__ == '__main__':
322 main()
327 main()
@@ -1,939 +1,939 b''
1 """Nose Plugin that supports IPython doctests.
1 """Nose Plugin that supports IPython doctests.
2
2
3 Limitations:
3 Limitations:
4
4
5 - When generating examples for use as doctests, make sure that you have
5 - When generating examples for use as doctests, make sure that you have
6 pretty-printing OFF. This can be done either by starting ipython with the
6 pretty-printing OFF. This can be done either by starting ipython with the
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
8 interactively disabling it with %Pprint. This is required so that IPython
8 interactively disabling it with %Pprint. This is required so that IPython
9 output matches that of normal Python, which is used by doctest for internal
9 output matches that of normal Python, which is used by doctest for internal
10 execution.
10 execution.
11
11
12 - Do not rely on specific prompt numbers for results (such as using
12 - Do not rely on specific prompt numbers for results (such as using
13 '_34==True', for example). For IPython tests run via an external process the
13 '_34==True', for example). For IPython tests run via an external process the
14 prompt numbers may be different, and IPython tests run as normal python code
14 prompt numbers may be different, and IPython tests run as normal python code
15 won't even have these special _NN variables set at all.
15 won't even have these special _NN variables set at all.
16 """
16 """
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Module imports
19 # Module imports
20
20
21 # From the standard library
21 # From the standard library
22 import __builtin__
22 import __builtin__
23 import commands
23 import commands
24 import doctest
24 import doctest
25 import inspect
25 import inspect
26 import logging
26 import logging
27 import os
27 import os
28 import re
28 import re
29 import sys
29 import sys
30 import traceback
30 import traceback
31 import unittest
31 import unittest
32
32
33 from inspect import getmodule
33 from inspect import getmodule
34 from StringIO import StringIO
34 from StringIO import StringIO
35
35
36 # We are overriding the default doctest runner, so we need to import a few
36 # We are overriding the default doctest runner, so we need to import a few
37 # things from doctest directly
37 # things from doctest directly
38 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
38 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
39 _unittest_reportflags, DocTestRunner,
39 _unittest_reportflags, DocTestRunner,
40 _extract_future_flags, pdb, _OutputRedirectingPdb,
40 _extract_future_flags, pdb, _OutputRedirectingPdb,
41 _exception_traceback,
41 _exception_traceback,
42 linecache)
42 linecache)
43
43
44 # Third-party modules
44 # Third-party modules
45 import nose.core
45 import nose.core
46
46
47 from nose.plugins import doctests, Plugin
47 from nose.plugins import doctests, Plugin
48 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
48 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
49
49
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51 # Module globals and other constants
51 # Module globals and other constants
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55 ###########################################################################
55 ###########################################################################
56 # *** HACK ***
56 # *** HACK ***
57 # We must start our own ipython object and heavily muck with it so that all the
57 # We must start our own ipython object and heavily muck with it so that all the
58 # modifications IPython makes to system behavior don't send the doctest
58 # modifications IPython makes to system behavior don't send the doctest
59 # machinery into a fit. This code should be considered a gross hack, but it
59 # machinery into a fit. This code should be considered a gross hack, but it
60 # gets the job done.
60 # gets the job done.
61
61
62 def default_argv():
62 def default_argv():
63 """Return a valid default argv for creating testing instances of ipython"""
63 """Return a valid default argv for creating testing instances of ipython"""
64
64
65 # Get the install directory for the user configuration and tell ipython to
65 # Get the install directory for the user configuration and tell ipython to
66 # use the default profile from there.
66 # use the default profile from there.
67 from IPython.config import userconfig
67 from IPython.config import default
68 ipcdir = os.path.dirname(userconfig.__file__)
68 ipcdir = os.path.dirname(default.__file__)
69 #ipconf = os.path.join(ipcdir,'ipy_user_conf.py')
69 ipconf = os.path.join(ipcdir,'ipython_config.py')
70 ipconf = os.path.join(ipcdir,'ipythonrc')
71 #print 'conf:',ipconf # dbg
70 #print 'conf:',ipconf # dbg
72
71 return ['--colors=NoColor','--no-term-title','--config-file=%s' % ipconf]
73 return ['--colors=NoColor','--noterm_title','-rcfile=%s' % ipconf]
74
72
75
73
76 # Hack to modify the %run command so we can sync the user's namespace with the
74 # Hack to modify the %run command so we can sync the user's namespace with the
77 # test globals. Once we move over to a clean magic system, this will be done
75 # test globals. Once we move over to a clean magic system, this will be done
78 # with much less ugliness.
76 # with much less ugliness.
79
77
80 class py_file_finder(object):
78 class py_file_finder(object):
81 def __init__(self,test_filename):
79 def __init__(self,test_filename):
82 self.test_filename = test_filename
80 self.test_filename = test_filename
83
81
84 def __call__(self,name):
82 def __call__(self,name):
85 from IPython.utils.genutils import get_py_filename
83 from IPython.utils.genutils import get_py_filename
86 try:
84 try:
87 return get_py_filename(name)
85 return get_py_filename(name)
88 except IOError:
86 except IOError:
89 test_dir = os.path.dirname(self.test_filename)
87 test_dir = os.path.dirname(self.test_filename)
90 new_path = os.path.join(test_dir,name)
88 new_path = os.path.join(test_dir,name)
91 return get_py_filename(new_path)
89 return get_py_filename(new_path)
92
90
93
91
94 def _run_ns_sync(self,arg_s,runner=None):
92 def _run_ns_sync(self,arg_s,runner=None):
95 """Modified version of %run that syncs testing namespaces.
93 """Modified version of %run that syncs testing namespaces.
96
94
97 This is strictly needed for running doctests that call %run.
95 This is strictly needed for running doctests that call %run.
98 """
96 """
99
97
100 # When tests call %run directly (not via doctest) these function attributes
98 # When tests call %run directly (not via doctest) these function attributes
101 # are not set
99 # are not set
102 try:
100 try:
103 fname = _run_ns_sync.test_filename
101 fname = _run_ns_sync.test_filename
104 except AttributeError:
102 except AttributeError:
105 fname = arg_s
103 fname = arg_s
106
104
107 finder = py_file_finder(fname)
105 finder = py_file_finder(fname)
108 out = _ip.magic_run_ori(arg_s,runner,finder)
106 out = _ip.magic_run_ori(arg_s,runner,finder)
109
107
110 # Simliarly, there is no test_globs when a test is NOT a doctest
108 # Simliarly, there is no test_globs when a test is NOT a doctest
111 if hasattr(_run_ns_sync,'test_globs'):
109 if hasattr(_run_ns_sync,'test_globs'):
112 _run_ns_sync.test_globs.update(_ip.user_ns)
110 _run_ns_sync.test_globs.update(_ip.user_ns)
113 return out
111 return out
114
112
115
113
116 class ipnsdict(dict):
114 class ipnsdict(dict):
117 """A special subclass of dict for use as an IPython namespace in doctests.
115 """A special subclass of dict for use as an IPython namespace in doctests.
118
116
119 This subclass adds a simple checkpointing capability so that when testing
117 This subclass adds a simple checkpointing capability so that when testing
120 machinery clears it (we use it as the test execution context), it doesn't
118 machinery clears it (we use it as the test execution context), it doesn't
121 get completely destroyed.
119 get completely destroyed.
122 """
120 """
123
121
124 def __init__(self,*a):
122 def __init__(self,*a):
125 dict.__init__(self,*a)
123 dict.__init__(self,*a)
126 self._savedict = {}
124 self._savedict = {}
127
125
128 def clear(self):
126 def clear(self):
129 dict.clear(self)
127 dict.clear(self)
130 self.update(self._savedict)
128 self.update(self._savedict)
131
129
132 def _checkpoint(self):
130 def _checkpoint(self):
133 self._savedict.clear()
131 self._savedict.clear()
134 self._savedict.update(self)
132 self._savedict.update(self)
135
133
136 def update(self,other):
134 def update(self,other):
137 self._checkpoint()
135 self._checkpoint()
138 dict.update(self,other)
136 dict.update(self,other)
139
137
140 # If '_' is in the namespace, python won't set it when executing code,
138 # If '_' is in the namespace, python won't set it when executing code,
141 # and we have examples that test it. So we ensure that the namespace
139 # and we have examples that test it. So we ensure that the namespace
142 # is always 'clean' of it before it's used for test code execution.
140 # is always 'clean' of it before it's used for test code execution.
143 self.pop('_',None)
141 self.pop('_',None)
144
142
145 # The builtins namespace must *always* be the real __builtin__ module,
143 # The builtins namespace must *always* be the real __builtin__ module,
146 # else weird stuff happens. The main ipython code does have provisions
144 # else weird stuff happens. The main ipython code does have provisions
147 # to ensure this after %run, but since in this class we do some
145 # to ensure this after %run, but since in this class we do some
148 # aggressive low-level cleaning of the execution namespace, we need to
146 # aggressive low-level cleaning of the execution namespace, we need to
149 # correct for that ourselves, to ensure consitency with the 'real'
147 # correct for that ourselves, to ensure consitency with the 'real'
150 # ipython.
148 # ipython.
151 self['__builtins__'] = __builtin__
149 self['__builtins__'] = __builtin__
152
150
153
151
154 def start_ipython():
152 def start_ipython():
155 """Start a global IPython shell, which we need for IPython-specific syntax.
153 """Start a global IPython shell, which we need for IPython-specific syntax.
156 """
154 """
157
155
158 # This function should only ever run once!
156 # This function should only ever run once!
159 if hasattr(start_ipython,'already_called'):
157 if hasattr(start_ipython,'already_called'):
160 return
158 return
161 start_ipython.already_called = True
159 start_ipython.already_called = True
162
160
163 # Ok, first time we're called, go ahead
161 # Ok, first time we're called, go ahead
164 import new
162 import new
165
163
166 import IPython
164 import IPython
167 from IPython.core import ipapi
165 from IPython.core import ipapp, iplib
168
166
169 def xsys(cmd):
167 def xsys(cmd):
170 """Execute a command and print its output.
168 """Execute a command and print its output.
171
169
172 This is just a convenience function to replace the IPython system call
170 This is just a convenience function to replace the IPython system call
173 with one that is more doctest-friendly.
171 with one that is more doctest-friendly.
174 """
172 """
175 cmd = _ip.var_expand(cmd,depth=1)
173 cmd = _ip.var_expand(cmd,depth=1)
176 sys.stdout.write(commands.getoutput(cmd))
174 sys.stdout.write(commands.getoutput(cmd))
177 sys.stdout.flush()
175 sys.stdout.flush()
178
176
179 # Store certain global objects that IPython modifies
177 # Store certain global objects that IPython modifies
180 _displayhook = sys.displayhook
178 _displayhook = sys.displayhook
181 _excepthook = sys.excepthook
179 _excepthook = sys.excepthook
182 _main = sys.modules.get('__main__')
180 _main = sys.modules.get('__main__')
183
181
184 argv = default_argv()
182 argv = default_argv()
185
183
186 # Start IPython instance. We customize it to start with minimal frills.
184 # Start IPython instance. We customize it to start with minimal frills.
187 IPython.shell.IPShell(argv,ipnsdict(),global_ns)
185 user_ns,global_ns = iplib.make_user_namespaces(ipnsdict(),{})
186 ip = ipapp.IPythonApp(argv, user_ns=user_ns, user_global_ns=global_ns)
187 ip.initialize()
188 ip.shell.builtin_trap.set()
188
189
189 # Deactivate the various python system hooks added by ipython for
190 # Deactivate the various python system hooks added by ipython for
190 # interactive convenience so we don't confuse the doctest system
191 # interactive convenience so we don't confuse the doctest system
191 sys.modules['__main__'] = _main
192 sys.modules['__main__'] = _main
192 sys.displayhook = _displayhook
193 sys.displayhook = _displayhook
193 sys.excepthook = _excepthook
194 sys.excepthook = _excepthook
194
195
195 # So that ipython magics and aliases can be doctested (they work by making
196 # So that ipython magics and aliases can be doctested (they work by making
196 # a call into a global _ip object)
197 # a call into a global _ip object)
197 _ip = ipapi.get()
198 __builtin__._ip = ip.shell
198 __builtin__._ip = _ip
199
199
200 # Modify the IPython system call with one that uses getoutput, so that we
200 # Modify the IPython system call with one that uses getoutput, so that we
201 # can capture subcommands and print them to Python's stdout, otherwise the
201 # can capture subcommands and print them to Python's stdout, otherwise the
202 # doctest machinery would miss them.
202 # doctest machinery would miss them.
203 _ip.system = xsys
203 ip.shell.system = xsys
204
204
205 # Also patch our %run function in.
205 # Also patch our %run function in.
206 im = new.instancemethod(_run_ns_sync,_ip, _ip.__class__)
206 im = new.instancemethod(_run_ns_sync,_ip, _ip.__class__)
207 _ip.magic_run_ori = _ip.magic_run
207 ip.shell.magic_run_ori = _ip.magic_run
208 _ip.magic_run = im
208 ip.shell.magic_run = im
209
209
210 # XXX - For some very bizarre reason, the loading of %history by default is
210 # XXX - For some very bizarre reason, the loading of %history by default is
211 # failing. This needs to be fixed later, but for now at least this ensures
211 # failing. This needs to be fixed later, but for now at least this ensures
212 # that tests that use %hist run to completion.
212 # that tests that use %hist run to completion.
213 from IPython.core import history
213 from IPython.core import history
214 history.init_ipython(_ip)
214 history.init_ipython(ip.shell)
215 if not hasattr(_ip,'magic_history'):
215 if not hasattr(ip.shell,'magic_history'):
216 raise RuntimeError("Can't load magics, aborting")
216 raise RuntimeError("Can't load magics, aborting")
217
217
218
218
219 # The start call MUST be made here. I'm not sure yet why it doesn't work if
219 # The start call MUST be made here. I'm not sure yet why it doesn't work if
220 # it is made later, at plugin initialization time, but in all my tests, that's
220 # it is made later, at plugin initialization time, but in all my tests, that's
221 # the case.
221 # the case.
222 start_ipython()
222 start_ipython()
223
223
224 # *** END HACK ***
224 # *** END HACK ***
225 ###########################################################################
225 ###########################################################################
226
226
227 # Classes and functions
227 # Classes and functions
228
228
229 def is_extension_module(filename):
229 def is_extension_module(filename):
230 """Return whether the given filename is an extension module.
230 """Return whether the given filename is an extension module.
231
231
232 This simply checks that the extension is either .so or .pyd.
232 This simply checks that the extension is either .so or .pyd.
233 """
233 """
234 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
234 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
235
235
236
236
237 class DocTestSkip(object):
237 class DocTestSkip(object):
238 """Object wrapper for doctests to be skipped."""
238 """Object wrapper for doctests to be skipped."""
239
239
240 ds_skip = """Doctest to skip.
240 ds_skip = """Doctest to skip.
241 >>> 1 #doctest: +SKIP
241 >>> 1 #doctest: +SKIP
242 """
242 """
243
243
244 def __init__(self,obj):
244 def __init__(self,obj):
245 self.obj = obj
245 self.obj = obj
246
246
247 def __getattribute__(self,key):
247 def __getattribute__(self,key):
248 if key == '__doc__':
248 if key == '__doc__':
249 return DocTestSkip.ds_skip
249 return DocTestSkip.ds_skip
250 else:
250 else:
251 return getattr(object.__getattribute__(self,'obj'),key)
251 return getattr(object.__getattribute__(self,'obj'),key)
252
252
253 # Modified version of the one in the stdlib, that fixes a python bug (doctests
253 # Modified version of the one in the stdlib, that fixes a python bug (doctests
254 # not found in extension modules, http://bugs.python.org/issue3158)
254 # not found in extension modules, http://bugs.python.org/issue3158)
255 class DocTestFinder(doctest.DocTestFinder):
255 class DocTestFinder(doctest.DocTestFinder):
256
256
257 def _from_module(self, module, object):
257 def _from_module(self, module, object):
258 """
258 """
259 Return true if the given object is defined in the given
259 Return true if the given object is defined in the given
260 module.
260 module.
261 """
261 """
262 if module is None:
262 if module is None:
263 return True
263 return True
264 elif inspect.isfunction(object):
264 elif inspect.isfunction(object):
265 return module.__dict__ is object.func_globals
265 return module.__dict__ is object.func_globals
266 elif inspect.isbuiltin(object):
266 elif inspect.isbuiltin(object):
267 return module.__name__ == object.__module__
267 return module.__name__ == object.__module__
268 elif inspect.isclass(object):
268 elif inspect.isclass(object):
269 return module.__name__ == object.__module__
269 return module.__name__ == object.__module__
270 elif inspect.ismethod(object):
270 elif inspect.ismethod(object):
271 # This one may be a bug in cython that fails to correctly set the
271 # This one may be a bug in cython that fails to correctly set the
272 # __module__ attribute of methods, but since the same error is easy
272 # __module__ attribute of methods, but since the same error is easy
273 # to make by extension code writers, having this safety in place
273 # to make by extension code writers, having this safety in place
274 # isn't such a bad idea
274 # isn't such a bad idea
275 return module.__name__ == object.im_class.__module__
275 return module.__name__ == object.im_class.__module__
276 elif inspect.getmodule(object) is not None:
276 elif inspect.getmodule(object) is not None:
277 return module is inspect.getmodule(object)
277 return module is inspect.getmodule(object)
278 elif hasattr(object, '__module__'):
278 elif hasattr(object, '__module__'):
279 return module.__name__ == object.__module__
279 return module.__name__ == object.__module__
280 elif isinstance(object, property):
280 elif isinstance(object, property):
281 return True # [XX] no way not be sure.
281 return True # [XX] no way not be sure.
282 else:
282 else:
283 raise ValueError("object must be a class or function")
283 raise ValueError("object must be a class or function")
284
284
285 def _find(self, tests, obj, name, module, source_lines, globs, seen):
285 def _find(self, tests, obj, name, module, source_lines, globs, seen):
286 """
286 """
287 Find tests for the given object and any contained objects, and
287 Find tests for the given object and any contained objects, and
288 add them to `tests`.
288 add them to `tests`.
289 """
289 """
290
290
291 if hasattr(obj,"skip_doctest"):
291 if hasattr(obj,"skip_doctest"):
292 #print 'SKIPPING DOCTEST FOR:',obj # dbg
292 #print 'SKIPPING DOCTEST FOR:',obj # dbg
293 obj = DocTestSkip(obj)
293 obj = DocTestSkip(obj)
294
294
295 doctest.DocTestFinder._find(self,tests, obj, name, module,
295 doctest.DocTestFinder._find(self,tests, obj, name, module,
296 source_lines, globs, seen)
296 source_lines, globs, seen)
297
297
298 # Below we re-run pieces of the above method with manual modifications,
298 # Below we re-run pieces of the above method with manual modifications,
299 # because the original code is buggy and fails to correctly identify
299 # because the original code is buggy and fails to correctly identify
300 # doctests in extension modules.
300 # doctests in extension modules.
301
301
302 # Local shorthands
302 # Local shorthands
303 from inspect import isroutine, isclass, ismodule
303 from inspect import isroutine, isclass, ismodule
304
304
305 # Look for tests in a module's contained objects.
305 # Look for tests in a module's contained objects.
306 if inspect.ismodule(obj) and self._recurse:
306 if inspect.ismodule(obj) and self._recurse:
307 for valname, val in obj.__dict__.items():
307 for valname, val in obj.__dict__.items():
308 valname1 = '%s.%s' % (name, valname)
308 valname1 = '%s.%s' % (name, valname)
309 if ( (isroutine(val) or isclass(val))
309 if ( (isroutine(val) or isclass(val))
310 and self._from_module(module, val) ):
310 and self._from_module(module, val) ):
311
311
312 self._find(tests, val, valname1, module, source_lines,
312 self._find(tests, val, valname1, module, source_lines,
313 globs, seen)
313 globs, seen)
314
314
315 # Look for tests in a class's contained objects.
315 # Look for tests in a class's contained objects.
316 if inspect.isclass(obj) and self._recurse:
316 if inspect.isclass(obj) and self._recurse:
317 #print 'RECURSE into class:',obj # dbg
317 #print 'RECURSE into class:',obj # dbg
318 for valname, val in obj.__dict__.items():
318 for valname, val in obj.__dict__.items():
319 # Special handling for staticmethod/classmethod.
319 # Special handling for staticmethod/classmethod.
320 if isinstance(val, staticmethod):
320 if isinstance(val, staticmethod):
321 val = getattr(obj, valname)
321 val = getattr(obj, valname)
322 if isinstance(val, classmethod):
322 if isinstance(val, classmethod):
323 val = getattr(obj, valname).im_func
323 val = getattr(obj, valname).im_func
324
324
325 # Recurse to methods, properties, and nested classes.
325 # Recurse to methods, properties, and nested classes.
326 if ((inspect.isfunction(val) or inspect.isclass(val) or
326 if ((inspect.isfunction(val) or inspect.isclass(val) or
327 inspect.ismethod(val) or
327 inspect.ismethod(val) or
328 isinstance(val, property)) and
328 isinstance(val, property)) and
329 self._from_module(module, val)):
329 self._from_module(module, val)):
330 valname = '%s.%s' % (name, valname)
330 valname = '%s.%s' % (name, valname)
331 self._find(tests, val, valname, module, source_lines,
331 self._find(tests, val, valname, module, source_lines,
332 globs, seen)
332 globs, seen)
333
333
334
334
335 class IPDoctestOutputChecker(doctest.OutputChecker):
335 class IPDoctestOutputChecker(doctest.OutputChecker):
336 """Second-chance checker with support for random tests.
336 """Second-chance checker with support for random tests.
337
337
338 If the default comparison doesn't pass, this checker looks in the expected
338 If the default comparison doesn't pass, this checker looks in the expected
339 output string for flags that tell us to ignore the output.
339 output string for flags that tell us to ignore the output.
340 """
340 """
341
341
342 random_re = re.compile(r'#\s*random\s+')
342 random_re = re.compile(r'#\s*random\s+')
343
343
344 def check_output(self, want, got, optionflags):
344 def check_output(self, want, got, optionflags):
345 """Check output, accepting special markers embedded in the output.
345 """Check output, accepting special markers embedded in the output.
346
346
347 If the output didn't pass the default validation but the special string
347 If the output didn't pass the default validation but the special string
348 '#random' is included, we accept it."""
348 '#random' is included, we accept it."""
349
349
350 # Let the original tester verify first, in case people have valid tests
350 # Let the original tester verify first, in case people have valid tests
351 # that happen to have a comment saying '#random' embedded in.
351 # that happen to have a comment saying '#random' embedded in.
352 ret = doctest.OutputChecker.check_output(self, want, got,
352 ret = doctest.OutputChecker.check_output(self, want, got,
353 optionflags)
353 optionflags)
354 if not ret and self.random_re.search(want):
354 if not ret and self.random_re.search(want):
355 #print >> sys.stderr, 'RANDOM OK:',want # dbg
355 #print >> sys.stderr, 'RANDOM OK:',want # dbg
356 return True
356 return True
357
357
358 return ret
358 return ret
359
359
360
360
361 class DocTestCase(doctests.DocTestCase):
361 class DocTestCase(doctests.DocTestCase):
362 """Proxy for DocTestCase: provides an address() method that
362 """Proxy for DocTestCase: provides an address() method that
363 returns the correct address for the doctest case. Otherwise
363 returns the correct address for the doctest case. Otherwise
364 acts as a proxy to the test case. To provide hints for address(),
364 acts as a proxy to the test case. To provide hints for address(),
365 an obj may also be passed -- this will be used as the test object
365 an obj may also be passed -- this will be used as the test object
366 for purposes of determining the test address, if it is provided.
366 for purposes of determining the test address, if it is provided.
367 """
367 """
368
368
369 # Note: this method was taken from numpy's nosetester module.
369 # Note: this method was taken from numpy's nosetester module.
370
370
371 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
371 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
372 # its constructor that blocks non-default arguments from being passed
372 # its constructor that blocks non-default arguments from being passed
373 # down into doctest.DocTestCase
373 # down into doctest.DocTestCase
374
374
375 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
375 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
376 checker=None, obj=None, result_var='_'):
376 checker=None, obj=None, result_var='_'):
377 self._result_var = result_var
377 self._result_var = result_var
378 doctests.DocTestCase.__init__(self, test,
378 doctests.DocTestCase.__init__(self, test,
379 optionflags=optionflags,
379 optionflags=optionflags,
380 setUp=setUp, tearDown=tearDown,
380 setUp=setUp, tearDown=tearDown,
381 checker=checker)
381 checker=checker)
382 # Now we must actually copy the original constructor from the stdlib
382 # Now we must actually copy the original constructor from the stdlib
383 # doctest class, because we can't call it directly and a bug in nose
383 # doctest class, because we can't call it directly and a bug in nose
384 # means it never gets passed the right arguments.
384 # means it never gets passed the right arguments.
385
385
386 self._dt_optionflags = optionflags
386 self._dt_optionflags = optionflags
387 self._dt_checker = checker
387 self._dt_checker = checker
388 self._dt_test = test
388 self._dt_test = test
389 self._dt_setUp = setUp
389 self._dt_setUp = setUp
390 self._dt_tearDown = tearDown
390 self._dt_tearDown = tearDown
391
391
392 # XXX - store this runner once in the object!
392 # XXX - store this runner once in the object!
393 runner = IPDocTestRunner(optionflags=optionflags,
393 runner = IPDocTestRunner(optionflags=optionflags,
394 checker=checker, verbose=False)
394 checker=checker, verbose=False)
395 self._dt_runner = runner
395 self._dt_runner = runner
396
396
397
397
398 # Each doctest should remember what directory it was loaded from...
398 # Each doctest should remember what directory it was loaded from...
399 self._ori_dir = os.getcwd()
399 self._ori_dir = os.getcwd()
400
400
401 # Modified runTest from the default stdlib
401 # Modified runTest from the default stdlib
402 def runTest(self):
402 def runTest(self):
403 test = self._dt_test
403 test = self._dt_test
404 runner = self._dt_runner
404 runner = self._dt_runner
405
405
406 old = sys.stdout
406 old = sys.stdout
407 new = StringIO()
407 new = StringIO()
408 optionflags = self._dt_optionflags
408 optionflags = self._dt_optionflags
409
409
410 if not (optionflags & REPORTING_FLAGS):
410 if not (optionflags & REPORTING_FLAGS):
411 # The option flags don't include any reporting flags,
411 # The option flags don't include any reporting flags,
412 # so add the default reporting flags
412 # so add the default reporting flags
413 optionflags |= _unittest_reportflags
413 optionflags |= _unittest_reportflags
414
414
415 try:
415 try:
416 # Save our current directory and switch out to the one where the
416 # Save our current directory and switch out to the one where the
417 # test was originally created, in case another doctest did a
417 # test was originally created, in case another doctest did a
418 # directory change. We'll restore this in the finally clause.
418 # directory change. We'll restore this in the finally clause.
419 curdir = os.getcwd()
419 curdir = os.getcwd()
420 os.chdir(self._ori_dir)
420 os.chdir(self._ori_dir)
421
421
422 runner.DIVIDER = "-"*70
422 runner.DIVIDER = "-"*70
423 failures, tries = runner.run(test,out=new.write,
423 failures, tries = runner.run(test,out=new.write,
424 clear_globs=False)
424 clear_globs=False)
425 finally:
425 finally:
426 sys.stdout = old
426 sys.stdout = old
427 os.chdir(curdir)
427 os.chdir(curdir)
428
428
429 if failures:
429 if failures:
430 raise self.failureException(self.format_failure(new.getvalue()))
430 raise self.failureException(self.format_failure(new.getvalue()))
431
431
432 def setUp(self):
432 def setUp(self):
433 """Modified test setup that syncs with ipython namespace"""
433 """Modified test setup that syncs with ipython namespace"""
434
434
435 if isinstance(self._dt_test.examples[0],IPExample):
435 if isinstance(self._dt_test.examples[0],IPExample):
436 # for IPython examples *only*, we swap the globals with the ipython
436 # for IPython examples *only*, we swap the globals with the ipython
437 # namespace, after updating it with the globals (which doctest
437 # namespace, after updating it with the globals (which doctest
438 # fills with the necessary info from the module being tested).
438 # fills with the necessary info from the module being tested).
439 _ip.user_ns.update(self._dt_test.globs)
439 _ip.user_ns.update(self._dt_test.globs)
440 self._dt_test.globs = _ip.user_ns
440 self._dt_test.globs = _ip.user_ns
441
441
442 super(DocTestCase, self).setUp()
442 super(DocTestCase, self).setUp()
443
443
444 def tearDown(self):
444 def tearDown(self):
445 # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but
445 # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but
446 # it does look like one to me: its tearDown method tries to run
446 # it does look like one to me: its tearDown method tries to run
447 #
447 #
448 # delattr(__builtin__, self._result_var)
448 # delattr(__builtin__, self._result_var)
449 #
449 #
450 # without checking that the attribute really is there; it implicitly
450 # without checking that the attribute really is there; it implicitly
451 # assumes it should have been set via displayhook. But if the
451 # assumes it should have been set via displayhook. But if the
452 # displayhook was never called, this doesn't necessarily happen. I
452 # displayhook was never called, this doesn't necessarily happen. I
453 # haven't been able to find a little self-contained example outside of
453 # haven't been able to find a little self-contained example outside of
454 # ipython that would show the problem so I can report it to the nose
454 # ipython that would show the problem so I can report it to the nose
455 # team, but it does happen a lot in our code.
455 # team, but it does happen a lot in our code.
456 #
456 #
457 # So here, we just protect as narrowly as possible by trapping an
457 # So here, we just protect as narrowly as possible by trapping an
458 # attribute error whose message would be the name of self._result_var,
458 # attribute error whose message would be the name of self._result_var,
459 # and letting any other error propagate.
459 # and letting any other error propagate.
460 try:
460 try:
461 super(DocTestCase, self).tearDown()
461 super(DocTestCase, self).tearDown()
462 except AttributeError, exc:
462 except AttributeError, exc:
463 if exc.args[0] != self._result_var:
463 if exc.args[0] != self._result_var:
464 raise
464 raise
465
465
466
466
467 # A simple subclassing of the original with a different class name, so we can
467 # A simple subclassing of the original with a different class name, so we can
468 # distinguish and treat differently IPython examples from pure python ones.
468 # distinguish and treat differently IPython examples from pure python ones.
469 class IPExample(doctest.Example): pass
469 class IPExample(doctest.Example): pass
470
470
471
471
472 class IPExternalExample(doctest.Example):
472 class IPExternalExample(doctest.Example):
473 """Doctest examples to be run in an external process."""
473 """Doctest examples to be run in an external process."""
474
474
475 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
475 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
476 options=None):
476 options=None):
477 # Parent constructor
477 # Parent constructor
478 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
478 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
479
479
480 # An EXTRA newline is needed to prevent pexpect hangs
480 # An EXTRA newline is needed to prevent pexpect hangs
481 self.source += '\n'
481 self.source += '\n'
482
482
483
483
484 class IPDocTestParser(doctest.DocTestParser):
484 class IPDocTestParser(doctest.DocTestParser):
485 """
485 """
486 A class used to parse strings containing doctest examples.
486 A class used to parse strings containing doctest examples.
487
487
488 Note: This is a version modified to properly recognize IPython input and
488 Note: This is a version modified to properly recognize IPython input and
489 convert any IPython examples into valid Python ones.
489 convert any IPython examples into valid Python ones.
490 """
490 """
491 # This regular expression is used to find doctest examples in a
491 # This regular expression is used to find doctest examples in a
492 # string. It defines three groups: `source` is the source code
492 # string. It defines three groups: `source` is the source code
493 # (including leading indentation and prompts); `indent` is the
493 # (including leading indentation and prompts); `indent` is the
494 # indentation of the first (PS1) line of the source code; and
494 # indentation of the first (PS1) line of the source code; and
495 # `want` is the expected output (including leading indentation).
495 # `want` is the expected output (including leading indentation).
496
496
497 # Classic Python prompts or default IPython ones
497 # Classic Python prompts or default IPython ones
498 _PS1_PY = r'>>>'
498 _PS1_PY = r'>>>'
499 _PS2_PY = r'\.\.\.'
499 _PS2_PY = r'\.\.\.'
500
500
501 _PS1_IP = r'In\ \[\d+\]:'
501 _PS1_IP = r'In\ \[\d+\]:'
502 _PS2_IP = r'\ \ \ \.\.\.+:'
502 _PS2_IP = r'\ \ \ \.\.\.+:'
503
503
504 _RE_TPL = r'''
504 _RE_TPL = r'''
505 # Source consists of a PS1 line followed by zero or more PS2 lines.
505 # Source consists of a PS1 line followed by zero or more PS2 lines.
506 (?P<source>
506 (?P<source>
507 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
507 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
508 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
508 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
509 \n? # a newline
509 \n? # a newline
510 # Want consists of any non-blank lines that do not start with PS1.
510 # Want consists of any non-blank lines that do not start with PS1.
511 (?P<want> (?:(?![ ]*$) # Not a blank line
511 (?P<want> (?:(?![ ]*$) # Not a blank line
512 (?![ ]*%s) # Not a line starting with PS1
512 (?![ ]*%s) # Not a line starting with PS1
513 (?![ ]*%s) # Not a line starting with PS2
513 (?![ ]*%s) # Not a line starting with PS2
514 .*$\n? # But any other line
514 .*$\n? # But any other line
515 )*)
515 )*)
516 '''
516 '''
517
517
518 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
518 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
519 re.MULTILINE | re.VERBOSE)
519 re.MULTILINE | re.VERBOSE)
520
520
521 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
521 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
522 re.MULTILINE | re.VERBOSE)
522 re.MULTILINE | re.VERBOSE)
523
523
524 # Mark a test as being fully random. In this case, we simply append the
524 # Mark a test as being fully random. In this case, we simply append the
525 # random marker ('#random') to each individual example's output. This way
525 # random marker ('#random') to each individual example's output. This way
526 # we don't need to modify any other code.
526 # we don't need to modify any other code.
527 _RANDOM_TEST = re.compile(r'#\s*all-random\s+')
527 _RANDOM_TEST = re.compile(r'#\s*all-random\s+')
528
528
529 # Mark tests to be executed in an external process - currently unsupported.
529 # Mark tests to be executed in an external process - currently unsupported.
530 _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL')
530 _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL')
531
531
532 def ip2py(self,source):
532 def ip2py(self,source):
533 """Convert input IPython source into valid Python."""
533 """Convert input IPython source into valid Python."""
534 out = []
534 out = []
535 newline = out.append
535 newline = out.append
536 #print 'IPSRC:\n',source,'\n###' # dbg
536 #print 'IPSRC:\n',source,'\n###' # dbg
537 # The input source must be first stripped of all bracketing whitespace
537 # The input source must be first stripped of all bracketing whitespace
538 # and turned into lines, so it looks to the parser like regular user
538 # and turned into lines, so it looks to the parser like regular user
539 # input
539 # input
540 for lnum,line in enumerate(source.strip().splitlines()):
540 for lnum,line in enumerate(source.strip().splitlines()):
541 newline(_ip.prefilter(line,lnum>0))
541 newline(_ip.prefilter(line,lnum>0))
542 newline('') # ensure a closing newline, needed by doctest
542 newline('') # ensure a closing newline, needed by doctest
543 #print "PYSRC:", '\n'.join(out) # dbg
543 #print "PYSRC:", '\n'.join(out) # dbg
544 return '\n'.join(out)
544 return '\n'.join(out)
545
545
546 def parse(self, string, name='<string>'):
546 def parse(self, string, name='<string>'):
547 """
547 """
548 Divide the given string into examples and intervening text,
548 Divide the given string into examples and intervening text,
549 and return them as a list of alternating Examples and strings.
549 and return them as a list of alternating Examples and strings.
550 Line numbers for the Examples are 0-based. The optional
550 Line numbers for the Examples are 0-based. The optional
551 argument `name` is a name identifying this string, and is only
551 argument `name` is a name identifying this string, and is only
552 used for error messages.
552 used for error messages.
553 """
553 """
554
554
555 #print 'Parse string:\n',string # dbg
555 #print 'Parse string:\n',string # dbg
556
556
557 string = string.expandtabs()
557 string = string.expandtabs()
558 # If all lines begin with the same indentation, then strip it.
558 # If all lines begin with the same indentation, then strip it.
559 min_indent = self._min_indent(string)
559 min_indent = self._min_indent(string)
560 if min_indent > 0:
560 if min_indent > 0:
561 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
561 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
562
562
563 output = []
563 output = []
564 charno, lineno = 0, 0
564 charno, lineno = 0, 0
565
565
566 # We make 'all random' tests by adding the '# random' mark to every
566 # We make 'all random' tests by adding the '# random' mark to every
567 # block of output in the test.
567 # block of output in the test.
568 if self._RANDOM_TEST.search(string):
568 if self._RANDOM_TEST.search(string):
569 random_marker = '\n# random'
569 random_marker = '\n# random'
570 else:
570 else:
571 random_marker = ''
571 random_marker = ''
572
572
573 # Whether to convert the input from ipython to python syntax
573 # Whether to convert the input from ipython to python syntax
574 ip2py = False
574 ip2py = False
575 # Find all doctest examples in the string. First, try them as Python
575 # Find all doctest examples in the string. First, try them as Python
576 # examples, then as IPython ones
576 # examples, then as IPython ones
577 terms = list(self._EXAMPLE_RE_PY.finditer(string))
577 terms = list(self._EXAMPLE_RE_PY.finditer(string))
578 if terms:
578 if terms:
579 # Normal Python example
579 # Normal Python example
580 #print '-'*70 # dbg
580 #print '-'*70 # dbg
581 #print 'PyExample, Source:\n',string # dbg
581 #print 'PyExample, Source:\n',string # dbg
582 #print '-'*70 # dbg
582 #print '-'*70 # dbg
583 Example = doctest.Example
583 Example = doctest.Example
584 else:
584 else:
585 # It's an ipython example. Note that IPExamples are run
585 # It's an ipython example. Note that IPExamples are run
586 # in-process, so their syntax must be turned into valid python.
586 # in-process, so their syntax must be turned into valid python.
587 # IPExternalExamples are run out-of-process (via pexpect) so they
587 # IPExternalExamples are run out-of-process (via pexpect) so they
588 # don't need any filtering (a real ipython will be executing them).
588 # don't need any filtering (a real ipython will be executing them).
589 terms = list(self._EXAMPLE_RE_IP.finditer(string))
589 terms = list(self._EXAMPLE_RE_IP.finditer(string))
590 if self._EXTERNAL_IP.search(string):
590 if self._EXTERNAL_IP.search(string):
591 #print '-'*70 # dbg
591 #print '-'*70 # dbg
592 #print 'IPExternalExample, Source:\n',string # dbg
592 #print 'IPExternalExample, Source:\n',string # dbg
593 #print '-'*70 # dbg
593 #print '-'*70 # dbg
594 Example = IPExternalExample
594 Example = IPExternalExample
595 else:
595 else:
596 #print '-'*70 # dbg
596 #print '-'*70 # dbg
597 #print 'IPExample, Source:\n',string # dbg
597 #print 'IPExample, Source:\n',string # dbg
598 #print '-'*70 # dbg
598 #print '-'*70 # dbg
599 Example = IPExample
599 Example = IPExample
600 ip2py = True
600 ip2py = True
601
601
602 for m in terms:
602 for m in terms:
603 # Add the pre-example text to `output`.
603 # Add the pre-example text to `output`.
604 output.append(string[charno:m.start()])
604 output.append(string[charno:m.start()])
605 # Update lineno (lines before this example)
605 # Update lineno (lines before this example)
606 lineno += string.count('\n', charno, m.start())
606 lineno += string.count('\n', charno, m.start())
607 # Extract info from the regexp match.
607 # Extract info from the regexp match.
608 (source, options, want, exc_msg) = \
608 (source, options, want, exc_msg) = \
609 self._parse_example(m, name, lineno,ip2py)
609 self._parse_example(m, name, lineno,ip2py)
610
610
611 # Append the random-output marker (it defaults to empty in most
611 # Append the random-output marker (it defaults to empty in most
612 # cases, it's only non-empty for 'all-random' tests):
612 # cases, it's only non-empty for 'all-random' tests):
613 want += random_marker
613 want += random_marker
614
614
615 if Example is IPExternalExample:
615 if Example is IPExternalExample:
616 options[doctest.NORMALIZE_WHITESPACE] = True
616 options[doctest.NORMALIZE_WHITESPACE] = True
617 want += '\n'
617 want += '\n'
618
618
619 # Create an Example, and add it to the list.
619 # Create an Example, and add it to the list.
620 if not self._IS_BLANK_OR_COMMENT(source):
620 if not self._IS_BLANK_OR_COMMENT(source):
621 output.append(Example(source, want, exc_msg,
621 output.append(Example(source, want, exc_msg,
622 lineno=lineno,
622 lineno=lineno,
623 indent=min_indent+len(m.group('indent')),
623 indent=min_indent+len(m.group('indent')),
624 options=options))
624 options=options))
625 # Update lineno (lines inside this example)
625 # Update lineno (lines inside this example)
626 lineno += string.count('\n', m.start(), m.end())
626 lineno += string.count('\n', m.start(), m.end())
627 # Update charno.
627 # Update charno.
628 charno = m.end()
628 charno = m.end()
629 # Add any remaining post-example text to `output`.
629 # Add any remaining post-example text to `output`.
630 output.append(string[charno:])
630 output.append(string[charno:])
631 return output
631 return output
632
632
633 def _parse_example(self, m, name, lineno,ip2py=False):
633 def _parse_example(self, m, name, lineno,ip2py=False):
634 """
634 """
635 Given a regular expression match from `_EXAMPLE_RE` (`m`),
635 Given a regular expression match from `_EXAMPLE_RE` (`m`),
636 return a pair `(source, want)`, where `source` is the matched
636 return a pair `(source, want)`, where `source` is the matched
637 example's source code (with prompts and indentation stripped);
637 example's source code (with prompts and indentation stripped);
638 and `want` is the example's expected output (with indentation
638 and `want` is the example's expected output (with indentation
639 stripped).
639 stripped).
640
640
641 `name` is the string's name, and `lineno` is the line number
641 `name` is the string's name, and `lineno` is the line number
642 where the example starts; both are used for error messages.
642 where the example starts; both are used for error messages.
643
643
644 Optional:
644 Optional:
645 `ip2py`: if true, filter the input via IPython to convert the syntax
645 `ip2py`: if true, filter the input via IPython to convert the syntax
646 into valid python.
646 into valid python.
647 """
647 """
648
648
649 # Get the example's indentation level.
649 # Get the example's indentation level.
650 indent = len(m.group('indent'))
650 indent = len(m.group('indent'))
651
651
652 # Divide source into lines; check that they're properly
652 # Divide source into lines; check that they're properly
653 # indented; and then strip their indentation & prompts.
653 # indented; and then strip their indentation & prompts.
654 source_lines = m.group('source').split('\n')
654 source_lines = m.group('source').split('\n')
655
655
656 # We're using variable-length input prompts
656 # We're using variable-length input prompts
657 ps1 = m.group('ps1')
657 ps1 = m.group('ps1')
658 ps2 = m.group('ps2')
658 ps2 = m.group('ps2')
659 ps1_len = len(ps1)
659 ps1_len = len(ps1)
660
660
661 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
661 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
662 if ps2:
662 if ps2:
663 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
663 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
664
664
665 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
665 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
666
666
667 if ip2py:
667 if ip2py:
668 # Convert source input from IPython into valid Python syntax
668 # Convert source input from IPython into valid Python syntax
669 source = self.ip2py(source)
669 source = self.ip2py(source)
670
670
671 # Divide want into lines; check that it's properly indented; and
671 # Divide want into lines; check that it's properly indented; and
672 # then strip the indentation. Spaces before the last newline should
672 # then strip the indentation. Spaces before the last newline should
673 # be preserved, so plain rstrip() isn't good enough.
673 # be preserved, so plain rstrip() isn't good enough.
674 want = m.group('want')
674 want = m.group('want')
675 want_lines = want.split('\n')
675 want_lines = want.split('\n')
676 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
676 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
677 del want_lines[-1] # forget final newline & spaces after it
677 del want_lines[-1] # forget final newline & spaces after it
678 self._check_prefix(want_lines, ' '*indent, name,
678 self._check_prefix(want_lines, ' '*indent, name,
679 lineno + len(source_lines))
679 lineno + len(source_lines))
680
680
681 # Remove ipython output prompt that might be present in the first line
681 # Remove ipython output prompt that might be present in the first line
682 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
682 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
683
683
684 want = '\n'.join([wl[indent:] for wl in want_lines])
684 want = '\n'.join([wl[indent:] for wl in want_lines])
685
685
686 # If `want` contains a traceback message, then extract it.
686 # If `want` contains a traceback message, then extract it.
687 m = self._EXCEPTION_RE.match(want)
687 m = self._EXCEPTION_RE.match(want)
688 if m:
688 if m:
689 exc_msg = m.group('msg')
689 exc_msg = m.group('msg')
690 else:
690 else:
691 exc_msg = None
691 exc_msg = None
692
692
693 # Extract options from the source.
693 # Extract options from the source.
694 options = self._find_options(source, name, lineno)
694 options = self._find_options(source, name, lineno)
695
695
696 return source, options, want, exc_msg
696 return source, options, want, exc_msg
697
697
698 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
698 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
699 """
699 """
700 Given the lines of a source string (including prompts and
700 Given the lines of a source string (including prompts and
701 leading indentation), check to make sure that every prompt is
701 leading indentation), check to make sure that every prompt is
702 followed by a space character. If any line is not followed by
702 followed by a space character. If any line is not followed by
703 a space character, then raise ValueError.
703 a space character, then raise ValueError.
704
704
705 Note: IPython-modified version which takes the input prompt length as a
705 Note: IPython-modified version which takes the input prompt length as a
706 parameter, so that prompts of variable length can be dealt with.
706 parameter, so that prompts of variable length can be dealt with.
707 """
707 """
708 space_idx = indent+ps1_len
708 space_idx = indent+ps1_len
709 min_len = space_idx+1
709 min_len = space_idx+1
710 for i, line in enumerate(lines):
710 for i, line in enumerate(lines):
711 if len(line) >= min_len and line[space_idx] != ' ':
711 if len(line) >= min_len and line[space_idx] != ' ':
712 raise ValueError('line %r of the docstring for %s '
712 raise ValueError('line %r of the docstring for %s '
713 'lacks blank after %s: %r' %
713 'lacks blank after %s: %r' %
714 (lineno+i+1, name,
714 (lineno+i+1, name,
715 line[indent:space_idx], line))
715 line[indent:space_idx], line))
716
716
717
717
718 SKIP = doctest.register_optionflag('SKIP')
718 SKIP = doctest.register_optionflag('SKIP')
719
719
720
720
721 class IPDocTestRunner(doctest.DocTestRunner,object):
721 class IPDocTestRunner(doctest.DocTestRunner,object):
722 """Test runner that synchronizes the IPython namespace with test globals.
722 """Test runner that synchronizes the IPython namespace with test globals.
723 """
723 """
724
724
725 def run(self, test, compileflags=None, out=None, clear_globs=True):
725 def run(self, test, compileflags=None, out=None, clear_globs=True):
726
726
727 # Hack: ipython needs access to the execution context of the example,
727 # Hack: ipython needs access to the execution context of the example,
728 # so that it can propagate user variables loaded by %run into
728 # so that it can propagate user variables loaded by %run into
729 # test.globs. We put them here into our modified %run as a function
729 # test.globs. We put them here into our modified %run as a function
730 # attribute. Our new %run will then only make the namespace update
730 # attribute. Our new %run will then only make the namespace update
731 # when called (rather than unconconditionally updating test.globs here
731 # when called (rather than unconconditionally updating test.globs here
732 # for all examples, most of which won't be calling %run anyway).
732 # for all examples, most of which won't be calling %run anyway).
733 _run_ns_sync.test_globs = test.globs
733 _run_ns_sync.test_globs = test.globs
734 _run_ns_sync.test_filename = test.filename
734 _run_ns_sync.test_filename = test.filename
735
735
736 return super(IPDocTestRunner,self).run(test,
736 return super(IPDocTestRunner,self).run(test,
737 compileflags,out,clear_globs)
737 compileflags,out,clear_globs)
738
738
739
739
740 class DocFileCase(doctest.DocFileCase):
740 class DocFileCase(doctest.DocFileCase):
741 """Overrides to provide filename
741 """Overrides to provide filename
742 """
742 """
743 def address(self):
743 def address(self):
744 return (self._dt_test.filename, None, None)
744 return (self._dt_test.filename, None, None)
745
745
746
746
747 class ExtensionDoctest(doctests.Doctest):
747 class ExtensionDoctest(doctests.Doctest):
748 """Nose Plugin that supports doctests in extension modules.
748 """Nose Plugin that supports doctests in extension modules.
749 """
749 """
750 name = 'extdoctest' # call nosetests with --with-extdoctest
750 name = 'extdoctest' # call nosetests with --with-extdoctest
751 enabled = True
751 enabled = True
752
752
753 def __init__(self,exclude_patterns=None):
753 def __init__(self,exclude_patterns=None):
754 """Create a new ExtensionDoctest plugin.
754 """Create a new ExtensionDoctest plugin.
755
755
756 Parameters
756 Parameters
757 ----------
757 ----------
758
758
759 exclude_patterns : sequence of strings, optional
759 exclude_patterns : sequence of strings, optional
760 These patterns are compiled as regular expressions, subsequently used
760 These patterns are compiled as regular expressions, subsequently used
761 to exclude any filename which matches them from inclusion in the test
761 to exclude any filename which matches them from inclusion in the test
762 suite (using pattern.search(), NOT pattern.match() ).
762 suite (using pattern.search(), NOT pattern.match() ).
763 """
763 """
764
764
765 if exclude_patterns is None:
765 if exclude_patterns is None:
766 exclude_patterns = []
766 exclude_patterns = []
767 self.exclude_patterns = map(re.compile,exclude_patterns)
767 self.exclude_patterns = map(re.compile,exclude_patterns)
768 doctests.Doctest.__init__(self)
768 doctests.Doctest.__init__(self)
769
769
770 def options(self, parser, env=os.environ):
770 def options(self, parser, env=os.environ):
771 Plugin.options(self, parser, env)
771 Plugin.options(self, parser, env)
772 parser.add_option('--doctest-tests', action='store_true',
772 parser.add_option('--doctest-tests', action='store_true',
773 dest='doctest_tests',
773 dest='doctest_tests',
774 default=env.get('NOSE_DOCTEST_TESTS',True),
774 default=env.get('NOSE_DOCTEST_TESTS',True),
775 help="Also look for doctests in test modules. "
775 help="Also look for doctests in test modules. "
776 "Note that classes, methods and functions should "
776 "Note that classes, methods and functions should "
777 "have either doctests or non-doctest tests, "
777 "have either doctests or non-doctest tests, "
778 "not both. [NOSE_DOCTEST_TESTS]")
778 "not both. [NOSE_DOCTEST_TESTS]")
779 parser.add_option('--doctest-extension', action="append",
779 parser.add_option('--doctest-extension', action="append",
780 dest="doctestExtension",
780 dest="doctestExtension",
781 help="Also look for doctests in files with "
781 help="Also look for doctests in files with "
782 "this extension [NOSE_DOCTEST_EXTENSION]")
782 "this extension [NOSE_DOCTEST_EXTENSION]")
783 # Set the default as a list, if given in env; otherwise
783 # Set the default as a list, if given in env; otherwise
784 # an additional value set on the command line will cause
784 # an additional value set on the command line will cause
785 # an error.
785 # an error.
786 env_setting = env.get('NOSE_DOCTEST_EXTENSION')
786 env_setting = env.get('NOSE_DOCTEST_EXTENSION')
787 if env_setting is not None:
787 if env_setting is not None:
788 parser.set_defaults(doctestExtension=tolist(env_setting))
788 parser.set_defaults(doctestExtension=tolist(env_setting))
789
789
790
790
791 def configure(self, options, config):
791 def configure(self, options, config):
792 Plugin.configure(self, options, config)
792 Plugin.configure(self, options, config)
793 self.doctest_tests = options.doctest_tests
793 self.doctest_tests = options.doctest_tests
794 self.extension = tolist(options.doctestExtension)
794 self.extension = tolist(options.doctestExtension)
795
795
796 self.parser = doctest.DocTestParser()
796 self.parser = doctest.DocTestParser()
797 self.finder = DocTestFinder()
797 self.finder = DocTestFinder()
798 self.checker = IPDoctestOutputChecker()
798 self.checker = IPDoctestOutputChecker()
799 self.globs = None
799 self.globs = None
800 self.extraglobs = None
800 self.extraglobs = None
801
801
802
802
803 def loadTestsFromExtensionModule(self,filename):
803 def loadTestsFromExtensionModule(self,filename):
804 bpath,mod = os.path.split(filename)
804 bpath,mod = os.path.split(filename)
805 modname = os.path.splitext(mod)[0]
805 modname = os.path.splitext(mod)[0]
806 try:
806 try:
807 sys.path.append(bpath)
807 sys.path.append(bpath)
808 module = __import__(modname)
808 module = __import__(modname)
809 tests = list(self.loadTestsFromModule(module))
809 tests = list(self.loadTestsFromModule(module))
810 finally:
810 finally:
811 sys.path.pop()
811 sys.path.pop()
812 return tests
812 return tests
813
813
814 # NOTE: the method below is almost a copy of the original one in nose, with
814 # NOTE: the method below is almost a copy of the original one in nose, with
815 # a few modifications to control output checking.
815 # a few modifications to control output checking.
816
816
817 def loadTestsFromModule(self, module):
817 def loadTestsFromModule(self, module):
818 #print '*** ipdoctest - lTM',module # dbg
818 #print '*** ipdoctest - lTM',module # dbg
819
819
820 if not self.matches(module.__name__):
820 if not self.matches(module.__name__):
821 log.debug("Doctest doesn't want module %s", module)
821 log.debug("Doctest doesn't want module %s", module)
822 return
822 return
823
823
824 tests = self.finder.find(module,globs=self.globs,
824 tests = self.finder.find(module,globs=self.globs,
825 extraglobs=self.extraglobs)
825 extraglobs=self.extraglobs)
826 if not tests:
826 if not tests:
827 return
827 return
828
828
829 # always use whitespace and ellipsis options
829 # always use whitespace and ellipsis options
830 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
830 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
831
831
832 tests.sort()
832 tests.sort()
833 module_file = module.__file__
833 module_file = module.__file__
834 if module_file[-4:] in ('.pyc', '.pyo'):
834 if module_file[-4:] in ('.pyc', '.pyo'):
835 module_file = module_file[:-1]
835 module_file = module_file[:-1]
836 for test in tests:
836 for test in tests:
837 if not test.examples:
837 if not test.examples:
838 continue
838 continue
839 if not test.filename:
839 if not test.filename:
840 test.filename = module_file
840 test.filename = module_file
841
841
842 yield DocTestCase(test,
842 yield DocTestCase(test,
843 optionflags=optionflags,
843 optionflags=optionflags,
844 checker=self.checker)
844 checker=self.checker)
845
845
846
846
847 def loadTestsFromFile(self, filename):
847 def loadTestsFromFile(self, filename):
848 if is_extension_module(filename):
848 if is_extension_module(filename):
849 for t in self.loadTestsFromExtensionModule(filename):
849 for t in self.loadTestsFromExtensionModule(filename):
850 yield t
850 yield t
851 else:
851 else:
852 if self.extension and anyp(filename.endswith, self.extension):
852 if self.extension and anyp(filename.endswith, self.extension):
853 name = os.path.basename(filename)
853 name = os.path.basename(filename)
854 dh = open(filename)
854 dh = open(filename)
855 try:
855 try:
856 doc = dh.read()
856 doc = dh.read()
857 finally:
857 finally:
858 dh.close()
858 dh.close()
859 test = self.parser.get_doctest(
859 test = self.parser.get_doctest(
860 doc, globs={'__file__': filename}, name=name,
860 doc, globs={'__file__': filename}, name=name,
861 filename=filename, lineno=0)
861 filename=filename, lineno=0)
862 if test.examples:
862 if test.examples:
863 #print 'FileCase:',test.examples # dbg
863 #print 'FileCase:',test.examples # dbg
864 yield DocFileCase(test)
864 yield DocFileCase(test)
865 else:
865 else:
866 yield False # no tests to load
866 yield False # no tests to load
867
867
868 def wantFile(self,filename):
868 def wantFile(self,filename):
869 """Return whether the given filename should be scanned for tests.
869 """Return whether the given filename should be scanned for tests.
870
870
871 Modified version that accepts extension modules as valid containers for
871 Modified version that accepts extension modules as valid containers for
872 doctests.
872 doctests.
873 """
873 """
874 # print '*** ipdoctest- wantFile:',filename # dbg
874 # print '*** ipdoctest- wantFile:',filename # dbg
875
875
876 for pat in self.exclude_patterns:
876 for pat in self.exclude_patterns:
877 if pat.search(filename):
877 if pat.search(filename):
878 # print '###>>> SKIP:',filename # dbg
878 # print '###>>> SKIP:',filename # dbg
879 return False
879 return False
880
880
881 if is_extension_module(filename):
881 if is_extension_module(filename):
882 return True
882 return True
883 else:
883 else:
884 return doctests.Doctest.wantFile(self,filename)
884 return doctests.Doctest.wantFile(self,filename)
885
885
886
886
887 class IPythonDoctest(ExtensionDoctest):
887 class IPythonDoctest(ExtensionDoctest):
888 """Nose Plugin that supports doctests in extension modules.
888 """Nose Plugin that supports doctests in extension modules.
889 """
889 """
890 name = 'ipdoctest' # call nosetests with --with-ipdoctest
890 name = 'ipdoctest' # call nosetests with --with-ipdoctest
891 enabled = True
891 enabled = True
892
892
893 def makeTest(self, obj, parent):
893 def makeTest(self, obj, parent):
894 """Look for doctests in the given object, which will be a
894 """Look for doctests in the given object, which will be a
895 function, method or class.
895 function, method or class.
896 """
896 """
897 # always use whitespace and ellipsis options
897 # always use whitespace and ellipsis options
898 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
898 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
899
899
900 doctests = self.finder.find(obj, module=getmodule(parent))
900 doctests = self.finder.find(obj, module=getmodule(parent))
901 if doctests:
901 if doctests:
902 for test in doctests:
902 for test in doctests:
903 if len(test.examples) == 0:
903 if len(test.examples) == 0:
904 continue
904 continue
905
905
906 yield DocTestCase(test, obj=obj,
906 yield DocTestCase(test, obj=obj,
907 optionflags=optionflags,
907 optionflags=optionflags,
908 checker=self.checker)
908 checker=self.checker)
909
909
910 def options(self, parser, env=os.environ):
910 def options(self, parser, env=os.environ):
911 Plugin.options(self, parser, env)
911 Plugin.options(self, parser, env)
912 parser.add_option('--ipdoctest-tests', action='store_true',
912 parser.add_option('--ipdoctest-tests', action='store_true',
913 dest='ipdoctest_tests',
913 dest='ipdoctest_tests',
914 default=env.get('NOSE_IPDOCTEST_TESTS',True),
914 default=env.get('NOSE_IPDOCTEST_TESTS',True),
915 help="Also look for doctests in test modules. "
915 help="Also look for doctests in test modules. "
916 "Note that classes, methods and functions should "
916 "Note that classes, methods and functions should "
917 "have either doctests or non-doctest tests, "
917 "have either doctests or non-doctest tests, "
918 "not both. [NOSE_IPDOCTEST_TESTS]")
918 "not both. [NOSE_IPDOCTEST_TESTS]")
919 parser.add_option('--ipdoctest-extension', action="append",
919 parser.add_option('--ipdoctest-extension', action="append",
920 dest="ipdoctest_extension",
920 dest="ipdoctest_extension",
921 help="Also look for doctests in files with "
921 help="Also look for doctests in files with "
922 "this extension [NOSE_IPDOCTEST_EXTENSION]")
922 "this extension [NOSE_IPDOCTEST_EXTENSION]")
923 # Set the default as a list, if given in env; otherwise
923 # Set the default as a list, if given in env; otherwise
924 # an additional value set on the command line will cause
924 # an additional value set on the command line will cause
925 # an error.
925 # an error.
926 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
926 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
927 if env_setting is not None:
927 if env_setting is not None:
928 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
928 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
929
929
930 def configure(self, options, config):
930 def configure(self, options, config):
931 Plugin.configure(self, options, config)
931 Plugin.configure(self, options, config)
932 self.doctest_tests = options.ipdoctest_tests
932 self.doctest_tests = options.ipdoctest_tests
933 self.extension = tolist(options.ipdoctest_extension)
933 self.extension = tolist(options.ipdoctest_extension)
934
934
935 self.parser = IPDocTestParser()
935 self.parser = IPDocTestParser()
936 self.finder = DocTestFinder(parser=self.parser)
936 self.finder = DocTestFinder(parser=self.parser)
937 self.checker = IPDoctestOutputChecker()
937 self.checker = IPDoctestOutputChecker()
938 self.globs = None
938 self.globs = None
939 self.extraglobs = None
939 self.extraglobs = None
@@ -1,311 +1,304 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
2
3 """Tests for genutils.py"""
3 """Tests for genutils.py"""
4
4
5 __docformat__ = "restructuredtext en"
5 __docformat__ = "restructuredtext en"
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
8 # Copyright (C) 2008 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # stdlib
18 # stdlib
19 import os
19 import os
20 import shutil
20 import shutil
21 import sys
21 import sys
22 import tempfile
22 import tempfile
23
23
24 from os.path import join, abspath, split
24 from os.path import join, abspath, split
25
25
26 # third-party
26 # third-party
27 import nose.tools as nt
27 import nose.tools as nt
28
28
29 from nose import with_setup
29 from nose import with_setup
30 from nose.tools import raises
30 from nose.tools import raises
31
31
32 # Our own
32 # Our own
33 import IPython
33 import IPython
34 from IPython.utils import genutils
34 from IPython.utils import genutils
35 from IPython.testing.decorators import skipif, skip_if_not_win32
35 from IPython.testing.decorators import skipif, skip_if_not_win32
36
36
37 # Platform-dependent imports
37 # Platform-dependent imports
38 try:
38 try:
39 import _winreg as wreg
39 import _winreg as wreg
40 except ImportError:
40 except ImportError:
41 #Fake _winreg module on none windows platforms
41 #Fake _winreg module on none windows platforms
42 import new
42 import new
43 sys.modules["_winreg"] = new.module("_winreg")
43 sys.modules["_winreg"] = new.module("_winreg")
44 import _winreg as wreg
44 import _winreg as wreg
45 #Add entries that needs to be stubbed by the testing code
45 #Add entries that needs to be stubbed by the testing code
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47
47
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 # Globals
49 # Globals
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51 env = os.environ
51 env = os.environ
52 TEST_FILE_PATH = split(abspath(__file__))[0]
52 TEST_FILE_PATH = split(abspath(__file__))[0]
53 TMP_TEST_DIR = tempfile.mkdtemp()
53 TMP_TEST_DIR = tempfile.mkdtemp()
54 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
54 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
55 IP_TEST_DIR = join(HOME_TEST_DIR,'_ipython')
55 IP_TEST_DIR = join(HOME_TEST_DIR,'_ipython')
56 #
56 #
57 # Setup/teardown functions/decorators
57 # Setup/teardown functions/decorators
58 #
58 #
59
59
60 def setup():
60 def setup():
61 """Setup testenvironment for the module:
61 """Setup testenvironment for the module:
62
62
63 - Adds dummy home dir tree
63 - Adds dummy home dir tree
64 """
64 """
65 # Do not mask exceptions here. In particular, catching WindowsError is a
65 # Do not mask exceptions here. In particular, catching WindowsError is a
66 # problem because that exception is only defined on Windows...
66 # problem because that exception is only defined on Windows...
67 os.makedirs(IP_TEST_DIR)
67 os.makedirs(IP_TEST_DIR)
68
68
69 def teardown():
69 def teardown():
70 """Teardown testenvironment for the module:
70 """Teardown testenvironment for the module:
71
71
72 - Remove dummy home dir tree
72 - Remove dummy home dir tree
73 """
73 """
74 # Note: we remove the parent test dir, which is the root of all test
74 # Note: we remove the parent test dir, which is the root of all test
75 # subdirs we may have created. Use shutil instead of os.removedirs, so
75 # subdirs we may have created. Use shutil instead of os.removedirs, so
76 # that non-empty directories are all recursively removed.
76 # that non-empty directories are all recursively removed.
77 shutil.rmtree(TMP_TEST_DIR)
77 shutil.rmtree(TMP_TEST_DIR)
78
78
79
79
80 def setup_environment():
80 def setup_environment():
81 """Setup testenvironment for some functions that are tested
81 """Setup testenvironment for some functions that are tested
82 in this module. In particular this functions stores attributes
82 in this module. In particular this functions stores attributes
83 and other things that we need to stub in some test functions.
83 and other things that we need to stub in some test functions.
84 This needs to be done on a function level and not module level because
84 This needs to be done on a function level and not module level because
85 each testfunction needs a pristine environment.
85 each testfunction needs a pristine environment.
86 """
86 """
87 global oldstuff, platformstuff
87 global oldstuff, platformstuff
88 oldstuff = (env.copy(), os.name, genutils.get_home_dir, IPython.__file__,)
88 oldstuff = (env.copy(), os.name, genutils.get_home_dir, IPython.__file__,)
89
89
90 if os.name == 'nt':
90 if os.name == 'nt':
91 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
91 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
92
92
93 if 'IPYTHONDIR' in env:
93 if 'IPYTHONDIR' in env:
94 del env['IPYTHONDIR']
94 del env['IPYTHONDIR']
95
95
96 def teardown_environment():
96 def teardown_environment():
97 """Restore things that were remebered by the setup_environment function
97 """Restore things that were remebered by the setup_environment function
98 """
98 """
99 (oldenv, os.name, genutils.get_home_dir, IPython.__file__,) = oldstuff
99 (oldenv, os.name, genutils.get_home_dir, IPython.__file__,) = oldstuff
100 for key in env.keys():
100 for key in env.keys():
101 if key not in oldenv:
101 if key not in oldenv:
102 del env[key]
102 del env[key]
103 env.update(oldenv)
103 env.update(oldenv)
104 if hasattr(sys, 'frozen'):
104 if hasattr(sys, 'frozen'):
105 del sys.frozen
105 del sys.frozen
106 if os.name == 'nt':
106 if os.name == 'nt':
107 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
107 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
108
108
109 # Build decorator that uses the setup_environment/setup_environment
109 # Build decorator that uses the setup_environment/setup_environment
110 with_enivronment = with_setup(setup_environment, teardown_environment)
110 with_enivronment = with_setup(setup_environment, teardown_environment)
111
111
112
112
113 #
113 #
114 # Tests for get_home_dir
114 # Tests for get_home_dir
115 #
115 #
116
116
117 @skip_if_not_win32
117 @skip_if_not_win32
118 @with_enivronment
118 @with_enivronment
119 def test_get_home_dir_1():
119 def test_get_home_dir_1():
120 """Testcase for py2exe logic, un-compressed lib
120 """Testcase for py2exe logic, un-compressed lib
121 """
121 """
122 sys.frozen = True
122 sys.frozen = True
123
123
124 #fake filename for IPython.__init__
124 #fake filename for IPython.__init__
125 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
125 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
126
126
127 home_dir = genutils.get_home_dir()
127 home_dir = genutils.get_home_dir()
128 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
128 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
129
129
130 @skip_if_not_win32
130 @skip_if_not_win32
131 @with_enivronment
131 @with_enivronment
132 def test_get_home_dir_2():
132 def test_get_home_dir_2():
133 """Testcase for py2exe logic, compressed lib
133 """Testcase for py2exe logic, compressed lib
134 """
134 """
135 sys.frozen = True
135 sys.frozen = True
136 #fake filename for IPython.__init__
136 #fake filename for IPython.__init__
137 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
137 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
138
138
139 home_dir = genutils.get_home_dir()
139 home_dir = genutils.get_home_dir()
140 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
140 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
141
141
142 @with_enivronment
142 @with_enivronment
143 def test_get_home_dir_3():
143 def test_get_home_dir_3():
144 """Testcase $HOME is set, then use its value as home directory."""
144 """Testcase $HOME is set, then use its value as home directory."""
145 env["HOME"] = HOME_TEST_DIR
145 env["HOME"] = HOME_TEST_DIR
146 home_dir = genutils.get_home_dir()
146 home_dir = genutils.get_home_dir()
147 nt.assert_equal(home_dir, env["HOME"])
147 nt.assert_equal(home_dir, env["HOME"])
148
148
149 @with_enivronment
149 @with_enivronment
150 def test_get_home_dir_4():
150 def test_get_home_dir_4():
151 """Testcase $HOME is not set, os=='poix'.
151 """Testcase $HOME is not set, os=='poix'.
152 This should fail with HomeDirError"""
152 This should fail with HomeDirError"""
153
153
154 os.name = 'posix'
154 os.name = 'posix'
155 if 'HOME' in env: del env['HOME']
155 if 'HOME' in env: del env['HOME']
156 nt.assert_raises(genutils.HomeDirError, genutils.get_home_dir)
156 nt.assert_raises(genutils.HomeDirError, genutils.get_home_dir)
157
157
158 @skip_if_not_win32
158 @skip_if_not_win32
159 @with_enivronment
159 @with_enivronment
160 def test_get_home_dir_5():
160 def test_get_home_dir_5():
161 """Testcase $HOME is not set, os=='nt'
161 """Testcase $HOME is not set, os=='nt'
162 env['HOMEDRIVE'],env['HOMEPATH'] points to path."""
162 env['HOMEDRIVE'],env['HOMEPATH'] points to path."""
163
163
164 os.name = 'nt'
164 os.name = 'nt'
165 if 'HOME' in env: del env['HOME']
165 if 'HOME' in env: del env['HOME']
166 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
166 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
167
167
168 home_dir = genutils.get_home_dir()
168 home_dir = genutils.get_home_dir()
169 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
169 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
170
170
171 @skip_if_not_win32
171 @skip_if_not_win32
172 @with_enivronment
172 @with_enivronment
173 def test_get_home_dir_6():
173 def test_get_home_dir_6():
174 """Testcase $HOME is not set, os=='nt'
174 """Testcase $HOME is not set, os=='nt'
175 env['HOMEDRIVE'],env['HOMEPATH'] do not point to path.
175 env['HOMEDRIVE'],env['HOMEPATH'] do not point to path.
176 env['USERPROFILE'] points to path
176 env['USERPROFILE'] points to path
177 """
177 """
178
178
179 os.name = 'nt'
179 os.name = 'nt'
180 if 'HOME' in env: del env['HOME']
180 if 'HOME' in env: del env['HOME']
181 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.abspath(TEST_FILE_PATH), "DOES NOT EXIST"
181 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.abspath(TEST_FILE_PATH), "DOES NOT EXIST"
182 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
182 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
183
183
184 home_dir = genutils.get_home_dir()
184 home_dir = genutils.get_home_dir()
185 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
185 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
186
186
187 # Should we stub wreg fully so we can run the test on all platforms?
187 # Should we stub wreg fully so we can run the test on all platforms?
188 @skip_if_not_win32
188 @skip_if_not_win32
189 @with_enivronment
189 @with_enivronment
190 def test_get_home_dir_7():
190 def test_get_home_dir_7():
191 """Testcase $HOME is not set, os=='nt'
191 """Testcase $HOME is not set, os=='nt'
192 env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing
192 env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing
193 """
193 """
194 os.name = 'nt'
194 os.name = 'nt'
195 if 'HOME' in env: del env['HOME']
195 if 'HOME' in env: del env['HOME']
196 if 'HOMEDRIVE' in env: del env['HOMEDRIVE']
196 if 'HOMEDRIVE' in env: del env['HOMEDRIVE']
197
197
198 #Stub windows registry functions
198 #Stub windows registry functions
199 def OpenKey(x, y):
199 def OpenKey(x, y):
200 class key:
200 class key:
201 def Close(self):
201 def Close(self):
202 pass
202 pass
203 return key()
203 return key()
204 def QueryValueEx(x, y):
204 def QueryValueEx(x, y):
205 return [abspath(HOME_TEST_DIR)]
205 return [abspath(HOME_TEST_DIR)]
206
206
207 wreg.OpenKey = OpenKey
207 wreg.OpenKey = OpenKey
208 wreg.QueryValueEx = QueryValueEx
208 wreg.QueryValueEx = QueryValueEx
209
209
210 home_dir = genutils.get_home_dir()
210 home_dir = genutils.get_home_dir()
211 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
211 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
212
212
213 #
213 #
214 # Tests for get_ipython_dir
214 # Tests for get_ipython_dir
215 #
215 #
216
216
217 @with_enivronment
217 @with_enivronment
218 def test_get_ipython_dir_1():
218 def test_get_ipython_dir_1():
219 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
219 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
220 env['IPYTHONDIR'] = "someplace/.ipython"
220 env['IPYTHONDIR'] = "someplace/.ipython"
221 ipdir = genutils.get_ipython_dir()
221 ipdir = genutils.get_ipython_dir()
222 nt.assert_equal(ipdir, os.path.abspath("someplace/.ipython"))
222 nt.assert_equal(ipdir, "someplace/.ipython")
223
223
224
224
225 @with_enivronment
225 @with_enivronment
226 def test_get_ipython_dir_2():
226 def test_get_ipython_dir_2():
227 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
227 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
228 genutils.get_home_dir = lambda : "someplace"
228 genutils.get_home_dir = lambda : "someplace"
229 os.name = "posix"
229 os.name = "posix"
230 ipdir = genutils.get_ipython_dir()
230 ipdir = genutils.get_ipython_dir()
231 nt.assert_equal(ipdir, os.path.abspath(os.path.join("someplace", ".ipython")))
231 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
232
232
233 @with_enivronment
234 def test_get_ipython_dir_3():
235 """test_get_ipython_dir_3, Testcase to see if we can call get_ipython_dir without Exceptions."""
236 genutils.get_home_dir = lambda : "someplace"
237 os.name = "nt"
238 ipdir = genutils.get_ipython_dir()
239 nt.assert_equal(ipdir, os.path.abspath(os.path.join("someplace", "_ipython")))
240
233
241 #
234 #
242 # Tests for get_security_dir
235 # Tests for get_security_dir
243 #
236 #
244
237
245 @with_enivronment
238 @with_enivronment
246 def test_get_security_dir():
239 def test_get_security_dir():
247 """Testcase to see if we can call get_security_dir without Exceptions."""
240 """Testcase to see if we can call get_security_dir without Exceptions."""
248 sdir = genutils.get_security_dir()
241 sdir = genutils.get_security_dir()
249
242
250 #
243 #
251 # Tests for get_log_dir
244 # Tests for get_log_dir
252 #
245 #
253
246
254 @with_enivronment
247 @with_enivronment
255 def test_get_log_dir():
248 def test_get_log_dir():
256 """Testcase to see if we can call get_log_dir without Exceptions."""
249 """Testcase to see if we can call get_log_dir without Exceptions."""
257 sdir = genutils.get_log_dir()
250 sdir = genutils.get_log_dir()
258
251
259 #
252 #
260 # Tests for popkey
253 # Tests for popkey
261 #
254 #
262
255
263 def test_popkey_1():
256 def test_popkey_1():
264 """test_popkey_1, Basic usage test of popkey
257 """test_popkey_1, Basic usage test of popkey
265 """
258 """
266 dct = dict(a=1, b=2, c=3)
259 dct = dict(a=1, b=2, c=3)
267 nt.assert_equal(genutils.popkey(dct, "a"), 1)
260 nt.assert_equal(genutils.popkey(dct, "a"), 1)
268 nt.assert_equal(dct, dict(b=2, c=3))
261 nt.assert_equal(dct, dict(b=2, c=3))
269 nt.assert_equal(genutils.popkey(dct, "b"), 2)
262 nt.assert_equal(genutils.popkey(dct, "b"), 2)
270 nt.assert_equal(dct, dict(c=3))
263 nt.assert_equal(dct, dict(c=3))
271 nt.assert_equal(genutils.popkey(dct, "c"), 3)
264 nt.assert_equal(genutils.popkey(dct, "c"), 3)
272 nt.assert_equal(dct, dict())
265 nt.assert_equal(dct, dict())
273
266
274 def test_popkey_2():
267 def test_popkey_2():
275 """test_popkey_2, Test to see that popkey of non occuring keys
268 """test_popkey_2, Test to see that popkey of non occuring keys
276 generates a KeyError exception
269 generates a KeyError exception
277 """
270 """
278 dct = dict(a=1, b=2, c=3)
271 dct = dict(a=1, b=2, c=3)
279 nt.assert_raises(KeyError, genutils.popkey, dct, "d")
272 nt.assert_raises(KeyError, genutils.popkey, dct, "d")
280
273
281 def test_popkey_3():
274 def test_popkey_3():
282 """test_popkey_3, Tests to see that popkey calls returns the correct value
275 """test_popkey_3, Tests to see that popkey calls returns the correct value
283 and that the key/value was removed from the dict.
276 and that the key/value was removed from the dict.
284 """
277 """
285 dct = dict(a=1, b=2, c=3)
278 dct = dict(a=1, b=2, c=3)
286 nt.assert_equal(genutils.popkey(dct, "A", 13), 13)
279 nt.assert_equal(genutils.popkey(dct, "A", 13), 13)
287 nt.assert_equal(dct, dict(a=1, b=2, c=3))
280 nt.assert_equal(dct, dict(a=1, b=2, c=3))
288 nt.assert_equal(genutils.popkey(dct, "B", 14), 14)
281 nt.assert_equal(genutils.popkey(dct, "B", 14), 14)
289 nt.assert_equal(dct, dict(a=1, b=2, c=3))
282 nt.assert_equal(dct, dict(a=1, b=2, c=3))
290 nt.assert_equal(genutils.popkey(dct, "C", 15), 15)
283 nt.assert_equal(genutils.popkey(dct, "C", 15), 15)
291 nt.assert_equal(dct, dict(a=1, b=2, c=3))
284 nt.assert_equal(dct, dict(a=1, b=2, c=3))
292 nt.assert_equal(genutils.popkey(dct, "a"), 1)
285 nt.assert_equal(genutils.popkey(dct, "a"), 1)
293 nt.assert_equal(dct, dict(b=2, c=3))
286 nt.assert_equal(dct, dict(b=2, c=3))
294 nt.assert_equal(genutils.popkey(dct, "b"), 2)
287 nt.assert_equal(genutils.popkey(dct, "b"), 2)
295 nt.assert_equal(dct, dict(c=3))
288 nt.assert_equal(dct, dict(c=3))
296 nt.assert_equal(genutils.popkey(dct, "c"), 3)
289 nt.assert_equal(genutils.popkey(dct, "c"), 3)
297 nt.assert_equal(dct, dict())
290 nt.assert_equal(dct, dict())
298
291
299
292
300 def test_filefind():
293 def test_filefind():
301 """Various tests for filefind"""
294 """Various tests for filefind"""
302 f = tempfile.NamedTemporaryFile()
295 f = tempfile.NamedTemporaryFile()
303 print 'fname:',f.name
296 print 'fname:',f.name
304 alt_dirs = genutils.get_ipython_dir()
297 alt_dirs = genutils.get_ipython_dir()
305 t = genutils.filefind(f.name,alt_dirs)
298 t = genutils.filefind(f.name,alt_dirs)
306 print 'found:',t
299 print 'found:',t
307
300
308
301
309 def test_get_ipython_package_dir():
302 def test_get_ipython_package_dir():
310 ipdir = genutils.get_ipython_package_dir()
303 ipdir = genutils.get_ipython_package_dir()
311 nt.assert_true(os.path.isdir(ipdir))
304 nt.assert_true(os.path.isdir(ipdir))
General Comments 0
You need to be logged in to leave comments. Login now