Skip to content

Commit 8f068b7

Browse files
committedOct 12, 2014
BUG: Make python2 *.npy files readable in python3.
The Python2 generated file had long integer literals like '1L' that broke in Python3. The fix here is to filter out the 'L' and let safe_eval take care of the integer type in converting the string. The fix here comes from Nathaniel Smith with a few added fixups. Closes numpy#5170.
1 parent 017969b commit 8f068b7

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed
 

‎numpy/lib/format.py

+41-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
import io
142142
import warnings
143143
from numpy.lib.utils import safe_eval
144-
from numpy.compat import asbytes, isfileobj, long, basestring
144+
from numpy.compat import asbytes, asstr, isfileobj, long, basestring
145145

146146
if sys.version_info[0] >= 3:
147147
import pickle
@@ -410,6 +410,45 @@ def read_array_header_2_0(fp):
410410
"""
411411
_read_array_header(fp, version=(2, 0))
412412

413+
414+
def _filter_header(s):
415+
"""Clean up 'L' in npz header ints.
416+
417+
Cleans up the 'L' in strings representing integers. Needed to allow npz
418+
headers produced in Python2 to be read in Python3.
419+
420+
Parameters
421+
----------
422+
s : byte string
423+
Npy file header.
424+
425+
Returns
426+
-------
427+
header : str
428+
Cleaned up header.
429+
430+
"""
431+
import tokenize
432+
if sys.version_info[0] >= 3:
433+
from io import StringIO
434+
else:
435+
from StringIO import StringIO
436+
437+
tokens = []
438+
last_token_was_number = False
439+
for token in tokenize.generate_tokens(StringIO(asstr(s)).read):
440+
token_type = token[0]
441+
token_string = token[1]
442+
if (last_token_was_number and
443+
token_type == tokenize.NAME and
444+
token_string == "L"):
445+
continue
446+
else:
447+
tokens.append(token)
448+
last_token_was_number = (token_type == tokenize.NUMBER)
449+
return tokenize.untokenize(tokens)
450+
451+
413452
def _read_array_header(fp, version):
414453
"""
415454
see read_array_header_1_0
@@ -434,6 +473,7 @@ def _read_array_header(fp, version):
434473
# "shape" : tuple of int
435474
# "fortran_order" : bool
436475
# "descr" : dtype.descr
476+
header = _filter_header(header)
437477
try:
438478
d = safe_eval(header)
439479
except SyntaxError as e:

0 commit comments

Comments
 (0)
Please sign in to comment.