##// END OF EJS Templates
Improvements to namespace handling with %run....
Fernando Perez -
Show More
@@ -1,867 +1,941 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 - IPython functions that produce output as a side-effect of calling a system
17 - IPython functions that produce output as a side-effect of calling a system
18 process (e.g. 'ls') can be doc-tested, but they must be handled in an
18 process (e.g. 'ls') can be doc-tested, but they must be handled in an
19 external IPython process. Such doctests must be tagged with:
19 external IPython process. Such doctests must be tagged with:
20
20
21 # ipdoctest: EXTERNAL
21 # ipdoctest: EXTERNAL
22
22
23 so that the testing machinery handles them differently. Since these are run
23 so that the testing machinery handles them differently. Since these are run
24 via pexpect in an external process, they can't deal with exceptions or other
24 via pexpect in an external process, they can't deal with exceptions or other
25 fancy featurs of regular doctests. You must limit such tests to simple
25 fancy featurs of regular doctests. You must limit such tests to simple
26 matching of the output. For this reason, I recommend you limit these kinds
26 matching of the output. For this reason, I recommend you limit these kinds
27 of doctests to features that truly require a separate process, and use the
27 of doctests to features that truly require a separate process, and use the
28 normal IPython ones (which have all the features of normal doctests) for
28 normal IPython ones (which have all the features of normal doctests) for
29 everything else. See the examples at the bottom of this file for a
29 everything else. See the examples at the bottom of this file for a
30 comparison of what can be done with both types.
30 comparison of what can be done with both types.
31 """
31 """
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Module imports
35 # Module imports
36
36
37 # From the standard library
37 # From the standard library
38 import __builtin__
38 import __builtin__
39 import commands
39 import commands
40 import doctest
40 import doctest
41 import inspect
41 import inspect
42 import logging
42 import logging
43 import os
43 import os
44 import re
44 import re
45 import sys
45 import sys
46 import traceback
46 import unittest
47 import unittest
47
48
48 from inspect import getmodule
49 from inspect import getmodule
50 from StringIO import StringIO
51
52 # We are overriding the default doctest runner, so we need to import a few
53 # things from doctest directly
54 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
55 _unittest_reportflags, DocTestRunner,
56 _extract_future_flags, pdb, _OutputRedirectingPdb,
57 _exception_traceback,
58 linecache)
49
59
50 # Third-party modules
60 # Third-party modules
51 import nose.core
61 import nose.core
52
62
53 from nose.plugins import doctests, Plugin
63 from nose.plugins import doctests, Plugin
54 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
64 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
55
65
56 # Our own imports
66 # Our own imports
57 #from extdoctest import ExtensionDoctest, DocTestFinder
67 #from extdoctest import ExtensionDoctest, DocTestFinder
58 #from dttools import DocTestFinder, DocTestCase
68 #from dttools import DocTestFinder, DocTestCase
59 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
60 # Module globals and other constants
70 # Module globals and other constants
61
71
62 log = logging.getLogger(__name__)
72 log = logging.getLogger(__name__)
63
73
64 ###########################################################################
74 ###########################################################################
65 # *** HACK ***
75 # *** HACK ***
66 # We must start our own ipython object and heavily muck with it so that all the
76 # We must start our own ipython object and heavily muck with it so that all the
67 # modifications IPython makes to system behavior don't send the doctest
77 # modifications IPython makes to system behavior don't send the doctest
68 # machinery into a fit. This code should be considered a gross hack, but it
78 # machinery into a fit. This code should be considered a gross hack, but it
69 # gets the job done.
79 # gets the job done.
70
80
71 class ncdict(dict):
81 class ncdict(dict):
72 """Non-copying dict class.
82 """Non-copying dict class.
73
83
74 This is a special-purpose dict subclass that overrides the .copy() method
84 This is a special-purpose dict subclass that overrides the .copy() method
75 to return the original object itself. We need it to ensure that doctests
85 to return the original object itself. We need it to ensure that doctests
76 happen in the IPython namespace, but doctest always makes a shallow copy of
86 happen in the IPython namespace, but doctest always makes a shallow copy of
77 the given globals for execution. Since we actually *want* this namespace
87 the given globals for execution. Since we actually *want* this namespace
78 to be persistent (this is how the user's session maintains state), we
88 to be persistent (this is how the user's session maintains state), we
79 simply fool doctest by returning the original object upoon copy.
89 simply fool doctest by returning the original object upoon copy.
80 """
90 """
81
91
82 def copy(self):
92 def copy(self):
83 return self
93 return self
84
94
85
95
96 # XXX - Hack to modify the %run command so we can sync the user's namespace
97 # with the test globals. Once we move over to a clean magic system, this will
98 # be done with much less ugliness.
99
86 def _my_run(self,arg_s,runner=None):
100 def _my_run(self,arg_s,runner=None):
87 """
101 """
88 """
102 """
89 #print 'HA!' # dbg
103 #print 'HA!' # dbg
90
104
91 return _ip.IP.magic_run_ori(arg_s,runner)
105 return _ip.IP.magic_run_ori(arg_s,runner)
92
106
93
107
94 def start_ipython():
108 def start_ipython():
95 """Start a global IPython shell, which we need for IPython-specific syntax.
109 """Start a global IPython shell, which we need for IPython-specific syntax.
96 """
110 """
97 import IPython
111 import IPython
98
112
99 def xsys(cmd):
113 def xsys(cmd):
100 """Execute a command and print its output.
114 """Execute a command and print its output.
101
115
102 This is just a convenience function to replace the IPython system call
116 This is just a convenience function to replace the IPython system call
103 with one that is more doctest-friendly.
117 with one that is more doctest-friendly.
104 """
118 """
105 cmd = _ip.IP.var_expand(cmd,depth=1)
119 cmd = _ip.IP.var_expand(cmd,depth=1)
106 sys.stdout.write(commands.getoutput(cmd))
120 sys.stdout.write(commands.getoutput(cmd))
107 sys.stdout.flush()
121 sys.stdout.flush()
108
122
109 # Store certain global objects that IPython modifies
123 # Store certain global objects that IPython modifies
110 _displayhook = sys.displayhook
124 _displayhook = sys.displayhook
111 _excepthook = sys.excepthook
125 _excepthook = sys.excepthook
112 _main = sys.modules.get('__main__')
126 _main = sys.modules.get('__main__')
113
127
114 # Start IPython instance. We customize it to start with minimal frills and
128 # Start IPython instance. We customize it to start with minimal frills and
115 # with our own namespace.
129 # with our own namespace.
116 argv = ['--classic','--noterm_title']
130 argv = ['--classic','--noterm_title']
117 user_ns = ncdict()
131 user_ns = ncdict()
118 IPython.Shell.IPShell(argv,user_ns)
132 IPython.Shell.IPShell(argv,user_ns)
119
133
120 # Deactivate the various python system hooks added by ipython for
134 # Deactivate the various python system hooks added by ipython for
121 # interactive convenience so we don't confuse the doctest system
135 # interactive convenience so we don't confuse the doctest system
122 sys.modules['__main__'] = _main
136 sys.modules['__main__'] = _main
123 sys.displayhook = _displayhook
137 sys.displayhook = _displayhook
124 sys.excepthook = _excepthook
138 sys.excepthook = _excepthook
125
139
126 # So that ipython magics and aliases can be doctested (they work by making
140 # So that ipython magics and aliases can be doctested (they work by making
127 # a call into a global _ip object)
141 # a call into a global _ip object)
128 _ip = IPython.ipapi.get()
142 _ip = IPython.ipapi.get()
129 __builtin__._ip = _ip
143 __builtin__._ip = _ip
130
144
131 # Modify the IPython system call with one that uses getoutput, so that we
145 # Modify the IPython system call with one that uses getoutput, so that we
132 # can capture subcommands and print them to Python's stdout, otherwise the
146 # can capture subcommands and print them to Python's stdout, otherwise the
133 # doctest machinery would miss them.
147 # doctest machinery would miss them.
134 _ip.system = xsys
148 _ip.system = xsys
135
149
136 import new
150 import new
137 im = new.instancemethod(_my_run,_ip.IP, _ip.IP.__class__)
151 im = new.instancemethod(_my_run,_ip.IP, _ip.IP.__class__)
138 _ip.IP.magic_run_ori = _ip.IP.magic_run
152 _ip.IP.magic_run_ori = _ip.IP.magic_run
139 _ip.IP.magic_run = im
153 _ip.IP.magic_run = im
140
154
141 # The start call MUST be made here. I'm not sure yet why it doesn't work if
155 # The start call MUST be made here. I'm not sure yet why it doesn't work if
142 # it is made later, at plugin initialization time, but in all my tests, that's
156 # it is made later, at plugin initialization time, but in all my tests, that's
143 # the case.
157 # the case.
144 start_ipython()
158 start_ipython()
145
159
146 # *** END HACK ***
160 # *** END HACK ***
147 ###########################################################################
161 ###########################################################################
148
162
149 # Classes and functions
163 # Classes and functions
150
164
151 def is_extension_module(filename):
165 def is_extension_module(filename):
152 """Return whether the given filename is an extension module.
166 """Return whether the given filename is an extension module.
153
167
154 This simply checks that the extension is either .so or .pyd.
168 This simply checks that the extension is either .so or .pyd.
155 """
169 """
156 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
170 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
157
171
158
172
159 # Modified version of the one in the stdlib, that fixes a python bug (doctests
173 # Modified version of the one in the stdlib, that fixes a python bug (doctests
160 # not found in extension modules, http://bugs.python.org/issue3158)
174 # not found in extension modules, http://bugs.python.org/issue3158)
161 class DocTestFinder(doctest.DocTestFinder):
175 class DocTestFinder(doctest.DocTestFinder):
162
176
163 def _from_module(self, module, object):
177 def _from_module(self, module, object):
164 """
178 """
165 Return true if the given object is defined in the given
179 Return true if the given object is defined in the given
166 module.
180 module.
167 """
181 """
168 if module is None:
182 if module is None:
169 #print '_fm C1' # dbg
183 #print '_fm C1' # dbg
170 return True
184 return True
171 elif inspect.isfunction(object):
185 elif inspect.isfunction(object):
172 #print '_fm C2' # dbg
186 #print '_fm C2' # dbg
173 return module.__dict__ is object.func_globals
187 return module.__dict__ is object.func_globals
174 elif inspect.isbuiltin(object):
188 elif inspect.isbuiltin(object):
175 #print '_fm C2-1' # dbg
189 #print '_fm C2-1' # dbg
176 return module.__name__ == object.__module__
190 return module.__name__ == object.__module__
177 elif inspect.isclass(object):
191 elif inspect.isclass(object):
178 #print '_fm C3' # dbg
192 #print '_fm C3' # dbg
179 return module.__name__ == object.__module__
193 return module.__name__ == object.__module__
180 elif inspect.ismethod(object):
194 elif inspect.ismethod(object):
181 # This one may be a bug in cython that fails to correctly set the
195 # This one may be a bug in cython that fails to correctly set the
182 # __module__ attribute of methods, but since the same error is easy
196 # __module__ attribute of methods, but since the same error is easy
183 # to make by extension code writers, having this safety in place
197 # to make by extension code writers, having this safety in place
184 # isn't such a bad idea
198 # isn't such a bad idea
185 #print '_fm C3-1' # dbg
199 #print '_fm C3-1' # dbg
186 return module.__name__ == object.im_class.__module__
200 return module.__name__ == object.im_class.__module__
187 elif inspect.getmodule(object) is not None:
201 elif inspect.getmodule(object) is not None:
188 #print '_fm C4' # dbg
202 #print '_fm C4' # dbg
189 #print 'C4 mod',module,'obj',object # dbg
203 #print 'C4 mod',module,'obj',object # dbg
190 return module is inspect.getmodule(object)
204 return module is inspect.getmodule(object)
191 elif hasattr(object, '__module__'):
205 elif hasattr(object, '__module__'):
192 #print '_fm C5' # dbg
206 #print '_fm C5' # dbg
193 return module.__name__ == object.__module__
207 return module.__name__ == object.__module__
194 elif isinstance(object, property):
208 elif isinstance(object, property):
195 #print '_fm C6' # dbg
209 #print '_fm C6' # dbg
196 return True # [XX] no way not be sure.
210 return True # [XX] no way not be sure.
197 else:
211 else:
198 raise ValueError("object must be a class or function")
212 raise ValueError("object must be a class or function")
199
213
200 def _find(self, tests, obj, name, module, source_lines, globs, seen):
214 def _find(self, tests, obj, name, module, source_lines, globs, seen):
201 """
215 """
202 Find tests for the given object and any contained objects, and
216 Find tests for the given object and any contained objects, and
203 add them to `tests`.
217 add them to `tests`.
204 """
218 """
205
219
206 doctest.DocTestFinder._find(self,tests, obj, name, module,
220 doctest.DocTestFinder._find(self,tests, obj, name, module,
207 source_lines, globs, seen)
221 source_lines, globs, seen)
208
222
209 # Below we re-run pieces of the above method with manual modifications,
223 # Below we re-run pieces of the above method with manual modifications,
210 # because the original code is buggy and fails to correctly identify
224 # because the original code is buggy and fails to correctly identify
211 # doctests in extension modules.
225 # doctests in extension modules.
212
226
213 # Local shorthands
227 # Local shorthands
214 from inspect import isroutine, isclass, ismodule
228 from inspect import isroutine, isclass, ismodule
215
229
216 # Look for tests in a module's contained objects.
230 # Look for tests in a module's contained objects.
217 if inspect.ismodule(obj) and self._recurse:
231 if inspect.ismodule(obj) and self._recurse:
218 for valname, val in obj.__dict__.items():
232 for valname, val in obj.__dict__.items():
219 valname1 = '%s.%s' % (name, valname)
233 valname1 = '%s.%s' % (name, valname)
220 if ( (isroutine(val) or isclass(val))
234 if ( (isroutine(val) or isclass(val))
221 and self._from_module(module, val) ):
235 and self._from_module(module, val) ):
222
236
223 self._find(tests, val, valname1, module, source_lines,
237 self._find(tests, val, valname1, module, source_lines,
224 globs, seen)
238 globs, seen)
225
239
226 # Look for tests in a class's contained objects.
240 # Look for tests in a class's contained objects.
227 if inspect.isclass(obj) and self._recurse:
241 if inspect.isclass(obj) and self._recurse:
228 #print 'RECURSE into class:',obj # dbg
242 #print 'RECURSE into class:',obj # dbg
229 for valname, val in obj.__dict__.items():
243 for valname, val in obj.__dict__.items():
230 #valname1 = '%s.%s' % (name, valname) # dbg
244 #valname1 = '%s.%s' % (name, valname) # dbg
231 #print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg
245 #print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg
232 # Special handling for staticmethod/classmethod.
246 # Special handling for staticmethod/classmethod.
233 if isinstance(val, staticmethod):
247 if isinstance(val, staticmethod):
234 val = getattr(obj, valname)
248 val = getattr(obj, valname)
235 if isinstance(val, classmethod):
249 if isinstance(val, classmethod):
236 val = getattr(obj, valname).im_func
250 val = getattr(obj, valname).im_func
237
251
238 # Recurse to methods, properties, and nested classes.
252 # Recurse to methods, properties, and nested classes.
239 if ((inspect.isfunction(val) or inspect.isclass(val) or
253 if ((inspect.isfunction(val) or inspect.isclass(val) or
240 inspect.ismethod(val) or
254 inspect.ismethod(val) or
241 isinstance(val, property)) and
255 isinstance(val, property)) and
242 self._from_module(module, val)):
256 self._from_module(module, val)):
243 valname = '%s.%s' % (name, valname)
257 valname = '%s.%s' % (name, valname)
244 self._find(tests, val, valname, module, source_lines,
258 self._find(tests, val, valname, module, source_lines,
245 globs, seen)
259 globs, seen)
246
260
247
261
248 # second-chance checker; if the default comparison doesn't
262 # second-chance checker; if the default comparison doesn't
249 # pass, then see if the expected output string contains flags that
263 # pass, then see if the expected output string contains flags that
250 # tell us to ignore the output
264 # tell us to ignore the output
251 class IPDoctestOutputChecker(doctest.OutputChecker):
265 class IPDoctestOutputChecker(doctest.OutputChecker):
252 def check_output(self, want, got, optionflags):
266 def check_output(self, want, got, optionflags):
253 #print '*** My Checker!' # dbg
267 #print '*** My Checker!' # dbg
254
268
255 ret = doctest.OutputChecker.check_output(self, want, got,
269 ret = doctest.OutputChecker.check_output(self, want, got,
256 optionflags)
270 optionflags)
257 if not ret:
271 if not ret:
258 if "#random" in want:
272 if "#random" in want:
259 return True
273 return True
260
274
261 return ret
275 return ret
262
276
263
277
264 class DocTestCase(doctests.DocTestCase):
278 class DocTestCase(doctests.DocTestCase):
265 """Proxy for DocTestCase: provides an address() method that
279 """Proxy for DocTestCase: provides an address() method that
266 returns the correct address for the doctest case. Otherwise
280 returns the correct address for the doctest case. Otherwise
267 acts as a proxy to the test case. To provide hints for address(),
281 acts as a proxy to the test case. To provide hints for address(),
268 an obj may also be passed -- this will be used as the test object
282 an obj may also be passed -- this will be used as the test object
269 for purposes of determining the test address, if it is provided.
283 for purposes of determining the test address, if it is provided.
270 """
284 """
271
285
272 # Note: this method was taken from numpy's nosetester module.
286 # Note: this method was taken from numpy's nosetester module.
273
287
274 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
288 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
275 # its constructor that blocks non-default arguments from being passed
289 # its constructor that blocks non-default arguments from being passed
276 # down into doctest.DocTestCase
290 # down into doctest.DocTestCase
277
291
278 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
292 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
279 checker=None, obj=None, result_var='_'):
293 checker=None, obj=None, result_var='_'):
280 self._result_var = result_var
294 self._result_var = result_var
281 doctests.DocTestCase.__init__(self, test,
295 doctests.DocTestCase.__init__(self, test,
282 optionflags=optionflags,
296 optionflags=optionflags,
283 setUp=setUp, tearDown=tearDown,
297 setUp=setUp, tearDown=tearDown,
284 checker=checker)
298 checker=checker)
285 # Now we must actually copy the original constructor from the stdlib
299 # Now we must actually copy the original constructor from the stdlib
286 # doctest class, because we can't call it directly and a bug in nose
300 # doctest class, because we can't call it directly and a bug in nose
287 # means it never gets passed the right arguments.
301 # means it never gets passed the right arguments.
288
302
289 self._dt_optionflags = optionflags
303 self._dt_optionflags = optionflags
290 self._dt_checker = checker
304 self._dt_checker = checker
291 self._dt_test = test
305 self._dt_test = test
292 self._dt_setUp = setUp
306 self._dt_setUp = setUp
293 self._dt_tearDown = tearDown
307 self._dt_tearDown = tearDown
294
308
309 # Modified runTest from the default stdlib
310 def runTest(self):
311 #print 'HERE!' # dbg
312
313 test = self._dt_test
314 old = sys.stdout
315 new = StringIO()
316 optionflags = self._dt_optionflags
317
318 if not (optionflags & REPORTING_FLAGS):
319 # The option flags don't include any reporting flags,
320 # so add the default reporting flags
321 optionflags |= _unittest_reportflags
322
323 runner = IPDocTestRunner(optionflags=optionflags,
324 checker=self._dt_checker, verbose=False)
325
326 try:
327 runner.DIVIDER = "-"*70
328 failures, tries = runner.run(
329 test, out=new.write, clear_globs=False)
330 finally:
331 sys.stdout = old
332
333 if failures:
334 raise self.failureException(self.format_failure(new.getvalue()))
295
335
296
336
297 # A simple subclassing of the original with a different class name, so we can
337 # A simple subclassing of the original with a different class name, so we can
298 # distinguish and treat differently IPython examples from pure python ones.
338 # distinguish and treat differently IPython examples from pure python ones.
299 class IPExample(doctest.Example): pass
339 class IPExample(doctest.Example): pass
300
340
301
341
302 class IPExternalExample(doctest.Example):
342 class IPExternalExample(doctest.Example):
303 """Doctest examples to be run in an external process."""
343 """Doctest examples to be run in an external process."""
304
344
305 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
345 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
306 options=None):
346 options=None):
307 # Parent constructor
347 # Parent constructor
308 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
348 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
309
349
310 # An EXTRA newline is needed to prevent pexpect hangs
350 # An EXTRA newline is needed to prevent pexpect hangs
311 self.source += '\n'
351 self.source += '\n'
312
352
313
353
314 class IPDocTestParser(doctest.DocTestParser):
354 class IPDocTestParser(doctest.DocTestParser):
315 """
355 """
316 A class used to parse strings containing doctest examples.
356 A class used to parse strings containing doctest examples.
317
357
318 Note: This is a version modified to properly recognize IPython input and
358 Note: This is a version modified to properly recognize IPython input and
319 convert any IPython examples into valid Python ones.
359 convert any IPython examples into valid Python ones.
320 """
360 """
321 # This regular expression is used to find doctest examples in a
361 # This regular expression is used to find doctest examples in a
322 # string. It defines three groups: `source` is the source code
362 # string. It defines three groups: `source` is the source code
323 # (including leading indentation and prompts); `indent` is the
363 # (including leading indentation and prompts); `indent` is the
324 # indentation of the first (PS1) line of the source code; and
364 # indentation of the first (PS1) line of the source code; and
325 # `want` is the expected output (including leading indentation).
365 # `want` is the expected output (including leading indentation).
326
366
327 # Classic Python prompts or default IPython ones
367 # Classic Python prompts or default IPython ones
328 _PS1_PY = r'>>>'
368 _PS1_PY = r'>>>'
329 _PS2_PY = r'\.\.\.'
369 _PS2_PY = r'\.\.\.'
330
370
331 _PS1_IP = r'In\ \[\d+\]:'
371 _PS1_IP = r'In\ \[\d+\]:'
332 _PS2_IP = r'\ \ \ \.\.\.+:'
372 _PS2_IP = r'\ \ \ \.\.\.+:'
333
373
334 _RE_TPL = r'''
374 _RE_TPL = r'''
335 # Source consists of a PS1 line followed by zero or more PS2 lines.
375 # Source consists of a PS1 line followed by zero or more PS2 lines.
336 (?P<source>
376 (?P<source>
337 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
377 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
338 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
378 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
339 \n? # a newline
379 \n? # a newline
340 # Want consists of any non-blank lines that do not start with PS1.
380 # Want consists of any non-blank lines that do not start with PS1.
341 (?P<want> (?:(?![ ]*$) # Not a blank line
381 (?P<want> (?:(?![ ]*$) # Not a blank line
342 (?![ ]*%s) # Not a line starting with PS1
382 (?![ ]*%s) # Not a line starting with PS1
343 (?![ ]*%s) # Not a line starting with PS2
383 (?![ ]*%s) # Not a line starting with PS2
344 .*$\n? # But any other line
384 .*$\n? # But any other line
345 )*)
385 )*)
346 '''
386 '''
347
387
348 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
388 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
349 re.MULTILINE | re.VERBOSE)
389 re.MULTILINE | re.VERBOSE)
350
390
351 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
391 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
352 re.MULTILINE | re.VERBOSE)
392 re.MULTILINE | re.VERBOSE)
353
393
354 def ip2py(self,source):
394 def ip2py(self,source):
355 """Convert input IPython source into valid Python."""
395 """Convert input IPython source into valid Python."""
356 out = []
396 out = []
357 newline = out.append
397 newline = out.append
358 for lnum,line in enumerate(source.splitlines()):
398 for lnum,line in enumerate(source.splitlines()):
359 newline(_ip.IP.prefilter(line,lnum>0))
399 newline(_ip.IP.prefilter(line,lnum>0))
360 newline('') # ensure a closing newline, needed by doctest
400 newline('') # ensure a closing newline, needed by doctest
361 #print "PYSRC:", '\n'.join(out) # dbg
401 #print "PYSRC:", '\n'.join(out) # dbg
362 return '\n'.join(out)
402 return '\n'.join(out)
363
403
364 def parse(self, string, name='<string>'):
404 def parse(self, string, name='<string>'):
365 """
405 """
366 Divide the given string into examples and intervening text,
406 Divide the given string into examples and intervening text,
367 and return them as a list of alternating Examples and strings.
407 and return them as a list of alternating Examples and strings.
368 Line numbers for the Examples are 0-based. The optional
408 Line numbers for the Examples are 0-based. The optional
369 argument `name` is a name identifying this string, and is only
409 argument `name` is a name identifying this string, and is only
370 used for error messages.
410 used for error messages.
371 """
411 """
372
412
373 #print 'Parse string:\n',string # dbg
413 #print 'Parse string:\n',string # dbg
374
414
375 string = string.expandtabs()
415 string = string.expandtabs()
376 # If all lines begin with the same indentation, then strip it.
416 # If all lines begin with the same indentation, then strip it.
377 min_indent = self._min_indent(string)
417 min_indent = self._min_indent(string)
378 if min_indent > 0:
418 if min_indent > 0:
379 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
419 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
380
420
381 output = []
421 output = []
382 charno, lineno = 0, 0
422 charno, lineno = 0, 0
383
423
384 # Whether to convert the input from ipython to python syntax
424 # Whether to convert the input from ipython to python syntax
385 ip2py = False
425 ip2py = False
386 # Find all doctest examples in the string. First, try them as Python
426 # Find all doctest examples in the string. First, try them as Python
387 # examples, then as IPython ones
427 # examples, then as IPython ones
388 terms = list(self._EXAMPLE_RE_PY.finditer(string))
428 terms = list(self._EXAMPLE_RE_PY.finditer(string))
389 if terms:
429 if terms:
390 # Normal Python example
430 # Normal Python example
391 #print '-'*70 # dbg
431 #print '-'*70 # dbg
392 #print 'PyExample, Source:\n',string # dbg
432 #print 'PyExample, Source:\n',string # dbg
393 #print '-'*70 # dbg
433 #print '-'*70 # dbg
394 Example = doctest.Example
434 Example = doctest.Example
395 else:
435 else:
396 # It's an ipython example. Note that IPExamples are run
436 # It's an ipython example. Note that IPExamples are run
397 # in-process, so their syntax must be turned into valid python.
437 # in-process, so their syntax must be turned into valid python.
398 # IPExternalExamples are run out-of-process (via pexpect) so they
438 # IPExternalExamples are run out-of-process (via pexpect) so they
399 # don't need any filtering (a real ipython will be executing them).
439 # don't need any filtering (a real ipython will be executing them).
400 terms = list(self._EXAMPLE_RE_IP.finditer(string))
440 terms = list(self._EXAMPLE_RE_IP.finditer(string))
401 if re.search(r'#\s*ipdoctest:\s*EXTERNAL',string):
441 if re.search(r'#\s*ipdoctest:\s*EXTERNAL',string):
402 #print '-'*70 # dbg
442 #print '-'*70 # dbg
403 #print 'IPExternalExample, Source:\n',string # dbg
443 #print 'IPExternalExample, Source:\n',string # dbg
404 #print '-'*70 # dbg
444 #print '-'*70 # dbg
405 Example = IPExternalExample
445 Example = IPExternalExample
406 else:
446 else:
407 #print '-'*70 # dbg
447 #print '-'*70 # dbg
408 #print 'IPExample, Source:\n',string # dbg
448 #print 'IPExample, Source:\n',string # dbg
409 #print '-'*70 # dbg
449 #print '-'*70 # dbg
410 Example = IPExample
450 Example = IPExample
411 ip2py = True
451 ip2py = True
412
452
413 for m in terms:
453 for m in terms:
414 # Add the pre-example text to `output`.
454 # Add the pre-example text to `output`.
415 output.append(string[charno:m.start()])
455 output.append(string[charno:m.start()])
416 # Update lineno (lines before this example)
456 # Update lineno (lines before this example)
417 lineno += string.count('\n', charno, m.start())
457 lineno += string.count('\n', charno, m.start())
418 # Extract info from the regexp match.
458 # Extract info from the regexp match.
419 (source, options, want, exc_msg) = \
459 (source, options, want, exc_msg) = \
420 self._parse_example(m, name, lineno,ip2py)
460 self._parse_example(m, name, lineno,ip2py)
421 if Example is IPExternalExample:
461 if Example is IPExternalExample:
422 options[doctest.NORMALIZE_WHITESPACE] = True
462 options[doctest.NORMALIZE_WHITESPACE] = True
423 want += '\n'
463 want += '\n'
424 # Create an Example, and add it to the list.
464 # Create an Example, and add it to the list.
425 if not self._IS_BLANK_OR_COMMENT(source):
465 if not self._IS_BLANK_OR_COMMENT(source):
426 #print 'Example source:', source # dbg
466 #print 'Example source:', source # dbg
427 output.append(Example(source, want, exc_msg,
467 output.append(Example(source, want, exc_msg,
428 lineno=lineno,
468 lineno=lineno,
429 indent=min_indent+len(m.group('indent')),
469 indent=min_indent+len(m.group('indent')),
430 options=options))
470 options=options))
431 # Update lineno (lines inside this example)
471 # Update lineno (lines inside this example)
432 lineno += string.count('\n', m.start(), m.end())
472 lineno += string.count('\n', m.start(), m.end())
433 # Update charno.
473 # Update charno.
434 charno = m.end()
474 charno = m.end()
435 # Add any remaining post-example text to `output`.
475 # Add any remaining post-example text to `output`.
436 output.append(string[charno:])
476 output.append(string[charno:])
437 return output
477 return output
438
478
439 def _parse_example(self, m, name, lineno,ip2py=False):
479 def _parse_example(self, m, name, lineno,ip2py=False):
440 """
480 """
441 Given a regular expression match from `_EXAMPLE_RE` (`m`),
481 Given a regular expression match from `_EXAMPLE_RE` (`m`),
442 return a pair `(source, want)`, where `source` is the matched
482 return a pair `(source, want)`, where `source` is the matched
443 example's source code (with prompts and indentation stripped);
483 example's source code (with prompts and indentation stripped);
444 and `want` is the example's expected output (with indentation
484 and `want` is the example's expected output (with indentation
445 stripped).
485 stripped).
446
486
447 `name` is the string's name, and `lineno` is the line number
487 `name` is the string's name, and `lineno` is the line number
448 where the example starts; both are used for error messages.
488 where the example starts; both are used for error messages.
449
489
450 Optional:
490 Optional:
451 `ip2py`: if true, filter the input via IPython to convert the syntax
491 `ip2py`: if true, filter the input via IPython to convert the syntax
452 into valid python.
492 into valid python.
453 """
493 """
454
494
455 # Get the example's indentation level.
495 # Get the example's indentation level.
456 indent = len(m.group('indent'))
496 indent = len(m.group('indent'))
457
497
458 # Divide source into lines; check that they're properly
498 # Divide source into lines; check that they're properly
459 # indented; and then strip their indentation & prompts.
499 # indented; and then strip their indentation & prompts.
460 source_lines = m.group('source').split('\n')
500 source_lines = m.group('source').split('\n')
461
501
462 # We're using variable-length input prompts
502 # We're using variable-length input prompts
463 ps1 = m.group('ps1')
503 ps1 = m.group('ps1')
464 ps2 = m.group('ps2')
504 ps2 = m.group('ps2')
465 ps1_len = len(ps1)
505 ps1_len = len(ps1)
466
506
467 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
507 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
468 if ps2:
508 if ps2:
469 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
509 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
470
510
471 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
511 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
472
512
473 if ip2py:
513 if ip2py:
474 # Convert source input from IPython into valid Python syntax
514 # Convert source input from IPython into valid Python syntax
475 source = self.ip2py(source)
515 source = self.ip2py(source)
476
516
477 # Divide want into lines; check that it's properly indented; and
517 # Divide want into lines; check that it's properly indented; and
478 # then strip the indentation. Spaces before the last newline should
518 # then strip the indentation. Spaces before the last newline should
479 # be preserved, so plain rstrip() isn't good enough.
519 # be preserved, so plain rstrip() isn't good enough.
480 want = m.group('want')
520 want = m.group('want')
481 want_lines = want.split('\n')
521 want_lines = want.split('\n')
482 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
522 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
483 del want_lines[-1] # forget final newline & spaces after it
523 del want_lines[-1] # forget final newline & spaces after it
484 self._check_prefix(want_lines, ' '*indent, name,
524 self._check_prefix(want_lines, ' '*indent, name,
485 lineno + len(source_lines))
525 lineno + len(source_lines))
486
526
487 # Remove ipython output prompt that might be present in the first line
527 # Remove ipython output prompt that might be present in the first line
488 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
528 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
489
529
490 want = '\n'.join([wl[indent:] for wl in want_lines])
530 want = '\n'.join([wl[indent:] for wl in want_lines])
491
531
492 # If `want` contains a traceback message, then extract it.
532 # If `want` contains a traceback message, then extract it.
493 m = self._EXCEPTION_RE.match(want)
533 m = self._EXCEPTION_RE.match(want)
494 if m:
534 if m:
495 exc_msg = m.group('msg')
535 exc_msg = m.group('msg')
496 else:
536 else:
497 exc_msg = None
537 exc_msg = None
498
538
499 # Extract options from the source.
539 # Extract options from the source.
500 options = self._find_options(source, name, lineno)
540 options = self._find_options(source, name, lineno)
501
541
502 return source, options, want, exc_msg
542 return source, options, want, exc_msg
503
543
504 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
544 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
505 """
545 """
506 Given the lines of a source string (including prompts and
546 Given the lines of a source string (including prompts and
507 leading indentation), check to make sure that every prompt is
547 leading indentation), check to make sure that every prompt is
508 followed by a space character. If any line is not followed by
548 followed by a space character. If any line is not followed by
509 a space character, then raise ValueError.
549 a space character, then raise ValueError.
510
550
511 Note: IPython-modified version which takes the input prompt length as a
551 Note: IPython-modified version which takes the input prompt length as a
512 parameter, so that prompts of variable length can be dealt with.
552 parameter, so that prompts of variable length can be dealt with.
513 """
553 """
514 space_idx = indent+ps1_len
554 space_idx = indent+ps1_len
515 min_len = space_idx+1
555 min_len = space_idx+1
516 for i, line in enumerate(lines):
556 for i, line in enumerate(lines):
517 if len(line) >= min_len and line[space_idx] != ' ':
557 if len(line) >= min_len and line[space_idx] != ' ':
518 raise ValueError('line %r of the docstring for %s '
558 raise ValueError('line %r of the docstring for %s '
519 'lacks blank after %s: %r' %
559 'lacks blank after %s: %r' %
520 (lineno+i+1, name,
560 (lineno+i+1, name,
521 line[indent:space_idx], line))
561 line[indent:space_idx], line))
522
562
563
523 SKIP = doctest.register_optionflag('SKIP')
564 SKIP = doctest.register_optionflag('SKIP')
524
565
525
566
526 class IPDocTestRunner(doctest.DocTestRunner):
567 class IPDocTestRunner(doctest.DocTestRunner):
527
568
528 # Unfortunately, doctest uses a private method (__run) for the actual run
569 # Unfortunately, doctest uses a private method (__run) for the actual run
529 # execution, so we can't cleanly override just that part. Instead, we have
570 # execution, so we can't cleanly override just that part. Instead, we have
530 # to copy/paste the entire run() implementation so we can call our own
571 # to copy/paste the entire run() implementation so we can call our own
531 # customized runner.
572 # customized runner.
573
532 #/////////////////////////////////////////////////////////////////
574 #/////////////////////////////////////////////////////////////////
533 # DocTest Running
575 # DocTest Running
534 #/////////////////////////////////////////////////////////////////
576 #/////////////////////////////////////////////////////////////////
577
578 __LINECACHE_FILENAME_RE = re.compile(r'<doctest '
579 r'(?P<name>[\w\.]+)'
580 r'\[(?P<examplenum>\d+)\]>$')
581
582 def __patched_linecache_getlines(self, filename, module_globals=None):
583 m = self.__LINECACHE_FILENAME_RE.match(filename)
584 if m and m.group('name') == self.test.name:
585 example = self.test.examples[int(m.group('examplenum'))]
586 return example.source.splitlines(True)
587 else:
588 return self.save_linecache_getlines(filename, module_globals)
589
535
590
536 def __run(self, test, compileflags, out):
591 def _run_ip(self, test, compileflags, out):
537 """
592 """
538 Run the examples in `test`. Write the outcome of each example
593 Run the examples in `test`. Write the outcome of each example
539 with one of the `DocTestRunner.report_*` methods, using the
594 with one of the `DocTestRunner.report_*` methods, using the
540 writer function `out`. `compileflags` is the set of compiler
595 writer function `out`. `compileflags` is the set of compiler
541 flags that should be used to execute examples. Return a tuple
596 flags that should be used to execute examples. Return a tuple
542 `(f, t)`, where `t` is the number of examples tried, and `f`
597 `(f, t)`, where `t` is the number of examples tried, and `f`
543 is the number of examples that failed. The examples are run
598 is the number of examples that failed. The examples are run
544 in the namespace `test.globs`.
599 in the namespace `test.globs`.
545 """
600 """
601
602 #print 'Custom ip runner! __run' # dbg
603
546 # Keep track of the number of failures and tries.
604 # Keep track of the number of failures and tries.
547 failures = tries = 0
605 failures = tries = 0
548
606
549 # Save the option flags (since option directives can be used
607 # Save the option flags (since option directives can be used
550 # to modify them).
608 # to modify them).
551 original_optionflags = self.optionflags
609 original_optionflags = self.optionflags
552
610
553 SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
611 SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
554
612
555 check = self._checker.check_output
613 check = self._checker.check_output
556
614
557 # Process each example.
615 # Process each example.
558 for examplenum, example in enumerate(test.examples):
616 for examplenum, example in enumerate(test.examples):
559
617
560 # If REPORT_ONLY_FIRST_FAILURE is set, then supress
618 # If REPORT_ONLY_FIRST_FAILURE is set, then supress
561 # reporting after the first failure.
619 # reporting after the first failure.
562 quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
620 quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
563 failures > 0)
621 failures > 0)
564
622
565 # Merge in the example's options.
623 # Merge in the example's options.
566 self.optionflags = original_optionflags
624 self.optionflags = original_optionflags
567 if example.options:
625 if example.options:
568 for (optionflag, val) in example.options.items():
626 for (optionflag, val) in example.options.items():
569 if val:
627 if val:
570 self.optionflags |= optionflag
628 self.optionflags |= optionflag
571 else:
629 else:
572 self.optionflags &= ~optionflag
630 self.optionflags &= ~optionflag
573
631
574 # If 'SKIP' is set, then skip this example.
632 # If 'SKIP' is set, then skip this example.
575 if self.optionflags & SKIP:
633 if self.optionflags & SKIP:
576 continue
634 continue
577
635
578 # Record that we started this example.
636 # Record that we started this example.
579 tries += 1
637 tries += 1
580 if not quiet:
638 if not quiet:
581 self.report_start(out, test, example)
639 self.report_start(out, test, example)
582
640
583 # Use a special filename for compile(), so we can retrieve
641 # Use a special filename for compile(), so we can retrieve
584 # the source code during interactive debugging (see
642 # the source code during interactive debugging (see
585 # __patched_linecache_getlines).
643 # __patched_linecache_getlines).
586 filename = '<doctest %s[%d]>' % (test.name, examplenum)
644 filename = '<doctest %s[%d]>' % (test.name, examplenum)
587
645
588 # Run the example in the given context (globs), and record
646 # Run the example in the given context (globs), and record
589 # any exception that gets raised. (But don't intercept
647 # any exception that gets raised. (But don't intercept
590 # keyboard interrupts.)
648 # keyboard interrupts.)
591 try:
649 try:
592 # Don't blink! This is where the user's code gets run.
650 # Don't blink! This is where the user's code gets run.
593 exec compile(example.source, filename, "single",
651 exec compile(example.source, filename, "single",
594 compileflags, 1) in test.globs
652 compileflags, 1) in test.globs
595 self.debugger.set_continue() # ==== Example Finished ====
653 self.debugger.set_continue() # ==== Example Finished ====
654 # ipython
655 #_ip.user_ns.update(test.globs)
656 test.globs.update(_ip.user_ns)
657 #
596 exception = None
658 exception = None
597 except KeyboardInterrupt:
659 except KeyboardInterrupt:
598 raise
660 raise
599 except:
661 except:
600 exception = sys.exc_info()
662 exception = sys.exc_info()
601 self.debugger.set_continue() # ==== Example Finished ====
663 self.debugger.set_continue() # ==== Example Finished ====
602
664
603 got = self._fakeout.getvalue() # the actual output
665 got = self._fakeout.getvalue() # the actual output
604 self._fakeout.truncate(0)
666 self._fakeout.truncate(0)
605 outcome = FAILURE # guilty until proved innocent or insane
667 outcome = FAILURE # guilty until proved innocent or insane
606
668
607 # If the example executed without raising any exceptions,
669 # If the example executed without raising any exceptions,
608 # verify its output.
670 # verify its output.
609 if exception is None:
671 if exception is None:
610 if check(example.want, got, self.optionflags):
672 if check(example.want, got, self.optionflags):
611 outcome = SUCCESS
673 outcome = SUCCESS
612
674
613 # The example raised an exception: check if it was expected.
675 # The example raised an exception: check if it was expected.
614 else:
676 else:
615 exc_info = sys.exc_info()
677 exc_info = sys.exc_info()
616 exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
678 exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
617 if not quiet:
679 if not quiet:
618 got += _exception_traceback(exc_info)
680 got += _exception_traceback(exc_info)
619
681
620 # If `example.exc_msg` is None, then we weren't expecting
682 # If `example.exc_msg` is None, then we weren't expecting
621 # an exception.
683 # an exception.
622 if example.exc_msg is None:
684 if example.exc_msg is None:
623 outcome = BOOM
685 outcome = BOOM
624
686
625 # We expected an exception: see whether it matches.
687 # We expected an exception: see whether it matches.
626 elif check(example.exc_msg, exc_msg, self.optionflags):
688 elif check(example.exc_msg, exc_msg, self.optionflags):
627 outcome = SUCCESS
689 outcome = SUCCESS
628
690
629 # Another chance if they didn't care about the detail.
691 # Another chance if they didn't care about the detail.
630 elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
692 elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
631 m1 = re.match(r'[^:]*:', example.exc_msg)
693 m1 = re.match(r'[^:]*:', example.exc_msg)
632 m2 = re.match(r'[^:]*:', exc_msg)
694 m2 = re.match(r'[^:]*:', exc_msg)
633 if m1 and m2 and check(m1.group(0), m2.group(0),
695 if m1 and m2 and check(m1.group(0), m2.group(0),
634 self.optionflags):
696 self.optionflags):
635 outcome = SUCCESS
697 outcome = SUCCESS
636
698
637 # Report the outcome.
699 # Report the outcome.
638 if outcome is SUCCESS:
700 if outcome is SUCCESS:
639 if not quiet:
701 if not quiet:
640 self.report_success(out, test, example, got)
702 self.report_success(out, test, example, got)
641 elif outcome is FAILURE:
703 elif outcome is FAILURE:
642 if not quiet:
704 if not quiet:
643 self.report_failure(out, test, example, got)
705 self.report_failure(out, test, example, got)
644 failures += 1
706 failures += 1
645 elif outcome is BOOM:
707 elif outcome is BOOM:
646 if not quiet:
708 if not quiet:
647 self.report_unexpected_exception(out, test, example,
709 self.report_unexpected_exception(out, test, example,
648 exc_info)
710 exc_info)
649 failures += 1
711 failures += 1
650 else:
712 else:
651 assert False, ("unknown outcome", outcome)
713 assert False, ("unknown outcome", outcome)
652
714
653 # Restore the option flags (in case they were modified)
715 # Restore the option flags (in case they were modified)
654 self.optionflags = original_optionflags
716 self.optionflags = original_optionflags
655
717
656 # Record and return the number of failures and tries.
718 # Record and return the number of failures and tries.
657
719
658 #self.__record_outcome(test, failures, tries)
659
660 # Hack to access a parent private method by working around Python's
720 # Hack to access a parent private method by working around Python's
661 # name mangling (which is fortunately simple).
721 # name mangling (which is fortunately simple).
722 #self.__record_outcome(test, failures, tries)
662 doctest.DocTestRunner._DocTestRunner__record_outcome(self,test,
723 doctest.DocTestRunner._DocTestRunner__record_outcome(self,test,
663 failures, tries)
724 failures, tries)
725
664 return failures, tries
726 return failures, tries
665
727
728
666 def run(self, test, compileflags=None, out=None, clear_globs=True):
729 def run(self, test, compileflags=None, out=None, clear_globs=True):
667 """
730 """
668 Run the examples in `test`, and display the results using the
731 Run the examples in `test`, and display the results using the
669 writer function `out`.
732 writer function `out`.
670
733
671 The examples are run in the namespace `test.globs`. If
734 The examples are run in the namespace `test.globs`. If
672 `clear_globs` is true (the default), then this namespace will
735 `clear_globs` is true (the default), then this namespace will
673 be cleared after the test runs, to help with garbage
736 be cleared after the test runs, to help with garbage
674 collection. If you would like to examine the namespace after
737 collection. If you would like to examine the namespace after
675 the test completes, then use `clear_globs=False`.
738 the test completes, then use `clear_globs=False`.
676
739
677 `compileflags` gives the set of flags that should be used by
740 `compileflags` gives the set of flags that should be used by
678 the Python compiler when running the examples. If not
741 the Python compiler when running the examples. If not
679 specified, then it will default to the set of future-import
742 specified, then it will default to the set of future-import
680 flags that apply to `globs`.
743 flags that apply to `globs`.
681
744
682 The output of each example is checked using
745 The output of each example is checked using
683 `DocTestRunner.check_output`, and the results are formatted by
746 `DocTestRunner.check_output`, and the results are formatted by
684 the `DocTestRunner.report_*` methods.
747 the `DocTestRunner.report_*` methods.
685 """
748 """
749 #print 'Custom ip runner!' # dbg
750
686 self.test = test
751 self.test = test
687
752
688 if compileflags is None:
753 if compileflags is None:
689 compileflags = _extract_future_flags(test.globs)
754 compileflags = _extract_future_flags(test.globs)
690
755
691 save_stdout = sys.stdout
756 save_stdout = sys.stdout
692 if out is None:
757 if out is None:
693 out = save_stdout.write
758 out = save_stdout.write
694 sys.stdout = self._fakeout
759 sys.stdout = self._fakeout
695
760
696 # Patch pdb.set_trace to restore sys.stdout during interactive
761 # Patch pdb.set_trace to restore sys.stdout during interactive
697 # debugging (so it's not still redirected to self._fakeout).
762 # debugging (so it's not still redirected to self._fakeout).
698 # Note that the interactive output will go to *our*
763 # Note that the interactive output will go to *our*
699 # save_stdout, even if that's not the real sys.stdout; this
764 # save_stdout, even if that's not the real sys.stdout; this
700 # allows us to write test cases for the set_trace behavior.
765 # allows us to write test cases for the set_trace behavior.
701 save_set_trace = pdb.set_trace
766 save_set_trace = pdb.set_trace
702 self.debugger = _OutputRedirectingPdb(save_stdout)
767 self.debugger = _OutputRedirectingPdb(save_stdout)
703 self.debugger.reset()
768 self.debugger.reset()
704 pdb.set_trace = self.debugger.set_trace
769 pdb.set_trace = self.debugger.set_trace
705
770
706 # Patch linecache.getlines, so we can see the example's source
771 # Patch linecache.getlines, so we can see the example's source
707 # when we're inside the debugger.
772 # when we're inside the debugger.
708 self.save_linecache_getlines = linecache.getlines
773 self.save_linecache_getlines = linecache.getlines
709 linecache.getlines = self.__patched_linecache_getlines
774 linecache.getlines = self.__patched_linecache_getlines
710
775
711 try:
776 try:
712 return self.__run(test, compileflags, out)
777 # Hack to access a parent private method by working around Python's
778 # name mangling (which is fortunately simple).
779 #return self.__run(test, compileflags, out)
780 return self._run_ip(test, compileflags, out)
781 #return doctest.DocTestRunner._DocTestRunner__run(self,test,
782 # compileflags, out)
713 finally:
783 finally:
784 _ip.user_ns.update(test.globs)
714 sys.stdout = save_stdout
785 sys.stdout = save_stdout
715 pdb.set_trace = save_set_trace
786 pdb.set_trace = save_set_trace
716 linecache.getlines = self.save_linecache_getlines
787 linecache.getlines = self.save_linecache_getlines
717 if clear_globs:
788 if clear_globs:
718 test.globs.clear()
789 test.globs.clear()
719
790
720
791
721 class DocFileCase(doctest.DocFileCase):
792 class DocFileCase(doctest.DocFileCase):
722 """Overrides to provide filename
793 """Overrides to provide filename
723 """
794 """
724 def address(self):
795 def address(self):
725 return (self._dt_test.filename, None, None)
796 return (self._dt_test.filename, None, None)
726
797
727
798
728 class ExtensionDoctest(doctests.Doctest):
799 class ExtensionDoctest(doctests.Doctest):
729 """Nose Plugin that supports doctests in extension modules.
800 """Nose Plugin that supports doctests in extension modules.
730 """
801 """
731 name = 'extdoctest' # call nosetests with --with-extdoctest
802 name = 'extdoctest' # call nosetests with --with-extdoctest
732 enabled = True
803 enabled = True
733
804
734 def options(self, parser, env=os.environ):
805 def options(self, parser, env=os.environ):
735 Plugin.options(self, parser, env)
806 Plugin.options(self, parser, env)
736
807
737 def configure(self, options, config):
808 def configure(self, options, config):
738 Plugin.configure(self, options, config)
809 Plugin.configure(self, options, config)
739 self.doctest_tests = options.doctest_tests
810 self.doctest_tests = options.doctest_tests
740 self.extension = tolist(options.doctestExtension)
811 self.extension = tolist(options.doctestExtension)
741 self.finder = DocTestFinder()
812 self.finder = DocTestFinder()
742 self.parser = doctest.DocTestParser()
813 self.parser = doctest.DocTestParser()
743 self.globs = None
814 self.globs = None
744 self.extraglobs = None
815 self.extraglobs = None
745
816
746 def loadTestsFromExtensionModule(self,filename):
817 def loadTestsFromExtensionModule(self,filename):
747 bpath,mod = os.path.split(filename)
818 bpath,mod = os.path.split(filename)
748 modname = os.path.splitext(mod)[0]
819 modname = os.path.splitext(mod)[0]
749 try:
820 try:
750 sys.path.append(bpath)
821 sys.path.append(bpath)
751 module = __import__(modname)
822 module = __import__(modname)
752 tests = list(self.loadTestsFromModule(module))
823 tests = list(self.loadTestsFromModule(module))
753 finally:
824 finally:
754 sys.path.pop()
825 sys.path.pop()
755 return tests
826 return tests
756
827
757 # NOTE: the method below is almost a copy of the original one in nose, with
828 # NOTE: the method below is almost a copy of the original one in nose, with
758 # a few modifications to control output checking.
829 # a few modifications to control output checking.
759
830
760 def loadTestsFromModule(self, module):
831 def loadTestsFromModule(self, module):
761 #print 'lTM',module # dbg
832 #print 'lTM',module # dbg
762
833
763 if not self.matches(module.__name__):
834 if not self.matches(module.__name__):
764 log.debug("Doctest doesn't want module %s", module)
835 log.debug("Doctest doesn't want module %s", module)
765 return
836 return
766
837
767 ## try:
838 ## try:
768 ## print 'Globs:',self.globs.keys() # dbg
839 ## print 'Globs:',self.globs.keys() # dbg
769 ## except:
840 ## except:
770 ## pass
841 ## pass
771
842
772 tests = self.finder.find(module,globs=self.globs,
843 tests = self.finder.find(module,globs=self.globs,
773 extraglobs=self.extraglobs)
844 extraglobs=self.extraglobs)
774 if not tests:
845 if not tests:
775 return
846 return
776 tests.sort()
847 tests.sort()
777 module_file = module.__file__
848 module_file = module.__file__
778 if module_file[-4:] in ('.pyc', '.pyo'):
849 if module_file[-4:] in ('.pyc', '.pyo'):
779 module_file = module_file[:-1]
850 module_file = module_file[:-1]
780 for test in tests:
851 for test in tests:
781 if not test.examples:
852 if not test.examples:
782 continue
853 continue
783 if not test.filename:
854 if not test.filename:
784 test.filename = module_file
855 test.filename = module_file
785
856
786 # xxx - checker and options may be ok instantiated once outside loop
857 # xxx - checker and options may be ok instantiated once outside loop
787
858
788 # always use whitespace and ellipsis options
859 # always use whitespace and ellipsis options
789 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
860 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
790 checker = IPDoctestOutputChecker()
861 checker = IPDoctestOutputChecker()
791
862
792 yield DocTestCase(test,
863 yield DocTestCase(test,
793 optionflags=optionflags,
864 optionflags=optionflags,
794 checker=checker)
865 checker=checker)
795
866
796 def loadTestsFromFile(self, filename):
867 def loadTestsFromFile(self, filename):
797 #print 'lTF',filename # dbg
868 #print 'lTF',filename # dbg
798
869
799 if is_extension_module(filename):
870 if is_extension_module(filename):
800 for t in self.loadTestsFromExtensionModule(filename):
871 for t in self.loadTestsFromExtensionModule(filename):
801 yield t
872 yield t
802 else:
873 else:
803 if self.extension and anyp(filename.endswith, self.extension):
874 if self.extension and anyp(filename.endswith, self.extension):
804 name = os.path.basename(filename)
875 name = os.path.basename(filename)
805 dh = open(filename)
876 dh = open(filename)
806 try:
877 try:
807 doc = dh.read()
878 doc = dh.read()
808 finally:
879 finally:
809 dh.close()
880 dh.close()
810 test = self.parser.get_doctest(
881 test = self.parser.get_doctest(
811 doc, globs={'__file__': filename}, name=name,
882 doc, globs={'__file__': filename}, name=name,
812 filename=filename, lineno=0)
883 filename=filename, lineno=0)
813 if test.examples:
884 if test.examples:
814 #print 'FileCase:',test.examples # dbg
885 #print 'FileCase:',test.examples # dbg
815 yield DocFileCase(test)
886 yield DocFileCase(test)
816 else:
887 else:
817 yield False # no tests to load
888 yield False # no tests to load
818
889
819 def wantFile(self,filename):
890 def wantFile(self,filename):
820 """Return whether the given filename should be scanned for tests.
891 """Return whether the given filename should be scanned for tests.
821
892
822 Modified version that accepts extension modules as valid containers for
893 Modified version that accepts extension modules as valid containers for
823 doctests.
894 doctests.
824 """
895 """
825 #print 'Filename:',filename # dbg
896 #print 'Filename:',filename # dbg
826
897
827 # temporarily hardcoded list, will move to driver later
898 # temporarily hardcoded list, will move to driver later
828 exclude = ['IPython/external/',
899 exclude = ['IPython/external/',
829 'IPython/Extensions/ipy_',
900 'IPython/Extensions/ipy_',
830 'IPython/platutils_win32',
901 'IPython/platutils_win32',
831 'IPython/frontend/cocoa',
902 'IPython/frontend/cocoa',
832 'IPython_doctest_plugin',
903 'IPython_doctest_plugin',
833 'IPython/Gnuplot',
904 'IPython/Gnuplot',
834 'IPython/Extensions/PhysicalQIn']
905 'IPython/Extensions/PhysicalQIn']
835
906
836 for fex in exclude:
907 for fex in exclude:
837 if fex in filename: # substring
908 if fex in filename: # substring
838 #print '###>>> SKIP:',filename # dbg
909 #print '###>>> SKIP:',filename # dbg
839 return False
910 return False
840
911
841 if is_extension_module(filename):
912 if is_extension_module(filename):
842 return True
913 return True
843 else:
914 else:
844 return doctests.Doctest.wantFile(self,filename)
915 return doctests.Doctest.wantFile(self,filename)
845
916
846
917
847 class IPythonDoctest(ExtensionDoctest):
918 class IPythonDoctest(ExtensionDoctest):
848 """Nose Plugin that supports doctests in extension modules.
919 """Nose Plugin that supports doctests in extension modules.
849 """
920 """
850 name = 'ipdoctest' # call nosetests with --with-ipdoctest
921 name = 'ipdoctest' # call nosetests with --with-ipdoctest
851 enabled = True
922 enabled = True
852
923
853 def configure(self, options, config):
924 def configure(self, options, config):
854
925
855 Plugin.configure(self, options, config)
926 Plugin.configure(self, options, config)
856 self.doctest_tests = options.doctest_tests
927 self.doctest_tests = options.doctest_tests
857 self.extension = tolist(options.doctestExtension)
928 self.extension = tolist(options.doctestExtension)
858 self.parser = IPDocTestParser()
929 self.parser = IPDocTestParser()
859 self.finder = DocTestFinder(parser=self.parser)
930 self.finder = DocTestFinder(parser=self.parser)
860
931
861 # XXX - we need to run in the ipython user's namespace, but doing so is
932 # XXX - we need to run in the ipython user's namespace, but doing so is
862 # breaking normal doctests!
933 # breaking normal doctests!
863
934
864 #self.globs = _ip.user_ns
935 #self.globs = _ip.user_ns
865 self.globs = None
936 self.globs = None
866
937
867 self.extraglobs = None
938 self.extraglobs = None
939
940 # Use a specially modified test runner that is IPython-aware
941 self.iprunner = None
General Comments 0
You need to be logged in to leave comments. Login now