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