diff options
author | Sergey Fedoseev <fedoseev.sergey@gmail.com> | 2019-02-25 16:59:12 (GMT) |
---|---|---|
committer | Victor Stinner <vstinner@redhat.com> | 2019-02-25 16:59:12 (GMT) |
commit | 234531b4462b20d668762bd78406fd2ebab129c9 (patch) | |
tree | f0a93cbdf6ebf42055498ea9533891cec0680bcf | |
parent | 55e335d7d59be44819c6b672d258e2d5feb1e633 (diff) | |
download | cpython-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.h | 1 | ||||
-rw-r--r-- | Modules/itertoolsmodule.c | 29 | ||||
-rw-r--r-- | Objects/call.c | 30 | ||||
-rw-r--r-- | Objects/listobject.c | 18 | ||||
-rw-r--r-- | Objects/structseq.c | 10 | ||||
-rw-r--r-- | Objects/tupleobject.c | 33 | ||||
-rw-r--r-- | Python/ceval.c | 7 |
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 */ |