mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
arraymodule: Fix SF bug 113960.
reverse() didn't work at all due to bad arg check. Fixed that. Added Brad Chapman to ACKS file, as the proud new owner of two implicitly copyrighted lines of Python source code <wink>. Repaired buffer_info's total lack of arg-checking. Replaced memmove by memcpy in reverse() guts, as memmove is often slower and the memory areas are guaranteed disjoint. Replaced poke-and-hope unchecked decl of tmp buffer size by assert-checked larger tmp buffer. Got rid of inconsistent spaces before open paren in docstrings. Added reverse() sanity tests to test_array.py.
This commit is contained in:
parent
64850efa39
commit
077a11dd00
3 changed files with 36 additions and 20 deletions
|
@ -122,9 +122,14 @@ def testtype(type, example):
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
x = a.pop()
|
||||||
|
if x != 'e':
|
||||||
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
if a != array.array(type, "acd"):
|
if a != array.array(type, "acd"):
|
||||||
raise TestFailed, "array(%s) pop-test" % `type`
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
|
a.reverse()
|
||||||
|
if a != array.array(type, "dca"):
|
||||||
|
raise TestFailed, "array(%s) reverse-test" % `type`
|
||||||
else:
|
else:
|
||||||
a = array.array(type, [1, 2, 3, 4, 5])
|
a = array.array(type, [1, 2, 3, 4, 5])
|
||||||
a[:-1] = a
|
a[:-1] = a
|
||||||
|
@ -155,9 +160,14 @@ def testtype(type, example):
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
x = a.pop()
|
||||||
|
if x != 5:
|
||||||
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
if a != array.array(type, [1, 3, 4]):
|
if a != array.array(type, [1, 3, 4]):
|
||||||
raise TestFailed, "array(%s) pop-test" % `type`
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
|
a.reverse()
|
||||||
|
if a != array.array(type, [4, 3, 1]):
|
||||||
|
raise TestFailed, "array(%s) reverse-test" % `type`
|
||||||
|
|
||||||
# test that overflow exceptions are raised as expected for assignment
|
# test that overflow exceptions are raised as expected for assignment
|
||||||
# to array of specific integral types
|
# to array of specific integral types
|
||||||
|
|
|
@ -58,6 +58,7 @@ Mike Carlton
|
||||||
Donn Cave
|
Donn Cave
|
||||||
Per Cederqvist
|
Per Cederqvist
|
||||||
Jeffrey Chang
|
Jeffrey Chang
|
||||||
|
Brad Chapman
|
||||||
Mitch Chapman
|
Mitch Chapman
|
||||||
David Chaum
|
David Chaum
|
||||||
Nicolas Chauvat
|
Nicolas Chauvat
|
||||||
|
|
|
@ -328,7 +328,6 @@ static struct arraydescr descriptors[] = {
|
||||||
{'d', sizeof(double), d_getitem, d_setitem},
|
{'d', sizeof(double), d_getitem, d_setitem},
|
||||||
{'\0', 0, 0, 0} /* Sentinel */
|
{'\0', 0, 0, 0} /* Sentinel */
|
||||||
};
|
};
|
||||||
/* If we ever allow items larger than double, we must change reverse()! */
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Implementations of array object methods.
|
Implementations of array object methods.
|
||||||
|
@ -650,7 +649,7 @@ array_count(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char count_doc [] =
|
static char count_doc [] =
|
||||||
"count (x)\n\
|
"count(x)\n\
|
||||||
\n\
|
\n\
|
||||||
Return number of occurences of x in the array.";
|
Return number of occurences of x in the array.";
|
||||||
|
|
||||||
|
@ -677,7 +676,7 @@ array_index(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char index_doc [] =
|
static char index_doc [] =
|
||||||
"index (x)\n\
|
"index(x)\n\
|
||||||
\n\
|
\n\
|
||||||
Return index of first occurence of x in the array.";
|
Return index of first occurence of x in the array.";
|
||||||
|
|
||||||
|
@ -708,7 +707,7 @@ array_remove(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char remove_doc [] =
|
static char remove_doc [] =
|
||||||
"remove (x)\n\
|
"remove(x)\n\
|
||||||
\n\
|
\n\
|
||||||
Remove the first occurence of x in the array.";
|
Remove the first occurence of x in the array.";
|
||||||
|
|
||||||
|
@ -739,7 +738,7 @@ array_pop(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char pop_doc [] =
|
static char pop_doc [] =
|
||||||
"pop ([i])\n\
|
"pop([i])\n\
|
||||||
\n\
|
\n\
|
||||||
Return the i-th element and delete it from the array. i defaults to -1.";
|
Return the i-th element and delete it from the array. i defaults to -1.";
|
||||||
|
|
||||||
|
@ -794,7 +793,7 @@ array_insert(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char insert_doc [] =
|
static char insert_doc [] =
|
||||||
"insert (i,x)\n\
|
"insert(i,x)\n\
|
||||||
\n\
|
\n\
|
||||||
Insert a new item x into the array before position i.";
|
Insert a new item x into the array before position i.";
|
||||||
|
|
||||||
|
@ -802,8 +801,12 @@ Insert a new item x into the array before position i.";
|
||||||
static PyObject *
|
static PyObject *
|
||||||
array_buffer_info(arrayobject *self, PyObject *args)
|
array_buffer_info(arrayobject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject* retval = PyTuple_New(2);
|
PyObject* retval = NULL;
|
||||||
if (!retval) return NULL;
|
if (!PyArg_ParseTuple(args, ":buffer_info"))
|
||||||
|
return NULL;
|
||||||
|
retval = PyTuple_New(2);
|
||||||
|
if (!retval)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
|
PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
|
||||||
PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
|
PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
|
||||||
|
@ -812,7 +815,7 @@ array_buffer_info(arrayobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char buffer_info_doc [] =
|
static char buffer_info_doc [] =
|
||||||
"buffer_info -> (address, length)\n\
|
"buffer_info() -> (address, length)\n\
|
||||||
\n\
|
\n\
|
||||||
Return a tuple (address, length) giving the current memory address and\n\
|
Return a tuple (address, length) giving the current memory address and\n\
|
||||||
the length in bytes of the buffer used to hold array's contents.";
|
the length in bytes of the buffer used to hold array's contents.";
|
||||||
|
@ -898,22 +901,24 @@ array_reverse(arrayobject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
register int itemsize = self->ob_descr->itemsize;
|
register int itemsize = self->ob_descr->itemsize;
|
||||||
register char *p, *q;
|
register char *p, *q;
|
||||||
char tmp[sizeof(double)]; /* Assume that's the max item size */
|
/* little buffer to hold items while swapping */
|
||||||
|
char tmp[256]; /* 8 is probably enough -- but why skimp */
|
||||||
|
assert(itemsize <= sizeof(tmp));
|
||||||
|
|
||||||
if (args != NULL) {
|
if (!PyArg_ParseTuple(args, ":reverse"))
|
||||||
PyErr_SetString(PyExc_TypeError,
|
return NULL;
|
||||||
"<array>.reverse requires exactly 0 arguments");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->ob_size > 1) {
|
if (self->ob_size > 1) {
|
||||||
for (p = self->ob_item,
|
for (p = self->ob_item,
|
||||||
q = self->ob_item + (self->ob_size - 1)*itemsize;
|
q = self->ob_item + (self->ob_size - 1)*itemsize;
|
||||||
p < q;
|
p < q;
|
||||||
p += itemsize, q -= itemsize) {
|
p += itemsize, q -= itemsize) {
|
||||||
memmove(tmp, p, itemsize);
|
/* memory areas guaranteed disjoint, so memcpy
|
||||||
memmove(p, q, itemsize);
|
* is safe (& memmove may be slower).
|
||||||
memmove(q, tmp, itemsize);
|
*/
|
||||||
|
memcpy(tmp, p, itemsize);
|
||||||
|
memcpy(p, q, itemsize);
|
||||||
|
memcpy(q, tmp, itemsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue