Show More
@@ -80,18 +80,6 b' class IPDoctestOutputChecker(doctest.OutputChecker):' | |||||
80 | class IPExample(doctest.Example): pass |
|
80 | class IPExample(doctest.Example): pass | |
81 |
|
81 | |||
82 |
|
82 | |||
83 | class IPExternalExample(doctest.Example): |
|
|||
84 | """Doctest examples to be run in an external process.""" |
|
|||
85 |
|
||||
86 | def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, |
|
|||
87 | options=None): |
|
|||
88 | # Parent constructor |
|
|||
89 | doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options) |
|
|||
90 |
|
||||
91 | # An EXTRA newline is needed to prevent pexpect hangs |
|
|||
92 | self.source += '\n' |
|
|||
93 |
|
||||
94 |
|
||||
95 | class IPDocTestParser(doctest.DocTestParser): |
|
83 | class IPDocTestParser(doctest.DocTestParser): | |
96 | """ |
|
84 | """ | |
97 | A class used to parse strings containing doctest examples. |
|
85 | A class used to parse strings containing doctest examples. | |
@@ -137,9 +125,6 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
137 | # we don't need to modify any other code. |
|
125 | # we don't need to modify any other code. | |
138 | _RANDOM_TEST = re.compile(r'#\s*all-random\s+') |
|
126 | _RANDOM_TEST = re.compile(r'#\s*all-random\s+') | |
139 |
|
127 | |||
140 | # Mark tests to be executed in an external process - currently unsupported. |
|
|||
141 | _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL') |
|
|||
142 |
|
||||
143 | def ip2py(self,source): |
|
128 | def ip2py(self,source): | |
144 | """Convert input IPython source into valid Python.""" |
|
129 | """Convert input IPython source into valid Python.""" | |
145 | block = _ip.input_transformer_manager.transform_cell(source) |
|
130 | block = _ip.input_transformer_manager.transform_cell(source) | |
@@ -182,25 +167,10 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
182 | terms = list(self._EXAMPLE_RE_PY.finditer(string)) |
|
167 | terms = list(self._EXAMPLE_RE_PY.finditer(string)) | |
183 | if terms: |
|
168 | if terms: | |
184 | # Normal Python example |
|
169 | # Normal Python example | |
185 | #print '-'*70 # dbg |
|
|||
186 | #print 'PyExample, Source:\n',string # dbg |
|
|||
187 | #print '-'*70 # dbg |
|
|||
188 | Example = doctest.Example |
|
170 | Example = doctest.Example | |
189 | else: |
|
171 | else: | |
190 |
# It's an ipython example. |
|
172 | # It's an ipython example. | |
191 | # in-process, so their syntax must be turned into valid python. |
|
|||
192 | # IPExternalExamples are run out-of-process (via pexpect) so they |
|
|||
193 | # don't need any filtering (a real ipython will be executing them). |
|
|||
194 | terms = list(self._EXAMPLE_RE_IP.finditer(string)) |
|
173 | terms = list(self._EXAMPLE_RE_IP.finditer(string)) | |
195 | if self._EXTERNAL_IP.search(string): |
|
|||
196 | #print '-'*70 # dbg |
|
|||
197 | #print 'IPExternalExample, Source:\n',string # dbg |
|
|||
198 | #print '-'*70 # dbg |
|
|||
199 | Example = IPExternalExample |
|
|||
200 | else: |
|
|||
201 | #print '-'*70 # dbg |
|
|||
202 | #print 'IPExample, Source:\n',string # dbg |
|
|||
203 | #print '-'*70 # dbg |
|
|||
204 |
|
|
174 | Example = IPExample | |
205 |
|
|
175 | ip2py = True | |
206 |
|
176 | |||
@@ -217,10 +187,6 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
217 | # cases, it's only non-empty for 'all-random' tests): |
|
187 | # cases, it's only non-empty for 'all-random' tests): | |
218 | want += random_marker |
|
188 | want += random_marker | |
219 |
|
189 | |||
220 | if Example is IPExternalExample: |
|
|||
221 | options[doctest.NORMALIZE_WHITESPACE] = True |
|
|||
222 | want += '\n' |
|
|||
223 |
|
||||
224 | # Create an Example, and add it to the list. |
|
190 | # Create an Example, and add it to the list. | |
225 | if not self._IS_BLANK_OR_COMMENT(source): |
|
191 | if not self._IS_BLANK_OR_COMMENT(source): | |
226 | output.append(Example(source, want, exc_msg, |
|
192 | output.append(Example(source, want, exc_msg, | |
@@ -328,18 +294,6 b' class IPDocTestRunner(doctest.DocTestRunner,object):' | |||||
328 | """ |
|
294 | """ | |
329 |
|
295 | |||
330 | def run(self, test, compileflags=None, out=None, clear_globs=True): |
|
296 | def run(self, test, compileflags=None, out=None, clear_globs=True): | |
331 |
|
||||
332 | # Hack: ipython needs access to the execution context of the example, |
|
|||
333 | # so that it can propagate user variables loaded by %run into |
|
|||
334 | # test.globs. We put them here into our modified %run as a function |
|
|||
335 | # attribute. Our new %run will then only make the namespace update |
|
|||
336 | # when called (rather than unconditionally updating test.globs here |
|
|||
337 | # for all examples, most of which won't be calling %run anyway). |
|
|||
338 | #_ip._ipdoctest_test_globs = test.globs |
|
|||
339 | #_ip._ipdoctest_test_filename = test.filename |
|
|||
340 |
|
||||
341 | test.globs.update(_ip.user_ns) |
|
|||
342 |
|
||||
343 | # Override terminal size to standardise traceback format |
|
297 | # Override terminal size to standardise traceback format | |
344 | with modified_env({'COLUMNS': '80', 'LINES': '24'}): |
|
298 | with modified_env({'COLUMNS': '80', 'LINES': '24'}): | |
345 | return super(IPDocTestRunner,self).run(test, |
|
299 | return super(IPDocTestRunner,self).run(test, |
@@ -1,7 +1,7 b'' | |||||
1 | """Simple example using doctests. |
|
1 | """Simple example using doctests. | |
2 |
|
2 | |||
3 | This file just contains doctests both using plain python and IPython prompts. |
|
3 | This file just contains doctests both using plain python and IPython prompts. | |
4 |
All tests should be loaded by |
|
4 | All tests should be loaded by Pytest. | |
5 | """ |
|
5 | """ | |
6 |
|
6 | |||
7 | def pyfunc(): |
|
7 | def pyfunc(): | |
@@ -24,10 +24,21 b' def pyfunc():' | |||||
24 | return 'pyfunc' |
|
24 | return 'pyfunc' | |
25 |
|
25 | |||
26 |
|
26 | |||
27 |
def ipyfunc |
|
27 | def ipyfunc(): | |
28 |
"""Some |
|
28 | """Some IPython tests... | |
|
29 | ||||
|
30 | In [1]: ipyfunc() | |||
|
31 | Out[1]: 'ipyfunc' | |||
|
32 | ||||
|
33 | In [2]: import os | |||
|
34 | ||||
|
35 | In [3]: 2+3 | |||
|
36 | Out[3]: 5 | |||
29 |
|
37 | |||
30 | >>> 1+1 |
|
38 | In [4]: for i in range(3): | |
31 | 2 |
|
39 | ...: print(i, end=' ') | |
|
40 | ...: print(i+1, end=' ') | |||
|
41 | ...: | |||
|
42 | Out[4]: 0 1 1 2 2 3 | |||
32 | """ |
|
43 | """ | |
33 |
return |
|
44 | return "ipyfunc" |
General Comments 0
You need to be logged in to leave comments.
Login now