Show More
@@ -132,6 +132,7 b' from IPython.core.error import TryNext' | |||||
132 | from IPython.core.inputtransformer2 import ESC_MAGIC |
|
132 | from IPython.core.inputtransformer2 import ESC_MAGIC | |
133 | from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol |
|
133 | from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol | |
134 | from IPython.core.oinspect import InspectColors |
|
134 | from IPython.core.oinspect import InspectColors | |
|
135 | from IPython.testing.skipdoctest import skip_doctest | |||
135 | from IPython.utils import generics |
|
136 | from IPython.utils import generics | |
136 | from IPython.utils.dir2 import dir2, get_real_method |
|
137 | from IPython.utils.dir2 import dir2, get_real_method | |
137 | from IPython.utils.path import ensure_dir_exists |
|
138 | from IPython.utils.path import ensure_dir_exists | |
@@ -190,6 +191,8 b' class ProvisionalCompleterWarning(FutureWarning):' | |||||
190 |
|
191 | |||
191 | warnings.filterwarnings('error', category=ProvisionalCompleterWarning) |
|
192 | warnings.filterwarnings('error', category=ProvisionalCompleterWarning) | |
192 |
|
193 | |||
|
194 | ||||
|
195 | @skip_doctest | |||
193 | @contextmanager |
|
196 | @contextmanager | |
194 | def provisionalcompleter(action='ignore'): |
|
197 | def provisionalcompleter(action='ignore'): | |
195 | """ |
|
198 | """ |
@@ -114,7 +114,6 b' from IPython import get_ipython' | |||||
114 | from IPython.utils import PyColorize |
|
114 | from IPython.utils import PyColorize | |
115 | from IPython.utils import coloransi, py3compat |
|
115 | from IPython.utils import coloransi, py3compat | |
116 | from IPython.core.excolors import exception_colors |
|
116 | from IPython.core.excolors import exception_colors | |
117 | from IPython.testing.skipdoctest import skip_doctest |
|
|||
118 |
|
117 | |||
119 | # skip module docstests |
|
118 | # skip module docstests | |
120 | __skip_doctest__ = True |
|
119 | __skip_doctest__ = True | |
@@ -180,7 +179,6 b' class Tracer(object):' | |||||
180 | while functioning acceptably (though with limitations) if outside of it. |
|
179 | while functioning acceptably (though with limitations) if outside of it. | |
181 | """ |
|
180 | """ | |
182 |
|
181 | |||
183 | @skip_doctest |
|
|||
184 | def __init__(self, colors=None): |
|
182 | def __init__(self, colors=None): | |
185 | """ |
|
183 | """ | |
186 | DEPRECATED |
|
184 | DEPRECATED | |
@@ -921,7 +919,6 b' class Pdb(OldPdb):' | |||||
921 | return True |
|
919 | return True | |
922 | return False |
|
920 | return False | |
923 |
|
921 | |||
924 | @skip_doctest |
|
|||
925 | def _is_in_decorator_internal_and_should_skip(self, frame): |
|
922 | def _is_in_decorator_internal_and_should_skip(self, frame): | |
926 | """ |
|
923 | """ | |
927 | Utility to tell us whether we are in a decorator internal and should stop. |
|
924 | Utility to tell us whether we are in a decorator internal and should stop. |
@@ -413,7 +413,6 b' class ExecutionMagics(Magics):' | |||||
413 | self.shell.call_pdb = new_pdb |
|
413 | self.shell.call_pdb = new_pdb | |
414 | print('Automatic pdb calling has been turned',on_off(new_pdb)) |
|
414 | print('Automatic pdb calling has been turned',on_off(new_pdb)) | |
415 |
|
415 | |||
416 | @skip_doctest |
|
|||
417 | @magic_arguments.magic_arguments() |
|
416 | @magic_arguments.magic_arguments() | |
418 | @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE', |
|
417 | @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE', | |
419 | help=""" |
|
418 | help=""" |
@@ -63,7 +63,6 b' class OSMagics(Magics):' | |||||
63 | super().__init__(shell=shell, **kwargs) |
|
63 | super().__init__(shell=shell, **kwargs) | |
64 |
|
64 | |||
65 |
|
65 | |||
66 | @skip_doctest |
|
|||
67 | def _isexec_POSIX(self, file): |
|
66 | def _isexec_POSIX(self, file): | |
68 | """ |
|
67 | """ | |
69 | Test for executable on a POSIX system |
|
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 | def _isexec_WIN(self, file): |
|
77 | def _isexec_WIN(self, file): | |
80 | """ |
|
78 | """ | |
81 | Test for executable file on non POSIX system |
|
79 | Test for executable file on non POSIX system | |
82 | """ |
|
80 | """ | |
83 | return file.is_file() and self.execre.match(file.name) is not None |
|
81 | return file.is_file() and self.execre.match(file.name) is not None | |
84 |
|
82 | |||
85 | @skip_doctest |
|
|||
86 | def isexec(self, file): |
|
83 | def isexec(self, file): | |
87 | """ |
|
84 | """ | |
88 | Test for executable file on non POSIX system |
|
85 | Test for executable file on non POSIX system | |
@@ -633,8 +630,8 b' class OSMagics(Magics):' | |||||
633 |
|
630 | |||
634 | # while the list form is useful to loop over: |
|
631 | # while the list form is useful to loop over: | |
635 | In [6]: for f in a.l: |
|
632 | In [6]: for f in a.l: | |
636 | ...: !wc -l $f |
|
633 | ...: !wc -l $f | |
637 | ...: |
|
634 | ...: | |
638 | 146 setup.py |
|
635 | 146 setup.py | |
639 | 130 win32_manual_post_install.py |
|
636 | 130 win32_manual_post_install.py | |
640 |
|
637 |
@@ -20,7 +20,6 b' Limitations:' | |||||
20 |
|
20 | |||
21 | # From the standard library |
|
21 | # From the standard library | |
22 | import doctest |
|
22 | import doctest | |
23 | import inspect |
|
|||
24 | import logging |
|
23 | import logging | |
25 | import os |
|
24 | import os | |
26 | import re |
|
25 | import re | |
@@ -38,106 +37,16 b' log = logging.getLogger(__name__)' | |||||
38 | # Classes and functions |
|
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 | class DocTestFinder(doctest.DocTestFinder): |
|
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): |
|
45 | if bool(getattr(obj, "__skip_doctest__", False)) and test is not None: | |
62 | """ |
|
46 | for example in test.examples: | |
63 | Return true if the given object is defined in the given |
|
47 | example.options[doctest.SKIP] = True | |
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) |
|
|||
92 |
|
48 | |||
93 | def _find(self, tests, obj, name, module, source_lines, globs, seen): |
|
49 | return test | |
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) |
|
|||
141 |
|
50 | |||
142 |
|
51 | |||
143 | class IPDoctestOutputChecker(doctest.OutputChecker): |
|
52 | class IPDoctestOutputChecker(doctest.OutputChecker): |
General Comments 0
You need to be logged in to leave comments.
Login now