summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Fedoseev <fedoseev.sergey@gmail.com>2019-02-25 16:59:12 (GMT)
committerVictor Stinner <vstinner@redhat.com>2019-02-25 16:59:12 (GMT)
commit234531b4462b20d668762bd78406fd2ebab129c9 (patch)
treef0a93cbdf6ebf42055498ea9533891cec0680bcf
parent55e335d7d59be44819c6b672d258e2d5feb1e633 (diff)
downloadcpython-234531b4462b20d668762bd78406fd2ebab129c9.zip
cpython-234531b4462b20d668762bd78406fd2ebab129c9.tar.gz
cpython-234531b4462b20d668762bd78406fd2ebab129c9.tar.bz2
bpo-36030: Add _PyTuple_FromArray() function (GH-11954)
-rw-r--r--Include/internal/pycore_tupleobject.h1
-rw-r--r--Modules/itertoolsmodule.c29
-rw-r--r--Objects/call.c30
-rw-r--r--Objects/listobject.c18
-rw-r--r--Objects/structseq.c10
-rw-r--r--Objects/tupleobject.c33
-rw-r--r--Python/ceval.c7
7 files changed, 31 insertions, 97 deletions
diff --git a/Include/internal/pycore_tupleobject.h b/Include/internal/pycore_tupleobject.h
index fdd7414..d0c5b62 100644
--- a/Include/internal/pycore_tupleobject.h
+++ b/Include/internal/pycore_tupleobject.h
@@ -11,6 +11,7 @@ extern "C" {
#include "tupleobject.h"
#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item)
+PyAPI_FUNC(PyObject *) _PyTuple_FromArray(PyObject *const *, Py_ssize_t);
#ifdef __cplusplus
}
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index c589dd1..536f7fa 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -1,6 +1,7 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
+#include "pycore_tupleobject.h"
#include "structmember.h"
/* Itertools module written and maintained
@@ -2239,15 +2240,10 @@ product_next(productobject *lz)
/* Copy the previous result tuple or re-use it if available */
if (Py_REFCNT(result) > 1) {
PyObject *old_result = result;
- result = PyTuple_New(npools);
+ result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools);
if (result == NULL)
goto empty;
lz->result = result;
- for (i=0; i < npools; i++) {
- elem = PyTuple_GET_ITEM(old_result, i);
- Py_INCREF(elem);
- PyTuple_SET_ITEM(result, i, elem);
- }
Py_DECREF(old_result);
}
/* Now, we've got the only copy so we can update it in-place */
@@ -2569,15 +2565,10 @@ combinations_next(combinationsobject *co)
/* Copy the previous result tuple or re-use it if available */
if (Py_REFCNT(result) > 1) {
PyObject *old_result = result;
- result = PyTuple_New(r);
+ result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
if (result == NULL)
goto empty;
co->result = result;
- for (i=0; i<r ; i++) {
- elem = PyTuple_GET_ITEM(old_result, i);
- Py_INCREF(elem);
- PyTuple_SET_ITEM(result, i, elem);
- }
Py_DECREF(old_result);
}
/* Now, we've got the only copy so we can update it in-place
@@ -2910,15 +2901,10 @@ cwr_next(cwrobject *co)
/* Copy the previous result tuple or re-use it if available */
if (Py_REFCNT(result) > 1) {
PyObject *old_result = result;
- result = PyTuple_New(r);
+ result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
if (result == NULL)
goto empty;
co->result = result;
- for (i=0; i<r ; i++) {
- elem = PyTuple_GET_ITEM(old_result, i);
- Py_INCREF(elem);
- PyTuple_SET_ITEM(result, i, elem);
- }
Py_DECREF(old_result);
}
/* Now, we've got the only copy so we can update it in-place CPython's
@@ -3258,15 +3244,10 @@ permutations_next(permutationsobject *po)
/* Copy the previous result tuple or re-use it if available */
if (Py_REFCNT(result) > 1) {
PyObject *old_result = result;
- result = PyTuple_New(r);
+ result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
if (result == NULL)
goto empty;
po->result = result;
- for (i=0; i<r ; i++) {
- elem = PyTuple_GET_ITEM(old_result, i);
- Py_INCREF(elem);
- PyTuple_SET_ITEM(result, i, elem);
- }
Py_DECREF(old_result);
}
/* Now, we've got the only copy so we can update it in-place */
diff --git a/Objects/call.c b/Objects/call.c
index be8e90d..3250f8a 100644
--- a/Objects/call.c
+++ b/Objects/call.c
@@ -1276,20 +1276,7 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...)
_Py_NO_INLINE PyObject *
_PyStack_AsTuple(PyObject *const *stack, Py_ssize_t nargs)
{
- PyObject *args;
- Py_ssize_t i;
-
- args = PyTuple_New(nargs);
- if (args == NULL) {
- return NULL;
- }
-
- for (i=0; i < nargs; i++) {
- PyObject *item = stack[i];
- Py_INCREF(item);
- PyTuple_SET_ITEM(args, i, item);
- }
- return args;
+ return _PyTuple_FromArray(stack, nargs);
}
@@ -1297,24 +1284,11 @@ PyObject*
_PyStack_AsTupleSlice(PyObject *const *stack, Py_ssize_t nargs,
Py_ssize_t start, Py_ssize_t end)
{
- PyObject *args;
- Py_ssize_t i;
-
assert(0 <= start);
assert(end <= nargs);
assert(start <= end);
- args = PyTuple_New(end - start);
- if (args == NULL) {
- return NULL;
- }
-
- for (i=start; i < end; i++) {
- PyObject *item = stack[i];
- Py_INCREF(item);
- PyTuple_SET_ITEM(args, i - start, item);
- }
- return args;
+ return _PyTuple_FromArray(stack + start, end - start);
}
diff --git a/Objects/listobject.c b/Objects/listobject.c
index cbd6e81..b6524e8 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -3,6 +3,7 @@
#include "Python.h"
#include "pycore_object.h"
#include "pycore_pystate.h"
+#include "pycore_tupleobject.h"
#include "pycore_accu.h"
#ifdef STDC_HEADERS
@@ -2501,26 +2502,11 @@ PyList_Reverse(PyObject *v)
PyObject *
PyList_AsTuple(PyObject *v)
{
- PyObject *w;
- PyObject **p, **q;
- Py_ssize_t n;
if (v == NULL || !PyList_Check(v)) {
PyErr_BadInternalCall();
return NULL;
}
- n = Py_SIZE(v);
- w = PyTuple_New(n);
- if (w == NULL)
- return NULL;
- p = ((PyTupleObject *)w)->ob_item;
- q = ((PyListObject *)v)->ob_item;
- while (--n >= 0) {
- Py_INCREF(*q);
- *p = *q;
- p++;
- q++;
- }
- return w;
+ return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
}
/*[clinic input]
diff --git a/Objects/structseq.c b/Objects/structseq.c
index cf94155..56b06c7 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -2,6 +2,7 @@
and posixmodule for example uses. */
#include "Python.h"
+#include "pycore_tupleobject.h"
#include "structmember.h"
static const char visible_length_key[] = "n_sequence_fields";
@@ -250,7 +251,7 @@ structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored))
n_fields = REAL_SIZE(self);
n_visible_fields = VISIBLE_SIZE(self);
n_unnamed_fields = UNNAMED_FIELDS(self);
- tup = PyTuple_New(n_visible_fields);
+ tup = _PyTuple_FromArray(self->ob_item, n_visible_fields);
if (!tup)
goto error;
@@ -258,12 +259,7 @@ structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored))
if (!dict)
goto error;
- for (i = 0; i < n_visible_fields; i++) {
- Py_INCREF(self->ob_item[i]);
- PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
- }
-
- for (; i < n_fields; i++) {
+ for (i = n_visible_fields; i < n_fields; i++) {
const char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0)
goto error;
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 9cf3f3d..75d2bf9 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -419,14 +419,26 @@ tupleitem(PyTupleObject *a, Py_ssize_t i)
return a->ob_item[i];
}
+PyObject *
+_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
+{
+ PyTupleObject *tuple = (PyTupleObject *)PyTuple_New(n);
+ if (tuple == NULL) {
+ return NULL;
+ }
+ PyObject **dst = tuple->ob_item;
+ for (Py_ssize_t i = 0; i < n; i++) {
+ PyObject *item = src[i];
+ Py_INCREF(item);
+ dst[i] = item;
+ }
+ return (PyObject *)tuple;
+}
+
static PyObject *
tupleslice(PyTupleObject *a, Py_ssize_t ilow,
Py_ssize_t ihigh)
{
- PyTupleObject *np;
- PyObject **src, **dest;
- Py_ssize_t i;
- Py_ssize_t len;
if (ilow < 0)
ilow = 0;
if (ihigh > Py_SIZE(a))
@@ -437,18 +449,7 @@ tupleslice(PyTupleObject *a, Py_ssize_t ilow,
Py_INCREF(a);
return (PyObject *)a;
}
- len = ihigh - ilow;
- np = (PyTupleObject *)PyTuple_New(len);
- if (np == NULL)
- return NULL;
- src = a->ob_item + ilow;
- dest = np->ob_item;
- for (i = 0; i < len; i++) {
- PyObject *v = src[i];
- Py_INCREF(v);
- dest[i] = v;
- }
- return (PyObject *)np;
+ return _PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow);
}
PyObject *
diff --git a/Python/ceval.c b/Python/ceval.c
index ff83863..68c1617 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3831,16 +3831,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Pack other positional arguments into the *args argument */
if (co->co_flags & CO_VARARGS) {
- u = PyTuple_New(argcount - n);
+ u = _PyTuple_FromArray(args + n, argcount - n);
if (u == NULL) {
goto fail;
}
SETLOCAL(total_args, u);
- for (i = n; i < argcount; i++) {
- x = args[i];
- Py_INCREF(x);
- PyTuple_SET_ITEM(u, i-n, x);
- }
}
/* Handle keyword arguments passed as two strided arrays */