##// END OF EJS Templates
Improvements to namespace handling with %run....
Fernando Perez -
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 #/////////////////////////////////////////////////////////////////
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
@@ -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