summaryrefslogtreecommitdiffstats
path: root/Modules/arraymodule.c
diff options
context:
space:
mode:
authororenmn <orenmn@gmail.com>2017-03-09 19:29:22 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2017-03-09 19:29:22 (GMT)
commite2c88bdd6bb3efbc81389958d62daf6dd0d6eda7 (patch)
treef97ed0ed5c6110b91ec3aa5c81d9ff2f69090ffb /Modules/arraymodule.c
parent5fad493dc6634635bc6ba951b39b4d1bf552ef84 (diff)
downloadcpython-e2c88bdd6bb3efbc81389958d62daf6dd0d6eda7.zip
cpython-e2c88bdd6bb3efbc81389958d62daf6dd0d6eda7.tar.gz
cpython-e2c88bdd6bb3efbc81389958d62daf6dd0d6eda7.tar.bz2
bpo-28298: make array 'Q', 'L' and 'I' accept big intables as elements
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r--Modules/arraymodule.c108
1 files changed, 62 insertions, 46 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index a4966b4..8612847 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -331,35 +331,51 @@ II_getitem(arrayobject *ap, Py_ssize_t i)
(unsigned long) ((unsigned int *)ap->ob_item)[i]);
}
+static PyObject *
+get_int_unless_float(PyObject *v)
+{
+ if (PyFloat_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "array item must be integer");
+ return NULL;
+ }
+ return (PyObject *)_PyLong_FromNbInt(v);
+}
+
static int
II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
unsigned long x;
- if (PyLong_Check(v)) {
- x = PyLong_AsUnsignedLong(v);
- if (x == (unsigned long) -1 && PyErr_Occurred())
+ int do_decref = 0; /* if nb_int was called */
+
+ if (!PyLong_Check(v)) {
+ v = get_int_unless_float(v);
+ if (NULL == v) {
return -1;
+ }
+ do_decref = 1;
}
- else {
- long y;
- if (!PyArg_Parse(v, "l;array item must be integer", &y))
- return -1;
- if (y < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned int is less than minimum");
- return -1;
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long)-1 && PyErr_Occurred()) {
+ if (do_decref) {
+ Py_DECREF(v);
}
- x = (unsigned long)y;
-
+ return -1;
}
if (x > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
- "unsigned int is greater than maximum");
+ "unsigned int is greater than maximum");
+ if (do_decref) {
+ Py_DECREF(v);
+ }
return -1;
}
-
if (i >= 0)
((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
+
+ if (do_decref) {
+ Py_DECREF(v);
+ }
return 0;
}
@@ -390,31 +406,28 @@ static int
LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
unsigned long x;
- if (PyLong_Check(v)) {
- x = PyLong_AsUnsignedLong(v);
- if (x == (unsigned long) -1 && PyErr_Occurred())
- return -1;
- }
- else {
- long y;
- if (!PyArg_Parse(v, "l;array item must be integer", &y))
- return -1;
- if (y < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned long is less than minimum");
+ int do_decref = 0; /* if nb_int was called */
+
+ if (!PyLong_Check(v)) {
+ v = get_int_unless_float(v);
+ if (NULL == v) {
return -1;
}
- x = (unsigned long)y;
-
+ do_decref = 1;
}
- if (x > ULONG_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned long is greater than maximum");
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long)-1 && PyErr_Occurred()) {
+ if (do_decref) {
+ Py_DECREF(v);
+ }
return -1;
}
-
if (i >= 0)
((unsigned long *)ap->ob_item)[i] = x;
+
+ if (do_decref) {
+ Py_DECREF(v);
+ }
return 0;
}
@@ -448,25 +461,28 @@ static int
QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
unsigned PY_LONG_LONG x;
- if (PyLong_Check(v)) {
- x = PyLong_AsUnsignedLongLong(v);
- if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred())
+ int do_decref = 0; /* if nb_int was called */
+
+ if (!PyLong_Check(v)) {
+ v = get_int_unless_float(v);
+ if (NULL == v) {
return -1;
+ }
+ do_decref = 1;
}
- else {
- PY_LONG_LONG y;
- if (!PyArg_Parse(v, "L;array item must be integer", &y))
- return -1;
- if (y < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned long long is less than minimum");
- return -1;
+ x = PyLong_AsUnsignedLongLong(v);
+ if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) {
+ if (do_decref) {
+ Py_DECREF(v);
}
- x = (unsigned PY_LONG_LONG)y;
+ return -1;
}
-
if (i >= 0)
((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x;
+
+ if (do_decref) {
+ Py_DECREF(v);
+ }
return 0;
}
#endif