[pypy-commit] pypy numpy-full-fromstring: Wrote some really ugly code to deal with all the corner cases of numpy fromstring error handling
jterrace
noreply at buildbot.pypy.org
Tue Dec 13 21:51:22 CET 2011
Author: Jeff Terrace <jterrace at gmail.com>
Branch: numpy-full-fromstring
Changeset: r50475:8c97ceda4c34
Date: 2011-12-13 15:51 -0500
http://bitbucket.org/pypy/pypy/changeset/8c97ceda4c34/
Log: Wrote some really ugly code to deal with all the corner cases of
numpy fromstring error handling
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -2,14 +2,17 @@
from pypy.interpreter.gateway import unwrap_spec
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.module.micronumpy import interp_dtype
+from pypy.objspace.std.strutil import strip_spaces
FLOAT_SIZE = rffi.sizeof(lltype.Float)
def _fromstring_text(space, s, count, sep, length, dtype):
- import string
from pypy.module.micronumpy.interp_numarray import W_NDimArray
+ sep_stripped = strip_spaces(sep)
+ skip_bad_vals = True if len(sep_stripped) == 0 else False
+
A = []
num_items = 0
ptr = 0
@@ -18,10 +21,28 @@
nextptr = s.find(sep, ptr)
if nextptr < 0:
nextptr = length
- piece = s[ptr:nextptr]
- #FIXME: need to check piece.isspace() also, but does not translate
- if len(piece) > 0:
- val = dtype.coerce(space, space.wrap(piece))
+ piece = strip_spaces(s[ptr:nextptr])
+ if len(piece) > 0 or not skip_bad_vals:
+ if len(piece) == 0 and not skip_bad_vals:
+ val = dtype.itemtype.default_fromstring(space)
+ else:
+ try:
+ val = dtype.coerce(space, space.wrap(piece))
+ except OperationError, e:
+ if not e.match(space, space.w_ValueError):
+ raise
+ gotit = False
+ while not gotit and len(piece) > 0:
+ piece = piece[:-1]
+ try:
+ val = dtype.coerce(space, space.wrap(piece))
+ gotit = True
+ except OperationError, e:
+ if not e.match(space, space.w_ValueError):
+ raise
+ if not gotit:
+ val = dtype.itemtype.default_fromstring(space)
+ nextptr = length
A.append(val)
num_items += 1
ptr = nextptr + 1
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1173,7 +1173,7 @@
cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4))
def test_fromstring(self):
- from numpypy import fromstring, uint8, float32, int32
+ from numpypy import fromstring, array, uint8, float32, int32
a = fromstring(self.data)
for i in range(4):
assert a[i] == i + 1
@@ -1201,12 +1201,28 @@
assert g[0] == 1
assert g[1] == 2
assert g[2] == 3
- #FIXME: below should work
- #h = fromstring("1, , 2, 3", dtype=uint8, sep=",")
- #assert len(h) == 3
- #assert h[0] == 1
- #assert h[1] == 2
- #assert h[2] == 3
+ h = fromstring("1, , 2, 3", dtype=uint8, sep=",")
+ assert h.tolist() == [1,0,2,3]
+ i = fromstring("1 2 3", dtype=uint8, sep=" ")
+ assert i.tolist() == [1,2,3]
+ j = fromstring("1\t\t\t\t2\t3", dtype=uint8, sep="\t")
+ assert j.tolist() == [1,2,3]
+ k = fromstring("1,x,2,3", dtype=uint8, sep=",")
+ assert k.tolist() == [1,0]
+ l = fromstring("1,x,2,3", dtype='float32', sep=",")
+ assert l.tolist() == [1.0,-1.0]
+ m = fromstring("1,,2,3", sep=",")
+ assert m.tolist() == [1.0,-1.0,2.0,3.0]
+ n = fromstring("3.4 2.0 3.8 2.2", dtype=int32, sep=" ")
+ assert n.tolist() == [3]
+ o = fromstring("1.0 2f.0f 3.8 2.2", dtype=float32, sep=" ")
+ assert len(o) == 2
+ assert o[0] == 1.0
+ assert o[1] == 2.0
+ p = fromstring("1.0,,2.0,3.0", sep=",")
+ assert p.tolist() == [1.0, -1.0, 2.0, 3.0]
+ q = fromstring("1.0,,2.0,3.0", sep=" ")
+ assert q.tolist() == [1.0]
def test_fromstring_types(self):
from numpypy import fromstring
@@ -1241,8 +1257,6 @@
raises(ValueError, fromstring, "\x01\x03\x03", dtype=uint16)
#5 bytes is larger than 3 bytes
raises(ValueError, fromstring, "\x01\x02\x03", count=5, dtype=uint8)
- #can't cast floats to ints with fromstring
- raises(ValueError, fromstring, "3.4 2.0 3.8 2.2", dtype=int32, sep=" ")
class AppTestRepr(BaseNumpyAppTest):
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -87,6 +87,9 @@
def _coerce(self, space, w_item):
raise NotImplementedError
+ def default_fromstring(self, space):
+ raise NotImplementedError
+
def read(self, storage, width, i, offset):
return self.box(libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
width, storage, i, offset
@@ -213,6 +216,9 @@
def for_computation(self, v):
return widen(v)
+
+ def default_fromstring(self, space):
+ return self._coerce(space, space.wrap(0))
@simple_binary_op
def div(self, v1, v2):
@@ -320,6 +326,9 @@
def for_computation(self, v):
return float(v)
+ def default_fromstring(self, space):
+ return self._coerce(space, space.wrap(-1.0))
+
@simple_binary_op
def div(self, v1, v2):
try:
More information about the pypy-commit
mailing list