Skip to content

Commit 2c94aa5

Browse files
committed
Fixed array.fromfile(); removed references to PyFileObject in array.tofile().
Fixed test_array by removing tests that these two functions don't work with cStringIO objects (which makes no sense).
1 parent 6c037ba commit 2c94aa5

File tree

2 files changed

+59
-78
lines changed

2 files changed

+59
-78
lines changed

Lib/test/test_array.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import unittest
77
from test import test_support
88
from weakref import proxy
9-
import array, cStringIO, math
9+
import array, io, math
1010
from pickle import loads, dumps
1111

1212
class ArraySubclass(array.array):
@@ -162,19 +162,13 @@ def test_insert(self):
162162
def test_tofromfile(self):
163163
a = array.array(self.typecode, 2*self.example)
164164
self.assertRaises(TypeError, a.tofile)
165-
##self.assertRaises(TypeError, a.tofile, cStringIO.StringIO())
166165
f = open(test_support.TESTFN, 'wb')
167166
try:
168167
a.tofile(f)
169168
f.close()
170169
b = array.array(self.typecode)
171170
f = open(test_support.TESTFN, 'rb')
172171
self.assertRaises(TypeError, b.fromfile)
173-
self.assertRaises(
174-
TypeError,
175-
b.fromfile,
176-
cStringIO.StringIO(), len(self.example)
177-
)
178172
b.fromfile(f, len(self.example))
179173
self.assertEqual(b, array.array(self.typecode, self.example))
180174
self.assertNotEqual(a, b)

Modules/arraymodule.c

Lines changed: 58 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,53 +1196,54 @@ PyDoc_STRVAR(reverse_doc,
11961196
\n\
11971197
Reverse the order of the items in the array.");
11981198

1199+
1200+
/* Forward */
1201+
static PyObject *array_fromstring(arrayobject *self, PyObject *args);
1202+
11991203
static PyObject *
12001204
array_fromfile(arrayobject *self, PyObject *args)
12011205
{
1202-
PyObject *f;
1203-
Py_ssize_t n;
1204-
FILE *fp;
1206+
PyObject *f, *b, *res;
1207+
Py_ssize_t itemsize = self->ob_descr->itemsize;
1208+
Py_ssize_t n, nbytes;
1209+
12051210
if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
12061211
return NULL;
1207-
fp = PyFile_AsFile(f);
1208-
if (fp == NULL) {
1209-
PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
1212+
1213+
nbytes = n * itemsize;
1214+
if (nbytes < 0 || nbytes/itemsize != n) {
1215+
PyErr_NoMemory();
12101216
return NULL;
12111217
}
1212-
if (n > 0) {
1213-
char *item = self->ob_item;
1214-
Py_ssize_t itemsize = self->ob_descr->itemsize;
1215-
size_t nread;
1216-
Py_ssize_t newlength;
1217-
size_t newbytes;
1218-
/* Be careful here about overflow */
1219-
if ((newlength = self->ob_size + n) <= 0 ||
1220-
(newbytes = newlength * itemsize) / itemsize !=
1221-
(size_t)newlength)
1222-
goto nomem;
1223-
PyMem_RESIZE(item, char, newbytes);
1224-
if (item == NULL) {
1225-
nomem:
1226-
PyErr_NoMemory();
1227-
return NULL;
1228-
}
1229-
self->ob_item = item;
1230-
self->ob_size += n;
1231-
self->allocated = self->ob_size;
1232-
nread = fread(item + (self->ob_size - n) * itemsize,
1233-
itemsize, n, fp);
1234-
if (nread < (size_t)n) {
1235-
self->ob_size -= (n - nread);
1236-
PyMem_RESIZE(item, char, self->ob_size*itemsize);
1237-
self->ob_item = item;
1238-
self->allocated = self->ob_size;
1239-
PyErr_SetString(PyExc_EOFError,
1240-
"not enough items in file");
1241-
return NULL;
1242-
}
1218+
1219+
b = PyObject_CallMethod(f, "read", "n", nbytes);
1220+
if (b == NULL)
1221+
return NULL;
1222+
1223+
if (!PyBytes_Check(b)) {
1224+
PyErr_SetString(PyExc_TypeError,
1225+
"read() didn't return bytes");
1226+
Py_DECREF(b);
1227+
return NULL;
12431228
}
1244-
Py_INCREF(Py_None);
1245-
return Py_None;
1229+
1230+
if (PyBytes_GET_SIZE(b) != nbytes) {
1231+
printf("nbytes = %d, len(b) == %d\n", nbytes, PyBytes_GET_SIZE(b));
1232+
PyErr_SetString(PyExc_EOFError,
1233+
"read() didn't return enough bytes");
1234+
Py_DECREF(b);
1235+
return NULL;
1236+
}
1237+
1238+
args = Py_BuildValue("(O)", b);
1239+
Py_DECREF(b);
1240+
if (args == NULL)
1241+
return NULL;
1242+
1243+
res = array_fromstring(self, args);
1244+
Py_DECREF(args);
1245+
1246+
return res;
12461247
}
12471248

12481249
PyDoc_STRVAR(fromfile_doc,
@@ -1255,42 +1256,29 @@ array. Also called as read.");
12551256
static PyObject *
12561257
array_tofile(arrayobject *self, PyObject *f)
12571258
{
1258-
FILE *fp;
1259+
Py_ssize_t nbytes = self->ob_size * self->ob_descr->itemsize;
1260+
/* Write 64K blocks at a time */
1261+
/* XXX Make the block size settable */
1262+
int BLOCKSIZE = 64*1024;
1263+
Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
1264+
Py_ssize_t i;
12591265

12601266
if (self->ob_size == 0)
12611267
goto done;
12621268

1263-
fp = PyFile_AsFile(f);
1264-
if (fp != NULL) {
1265-
if (fwrite(self->ob_item, self->ob_descr->itemsize,
1266-
self->ob_size, fp) != (size_t)self->ob_size) {
1267-
PyErr_SetFromErrno(PyExc_IOError);
1268-
clearerr(fp);
1269+
for (i = 0; i < nblocks; i++) {
1270+
char* ptr = self->ob_item + i*BLOCKSIZE;
1271+
Py_ssize_t size = BLOCKSIZE;
1272+
PyObject *bytes, *res;
1273+
if (i*BLOCKSIZE + size > nbytes)
1274+
size = nbytes - i*BLOCKSIZE;
1275+
bytes = PyBytes_FromStringAndSize(ptr, size);
1276+
if (bytes == NULL)
1277+
return NULL;
1278+
res = PyObject_CallMethod(f, "write", "O", bytes);
1279+
Py_DECREF(bytes);
1280+
if (res == NULL)
12691281
return NULL;
1270-
}
1271-
}
1272-
else {
1273-
Py_ssize_t nbytes = self->ob_size * self->ob_descr->itemsize;
1274-
/* Write 64K blocks at a time */
1275-
/* XXX Make the block size settable */
1276-
int BLOCKSIZE = 64*1024;
1277-
Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
1278-
Py_ssize_t i;
1279-
for (i = 0; i < nblocks; i++) {
1280-
char* ptr = self->ob_item + i*BLOCKSIZE;
1281-
Py_ssize_t size = BLOCKSIZE;
1282-
PyObject *bytes, *res;
1283-
if (i*BLOCKSIZE + size > nbytes)
1284-
size = nbytes - i*BLOCKSIZE;
1285-
bytes = PyBytes_FromStringAndSize(ptr, size);
1286-
if (bytes == NULL)
1287-
return NULL;
1288-
res = PyObject_CallMethod(f, "write", "O",
1289-
bytes);
1290-
Py_DECREF(bytes);
1291-
if (res == NULL)
1292-
return NULL;
1293-
}
12941282
}
12951283

12961284
done:
@@ -1349,7 +1337,6 @@ PyDoc_STRVAR(fromlist_doc,
13491337
\n\
13501338
Append items to array from list.");
13511339

1352-
13531340
static PyObject *
13541341
array_tolist(arrayobject *self, PyObject *unused)
13551342
{

0 commit comments

Comments
 (0)