Skip to content

Commit f105911

Browse files
committed
NF - add doctest search replace and markup parser
1 parent f9964a6 commit f105911

File tree

4 files changed

+140
-17
lines changed

4 files changed

+140
-17
lines changed

nibabel/analyze.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@
141141
array_to_file, array_from_file, can_cast, \
142142
floating_point_types
143143

144-
from .spatialimages import HeaderDataError, HeaderTypeError, \
145-
ImageDataError, SpatialImage
144+
from .spatialimages import (HeaderDataError, HeaderTypeError,
145+
ImageDataError, SpatialImage)
146146

147147
from . import imageglobals as imageglobals
148148
from .fileholders import FileHolderError, copy_file_map
@@ -395,10 +395,10 @@ def from_fileobj(klass, fileobj, endianness=None, check=True):
395395
396396
Examples
397397
--------
398-
>>> import StringIO
398+
>>> from StringIO import StringIO as BytesIO
399399
>>> hdr = AnalyzeHeader()
400-
>>> fileobj = StringIO.StringIO(hdr.binaryblock)
401-
>>> fileobj.seek(0)
400+
>>> fileobj = BytesIO(hdr.binaryblock)
401+
>>> _ = fileobj.seek(0) # returns 0 in python 3
402402
>>> hdr2 = AnalyzeHeader.from_fileobj(fileobj)
403403
>>> hdr2.binaryblock == hdr.binaryblock
404404
True
@@ -445,8 +445,8 @@ def write_to(self, fileobj):
445445
Examples
446446
--------
447447
>>> hdr = AnalyzeHeader()
448-
>>> import StringIO
449-
>>> str_io = StringIO.StringIO()
448+
>>> from StringIO import StringIO as BytesIO
449+
>>> str_io = BytesIO()
450450
>>> hdr.write_to(str_io)
451451
>>> hdr.binaryblock == str_io.getvalue()
452452
True
@@ -612,8 +612,8 @@ def data_to_fileobj(self, data, fileobj):
612612
>>> hdr = AnalyzeHeader()
613613
>>> hdr.set_data_shape((1, 2, 3))
614614
>>> hdr.set_data_dtype(np.float64)
615-
>>> from StringIO import StringIO
616-
>>> str_io = StringIO()
615+
>>> from StringIO import StringIO as BytesIO
616+
>>> str_io = BytesIO()
617617
>>> data = np.arange(6).reshape(1,2,3)
618618
>>> hdr.data_to_fileobj(data, str_io)
619619
>>> data.astype(np.float64).tostring('F') == str_io.getvalue()
@@ -655,7 +655,7 @@ def __setitem__(self, item, value):
655655
--------
656656
>>> hdr = AnalyzeHeader()
657657
>>> hdr['descrip'] = 'description'
658-
>>> str(hdr['descrip'])
658+
>>> np.asscalar(hdr['descrip']) #23: bytes
659659
'description'
660660
'''
661661
self._header_data[item] = value

nibabel/trackvis.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,26 +237,26 @@ def write(fileobj, streamlines, hdr_mapping=None, endianness=None):
237237
238238
Examples
239239
--------
240-
>>> from StringIO import StringIO
241-
>>> file_obj = StringIO()
240+
>>> from StringIO import StringIO as BytesIO
241+
>>> file_obj = BytesIO()
242242
>>> pts0 = np.random.uniform(size=(10,3))
243243
>>> pts1 = np.random.uniform(size=(10,3))
244244
>>> streamlines = ([(pts0, None, None), (pts1, None, None)])
245245
>>> write(file_obj, streamlines)
246-
>>> file_obj.seek(0)
246+
>>> _ = file_obj.seek(0) # returns 0 in python 3
247247
>>> streams, hdr = read(file_obj)
248248
>>> len(streams)
249249
2
250250
251251
If there are too many streamlines to fit in memory, you can pass an iterable
252252
thing instead of a list
253253
254-
>>> file_obj = StringIO()
254+
>>> file_obj = BytesIO()
255255
>>> def gen():
256256
... yield (pts0, None, None)
257257
... yield (pts0, None, None)
258258
>>> write(file_obj, gen())
259-
>>> file_obj.seek(0)
259+
>>> _ = file_obj.seek(0)
260260
>>> streams, hdr = read(file_obj)
261261
>>> len(streams)
262262
2
@@ -387,8 +387,8 @@ def empty_header(endianness=None, version=2):
387387
>>> hdr = empty_header()
388388
>>> print hdr['version']
389389
2
390-
>>> print hdr['id_string']
391-
TRACK
390+
>>> np.asscalar(hdr['id_string']) #23: bytes
391+
'TRACK'
392392
>>> endian_codes[hdr['version'].dtype.byteorder] == native_code
393393
True
394394
>>> hdr = empty_header(swapped_code)

nisext/py3builder.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
""" distutils utilities for porting to python 3 within 2-compatible tree """
22

3+
from __future__ import with_statement
4+
import re
5+
36
try:
47
from distutils.command.build_py import build_py_2to3
58
except ImportError:
@@ -35,4 +38,96 @@ def log_debug(self, msg, *args):
3538
r.refactor(files, write=True)
3639
# Then doctests
3740
r.refactor(files, write=True, doctests_only=True)
41+
# Then custom doctests markup
42+
doctest_markup_files(files)
43+
44+
45+
def doctest_markup_files(fnames):
46+
""" Process simple doctest comment markup on sequence of filenames
47+
48+
Parameters
49+
----------
50+
fnames : seq
51+
sequence of filenames
52+
53+
Returns
54+
-------
55+
None
56+
"""
57+
for fname in fnames:
58+
with open(fname, 'rt') as fobj:
59+
res = list(fobj)
60+
out = doctest_markup(res)
61+
with open(fname, 'wt') as fobj:
62+
fobj.write(''.join(out))
63+
64+
65+
REGGIES = (
66+
(re.compile('from\s+io\s+import\s+StringIO\s+as\s+BytesIO\s*?(?=$)'),
67+
'from io import BytesIO'),
68+
)
69+
70+
MARK_COMMENT = re.compile('#23:\s*(.*?)\s*$')
71+
FIRST_NW = re.compile('(\s*)(\S.*)', re.DOTALL)
72+
73+
def doctest_markup(lines):
74+
""" Process doctest comment markup on sequence of strings
75+
76+
The markup is very crude. The algorithm looks for lines starting with
77+
``>>>``. All other lines are passed through unchanged.
78+
79+
Next it looks for known simple search replaces and does those.
80+
81+
* ``from StringIO import StringIO as BytesIO`` replaced by ``from io import
82+
BytesIO``.
83+
* ``from StringIO import StringIO`` replaced by ``from io import StringIO``.
84+
85+
Next it looks to see if the line ends with a comment starting with ``#23:``.
86+
87+
* ``bytes`` : prepend 'b' to next output line; for when you want to show
88+
output of bytes type in python 3
89+
90+
Parameters
91+
----------
92+
lines : sequence of str
93+
94+
Returns
95+
-------
96+
newlines : sequence of str
97+
"""
98+
newlines = []
99+
lines = iter(lines)
100+
while(True):
101+
try:
102+
line = next(lines)
103+
except StopIteration:
104+
break
105+
if not line.lstrip().startswith('>>>'):
106+
newlines.append(line)
107+
continue
108+
# Check simple regexps (no markup)
109+
for reg, substr in REGGIES:
110+
if reg.search(line):
111+
line = reg.sub(substr, line)
112+
break
113+
# Check for specific markup
114+
mark_match = MARK_COMMENT.search(line)
115+
if mark_match is None:
116+
newlines.append(line)
117+
continue
118+
markup = mark_match.groups()[0]
119+
# Actually we don't know what to do with markup yet
120+
if markup == 'bytes':
121+
newlines.append(line)
122+
try:
123+
line = next(lines)
124+
except StopIteration:
125+
break
126+
match = FIRST_NW.match(line)
127+
if match:
128+
line = '%sb%s' % match.groups()
129+
newlines.append(line)
130+
else:
131+
newlines.append(line)
132+
return newlines
38133

nisext/tests/test_doctest_markup.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
""" Testing doctest markup tests
2+
"""
3+
4+
from ..py3builder import doctest_markup
5+
6+
from numpy.testing import (assert_array_almost_equal,
7+
assert_array_equal)
8+
9+
from nose.tools import assert_true, assert_equal, assert_raises
10+
11+
12+
def test_search_replace():
13+
# Test search and replace regexps
14+
assert_equal(['any string'], doctest_markup(['any string']))
15+
line = 'from io import StringIO as BytesIO'
16+
assert_equal([line], doctest_markup([line]))
17+
line = '>>> ' + line
18+
assert_equal(['>>> from io import BytesIO'], doctest_markup([line]))
19+
line = line + ' '
20+
assert_equal(['>>> from io import BytesIO'], doctest_markup([line]))
21+
line = line + '\n'
22+
assert_equal(['>>> from io import BytesIO\n'], doctest_markup([line]))
23+
# Bytes output
24+
assert_equal(['any', ' some'], doctest_markup(['any', ' some']))
25+
assert_equal(['any #23: bytes', ' some'],
26+
doctest_markup(['any #23: bytes', ' some']))
27+
assert_equal([' >>> any #23: bytes \n', ' bsome \n'],
28+
doctest_markup([' >>> any #23: bytes \n', ' some \n']))

0 commit comments

Comments
 (0)