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