##// END OF EJS Templates
Cleanups, document, working on support for full random tests.
Fernando Perez -
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 in teh first line.
87 if multiline, the random mark is only needed once.
86 88
87 >>> 1+3
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 1:
104 if 0:
97 105 def ranf2():
98 """A function whose examples'output are all to be ignored.
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 return True
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