##// END OF EJS Templates
Merge pull request #13314 from Kojoley/refactor-doctest-skipping-implementation...
Matthias Bussonnier -
r27124:a8ca8395 merge
parent child Browse files
Show More
@@ -132,6 +132,7 b' from IPython.core.error import TryNext'
132 132 from IPython.core.inputtransformer2 import ESC_MAGIC
133 133 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
134 134 from IPython.core.oinspect import InspectColors
135 from IPython.testing.skipdoctest import skip_doctest
135 136 from IPython.utils import generics
136 137 from IPython.utils.dir2 import dir2, get_real_method
137 138 from IPython.utils.path import ensure_dir_exists
@@ -190,6 +191,8 b' class ProvisionalCompleterWarning(FutureWarning):'
190 191
191 192 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
192 193
194
195 @skip_doctest
193 196 @contextmanager
194 197 def provisionalcompleter(action='ignore'):
195 198 """
@@ -114,7 +114,6 b' from IPython import get_ipython'
114 114 from IPython.utils import PyColorize
115 115 from IPython.utils import coloransi, py3compat
116 116 from IPython.core.excolors import exception_colors
117 from IPython.testing.skipdoctest import skip_doctest
118 117
119 118 # skip module docstests
120 119 __skip_doctest__ = True
@@ -180,7 +179,6 b' class Tracer(object):'
180 179 while functioning acceptably (though with limitations) if outside of it.
181 180 """
182 181
183 @skip_doctest
184 182 def __init__(self, colors=None):
185 183 """
186 184 DEPRECATED
@@ -921,7 +919,6 b' class Pdb(OldPdb):'
921 919 return True
922 920 return False
923 921
924 @skip_doctest
925 922 def _is_in_decorator_internal_and_should_skip(self, frame):
926 923 """
927 924 Utility to tell us whether we are in a decorator internal and should stop.
@@ -413,7 +413,6 b' class ExecutionMagics(Magics):'
413 413 self.shell.call_pdb = new_pdb
414 414 print('Automatic pdb calling has been turned',on_off(new_pdb))
415 415
416 @skip_doctest
417 416 @magic_arguments.magic_arguments()
418 417 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
419 418 help="""
@@ -63,7 +63,6 b' class OSMagics(Magics):'
63 63 super().__init__(shell=shell, **kwargs)
64 64
65 65
66 @skip_doctest
67 66 def _isexec_POSIX(self, file):
68 67 """
69 68 Test for executable on a POSIX system
@@ -75,14 +74,12 b' class OSMagics(Magics):'
75 74
76 75
77 76
78 @skip_doctest
79 77 def _isexec_WIN(self, file):
80 78 """
81 79 Test for executable file on non POSIX system
82 80 """
83 81 return file.is_file() and self.execre.match(file.name) is not None
84 82
85 @skip_doctest
86 83 def isexec(self, file):
87 84 """
88 85 Test for executable file on non POSIX system
@@ -633,8 +630,8 b' class OSMagics(Magics):'
633 630
634 631 # while the list form is useful to loop over:
635 632 In [6]: for f in a.l:
636 ...: !wc -l $f
637 ...:
633 ...: !wc -l $f
634 ...:
638 635 146 setup.py
639 636 130 win32_manual_post_install.py
640 637
@@ -20,7 +20,6 b' Limitations:'
20 20
21 21 # From the standard library
22 22 import doctest
23 import inspect
24 23 import logging
25 24 import os
26 25 import re
@@ -38,106 +37,16 b' log = logging.getLogger(__name__)'
38 37 # Classes and functions
39 38 #-----------------------------------------------------------------------------
40 39
41 class DocTestSkip(object):
42 """Object wrapper for doctests to be skipped."""
43 40
44 ds_skip = """Doctest to skip.
45 >>> 1 #doctest: +SKIP
46 """
47
48 def __init__(self,obj):
49 self.obj = obj
50
51 def __getattribute__(self,key):
52 if key == '__doc__':
53 return DocTestSkip.ds_skip
54 else:
55 return getattr(object.__getattribute__(self,'obj'),key)
56
57 # Modified version of the one in the stdlib, that fixes a python bug (doctests
58 # not found in extension modules, http://bugs.python.org/issue3158)
59 41 class DocTestFinder(doctest.DocTestFinder):
42 def _get_test(self, obj, name, module, globs, source_lines):
43 test = super()._get_test(obj, name, module, globs, source_lines)
60 44
61 def _from_module(self, module, object):
62 """
63 Return true if the given object is defined in the given
64 module.
65 """
66 if module is None:
67 return True
68 elif inspect.isfunction(object):
69 return module.__dict__ is object.__globals__
70 elif inspect.isbuiltin(object):
71 return module.__name__ == object.__module__
72 elif inspect.isclass(object):
73 return module.__name__ == object.__module__
74 elif inspect.ismethod(object):
75 # This one may be a bug in cython that fails to correctly set the
76 # __module__ attribute of methods, but since the same error is easy
77 # to make by extension code writers, having this safety in place
78 # isn't such a bad idea
79 return module.__name__ == object.__self__.__class__.__module__
80 elif inspect.getmodule(object) is not None:
81 return module is inspect.getmodule(object)
82 elif hasattr(object, '__module__'):
83 return module.__name__ == object.__module__
84 elif isinstance(object, property):
85 return True # [XX] no way not be sure.
86 elif inspect.ismethoddescriptor(object):
87 # Unbound PyQt signals reach this point in Python 3.4b3, and we want
88 # to avoid throwing an error. See also http://bugs.python.org/issue3158
89 return False
90 else:
91 raise ValueError("object must be a class or function, got %r" % object)
45 if bool(getattr(obj, "__skip_doctest__", False)) and test is not None:
46 for example in test.examples:
47 example.options[doctest.SKIP] = True
92 48
93 def _find(self, tests, obj, name, module, source_lines, globs, seen):
94 """
95 Find tests for the given object and any contained objects, and
96 add them to `tests`.
97 """
98 print('_find for:', obj, name, module) # dbg
99 if bool(getattr(obj, "__skip_doctest__", False)):
100 #print 'SKIPPING DOCTEST FOR:',obj # dbg
101 obj = DocTestSkip(obj)
102
103 doctest.DocTestFinder._find(self,tests, obj, name, module,
104 source_lines, globs, seen)
105
106 # Below we re-run pieces of the above method with manual modifications,
107 # because the original code is buggy and fails to correctly identify
108 # doctests in extension modules.
109
110 # Local shorthands
111 from inspect import isroutine, isclass
112
113 # Look for tests in a module's contained objects.
114 if inspect.ismodule(obj) and self._recurse:
115 for valname, val in obj.__dict__.items():
116 valname1 = '%s.%s' % (name, valname)
117 if ( (isroutine(val) or isclass(val))
118 and self._from_module(module, val) ):
119
120 self._find(tests, val, valname1, module, source_lines,
121 globs, seen)
122
123 # Look for tests in a class's contained objects.
124 if inspect.isclass(obj) and self._recurse:
125 #print 'RECURSE into class:',obj # dbg
126 for valname, val in obj.__dict__.items():
127 # Special handling for staticmethod/classmethod.
128 if isinstance(val, staticmethod):
129 val = getattr(obj, valname)
130 if isinstance(val, classmethod):
131 val = getattr(obj, valname).__func__
132
133 # Recurse to methods, properties, and nested classes.
134 if ((inspect.isfunction(val) or inspect.isclass(val) or
135 inspect.ismethod(val) or
136 isinstance(val, property)) and
137 self._from_module(module, val)):
138 valname = '%s.%s' % (name, valname)
139 self._find(tests, val, valname, module, source_lines,
140 globs, seen)
49 return test
141 50
142 51
143 52 class IPDoctestOutputChecker(doctest.OutputChecker):
General Comments 0
You need to be logged in to leave comments. Login now