Show More
@@ -74,28 +74,36 b' def ipfunc():' | |||
|
74 | 74 | def ranfunc(): |
|
75 | 75 | """A function with some random output. |
|
76 | 76 | |
|
77 | Normal inputs are verified as usual: | |
|
77 | 78 | >>> 1+3 |
|
78 | junk goes here... #random | |
|
79 | 4 | |
|
79 | 80 | |
|
81 | But if you put '# random' in the output, it is ignored: | |
|
80 | 82 | >>> 1+3 |
|
81 | 4 | |
|
83 | junk goes here... # random | |
|
82 | 84 | |
|
83 | 85 | >>> 1+2 |
|
84 | 86 | again, anything goes #random |
|
85 |
if multiline, the random mark is only needed |
|
|
87 | if multiline, the random mark is only needed once. | |
|
86 | 88 | |
|
87 |
>>> 1+ |
|
|
88 | 4 | |
|
89 | >>> 1+2 | |
|
90 | You can also put the random marker at the end: | |
|
91 | # random | |
|
92 | ||
|
93 | >>> 1+2 | |
|
94 | # random | |
|
95 | .. or at the beginning. | |
|
89 | 96 | |
|
97 | More correct input is properly verified: | |
|
90 | 98 | >>> ranfunc() |
|
91 | 99 | 'ranfunc' |
|
92 | 100 | """ |
|
93 | 101 | return 'ranfunc' |
|
94 | 102 | |
|
95 | 103 | |
|
96 |
if |
|
|
104 | if 0: | |
|
97 | 105 | def ranf2(): |
|
98 |
"""A function whose examples'output are |
|
|
106 | """A function whose examples' output are completely ignored. | |
|
99 | 107 | |
|
100 | 108 | Examples: |
|
101 | 109 |
@@ -184,33 +184,24 b' class DocTestFinder(doctest.DocTestFinder):' | |||
|
184 | 184 | module. |
|
185 | 185 | """ |
|
186 | 186 | if module is None: |
|
187 | #print '_fm C1' # dbg | |
|
188 | 187 | return True |
|
189 | 188 | elif inspect.isfunction(object): |
|
190 | #print '_fm C2' # dbg | |
|
191 | 189 | return module.__dict__ is object.func_globals |
|
192 | 190 | elif inspect.isbuiltin(object): |
|
193 | #print '_fm C2-1' # dbg | |
|
194 | 191 | return module.__name__ == object.__module__ |
|
195 | 192 | elif inspect.isclass(object): |
|
196 | #print '_fm C3' # dbg | |
|
197 | 193 | return module.__name__ == object.__module__ |
|
198 | 194 | elif inspect.ismethod(object): |
|
199 | 195 | # This one may be a bug in cython that fails to correctly set the |
|
200 | 196 | # __module__ attribute of methods, but since the same error is easy |
|
201 | 197 | # to make by extension code writers, having this safety in place |
|
202 | 198 | # isn't such a bad idea |
|
203 | #print '_fm C3-1' # dbg | |
|
204 | 199 | return module.__name__ == object.im_class.__module__ |
|
205 | 200 | elif inspect.getmodule(object) is not None: |
|
206 | #print '_fm C4' # dbg | |
|
207 | #print 'C4 mod',module,'obj',object # dbg | |
|
208 | 201 | return module is inspect.getmodule(object) |
|
209 | 202 | elif hasattr(object, '__module__'): |
|
210 | #print '_fm C5' # dbg | |
|
211 | 203 | return module.__name__ == object.__module__ |
|
212 | 204 | elif isinstance(object, property): |
|
213 | #print '_fm C6' # dbg | |
|
214 | 205 | return True # [XX] no way not be sure. |
|
215 | 206 | else: |
|
216 | 207 | raise ValueError("object must be a class or function") |
@@ -263,18 +254,28 b' class DocTestFinder(doctest.DocTestFinder):' | |||
|
263 | 254 | globs, seen) |
|
264 | 255 | |
|
265 | 256 | |
|
266 | # second-chance checker; if the default comparison doesn't | |
|
267 | # pass, then see if the expected output string contains flags that | |
|
268 | # tell us to ignore the output | |
|
269 | 257 | class IPDoctestOutputChecker(doctest.OutputChecker): |
|
258 | """Second-chance checker with support for random tests. | |
|
259 | ||
|
260 | If the default comparison doesn't pass, this checker looks in the expected | |
|
261 | output string for flags that tell us to ignore the output. | |
|
262 | """ | |
|
263 | ||
|
264 | random_re = re.compile(r'#\s*random') | |
|
265 | ||
|
270 | 266 | def check_output(self, want, got, optionflags): |
|
271 | #print '*** My Checker!' # dbg | |
|
267 | """Check output, accepting special markers embedded in the output. | |
|
272 | 268 |
|
|
269 | If the output didn't pass the default validation but the special string | |
|
270 | '#random' is included, we accept it.""" | |
|
271 | ||
|
272 | # Let the original tester verify first, in case people have valid tests | |
|
273 | # that happen to have a comment saying '#random' embedded in. | |
|
273 | 274 | ret = doctest.OutputChecker.check_output(self, want, got, |
|
274 | 275 | optionflags) |
|
275 | if not ret: | |
|
276 | if "#random" in want: | |
|
277 |
|
|
|
276 | if not ret and self.random_re.search(want): | |
|
277 | #print >> sys.stderr, 'RANDOM OK:',want # dbg | |
|
278 | return True | |
|
278 | 279 | |
|
279 | 280 | return ret |
|
280 | 281 | |
@@ -405,6 +406,8 b' class IPDocTestParser(doctest.DocTestParser):' | |||
|
405 | 406 | _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP), |
|
406 | 407 | re.MULTILINE | re.VERBOSE) |
|
407 | 408 | |
|
409 | _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL') | |
|
410 | ||
|
408 | 411 | def ip2py(self,source): |
|
409 | 412 | """Convert input IPython source into valid Python.""" |
|
410 | 413 | out = [] |
@@ -452,7 +455,7 b' class IPDocTestParser(doctest.DocTestParser):' | |||
|
452 | 455 | # IPExternalExamples are run out-of-process (via pexpect) so they |
|
453 | 456 | # don't need any filtering (a real ipython will be executing them). |
|
454 | 457 | terms = list(self._EXAMPLE_RE_IP.finditer(string)) |
|
455 | if re.search(r'#\s*ipdoctest:\s*EXTERNAL',string): | |
|
458 | if self._EXTERNAL_IP.search(string): | |
|
456 | 459 | #print '-'*70 # dbg |
|
457 | 460 | #print 'IPExternalExample, Source:\n',string # dbg |
|
458 | 461 | #print '-'*70 # dbg |
General Comments 0
You need to be logged in to leave comments.
Login now