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 | """ |
@@ -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 | |
@@ -54,42 +53,8 b' class DocTestSkip(object):' | |||||
54 | else: |
|
53 | else: | |
55 | return getattr(object.__getattribute__(self,'obj'),key) |
|
54 | return getattr(object.__getattribute__(self,'obj'),key) | |
56 |
|
55 | |||
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): |
|
|||
60 |
|
||||
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) |
|
|||
92 |
|
56 | |||
|
57 | class DocTestFinder(doctest.DocTestFinder): | |||
93 | def _find(self, tests, obj, name, module, source_lines, globs, seen): |
|
58 | def _find(self, tests, obj, name, module, source_lines, globs, seen): | |
94 | """ |
|
59 | """ | |
95 | Find tests for the given object and any contained objects, and |
|
60 | Find tests for the given object and any contained objects, and | |
@@ -99,45 +64,8 b' class DocTestFinder(doctest.DocTestFinder):' | |||||
99 | if bool(getattr(obj, "__skip_doctest__", False)): |
|
64 | if bool(getattr(obj, "__skip_doctest__", False)): | |
100 | #print 'SKIPPING DOCTEST FOR:',obj # dbg |
|
65 | #print 'SKIPPING DOCTEST FOR:',obj # dbg | |
101 | obj = DocTestSkip(obj) |
|
66 | obj = DocTestSkip(obj) | |
102 |
|
67 | |||
103 |
|
|
68 | super()._find(tests, obj, name, module, source_lines, globs, seen) | |
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 |
|
69 | |||
142 |
|
70 | |||
143 | class IPDoctestOutputChecker(doctest.OutputChecker): |
|
71 | class IPDoctestOutputChecker(doctest.OutputChecker): |
General Comments 0
You need to be logged in to leave comments.
Login now