Show More
@@ -43,9 +43,19 b' 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 |
@@ -83,6 +93,10 b' class ncdict(dict):' | |||
|
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 | """ |
@@ -292,6 +306,32 b' class DocTestCase(doctests.DocTestCase):' | |||
|
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 |
@@ -520,6 +560,7 b' class IPDocTestParser(doctest.DocTestParser):' | |||
|
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 | |
@@ -529,11 +570,25 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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 | #///////////////////////////////////////////////////////////////// |
|
535 | 577 | |
|
536 | def __run(self, test, compileflags, out): | |
|
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 | ||
|
590 | ||
|
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 |
@@ -543,6 +598,9 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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 | |
@@ -593,6 +651,10 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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 |
@@ -655,14 +717,15 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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 |
@@ -683,6 +746,8 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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: |
@@ -709,8 +774,14 b' class IPDocTestRunner(doctest.DocTestRunner):' | |||
|
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 |
@@ -865,3 +936,6 b' class IPythonDoctest(ExtensionDoctest):' | |||
|
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