Skip to content

Commit 01ae040

Browse files
committed
Convert genericalias _Py_make_parameters() to writer
Add private _PyTupleWriter_GetItems() helper function.
1 parent 537989d commit 01ae040

File tree

3 files changed

+39
-39
lines changed

3 files changed

+39
-39
lines changed

Include/internal/pycore_tuple.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ _PyTuple_Recycle(PyObject *op)
7171
#endif
7272
#define _PyTuple_HASH_EMPTY (_PyTuple_HASH_XXPRIME_5 + (_PyTuple_HASH_XXPRIME_5 ^ 3527539UL))
7373

74+
extern PyObject** _PyTupleWriter_GetItems(
75+
PyTupleWriter *writer,
76+
Py_ssize_t *size);
77+
7478
#ifdef __cplusplus
7579
}
7680
#endif

Objects/genericaliasobject.c

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,17 @@ tuple_index(PyObject *self, Py_ssize_t len, PyObject *item)
153153
}
154154

155155
static int
156-
tuple_add(PyObject *self, Py_ssize_t len, PyObject *item)
156+
tuplewriter_add(PyTupleWriter *writer, PyObject *item)
157157
{
158-
if (tuple_index(self, len, item) < 0) {
159-
PyTuple_SET_ITEM(self, len, Py_NewRef(item));
160-
return 1;
158+
Py_ssize_t len;
159+
PyObject **items = _PyTupleWriter_GetItems(writer, &len);
160+
for (Py_ssize_t i = 0; i < len; i++) {
161+
if (items[i] == item) {
162+
return 0;
163+
}
161164
}
162-
return 0;
165+
166+
return PyTupleWriter_Add(writer, item);
163167
}
164168

165169
PyObject *
@@ -175,13 +179,10 @@ _Py_make_parameters(PyObject *args)
175179
}
176180
}
177181
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
178-
Py_ssize_t len = nargs;
179-
PyObject *parameters = PyTuple_New(len);
182+
PyTupleWriter *parameters = PyTupleWriter_Create(nargs);
180183
if (parameters == NULL) {
181-
Py_XDECREF(tuple_args);
182-
return NULL;
184+
goto error;
183185
}
184-
Py_ssize_t iparam = 0;
185186
for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
186187
PyObject *t = PyTuple_GET_ITEM(args, iarg);
187188
// We don't want __parameters__ descriptor of a bare Python class.
@@ -190,60 +191,47 @@ _Py_make_parameters(PyObject *args)
190191
}
191192
int rc = PyObject_HasAttrWithError(t, &_Py_ID(__typing_subst__));
192193
if (rc < 0) {
193-
Py_DECREF(parameters);
194-
Py_XDECREF(tuple_args);
195-
return NULL;
194+
goto error;
196195
}
197196
if (rc) {
198-
iparam += tuple_add(parameters, iparam, t);
197+
if (tuplewriter_add(parameters, t) < 0) {
198+
goto error;
199+
}
199200
}
200201
else {
201202
PyObject *subparams;
202203
if (PyObject_GetOptionalAttr(t, &_Py_ID(__parameters__),
203204
&subparams) < 0) {
204-
Py_DECREF(parameters);
205-
Py_XDECREF(tuple_args);
206-
return NULL;
205+
goto error;
207206
}
208207
if (!subparams && (PyTuple_Check(t) || PyList_Check(t))) {
209208
// Recursively call _Py_make_parameters for lists/tuples and
210209
// add the results to the current parameters.
211210
subparams = _Py_make_parameters(t);
212211
if (subparams == NULL) {
213-
Py_DECREF(parameters);
214-
Py_XDECREF(tuple_args);
215-
return NULL;
212+
goto error;
216213
}
217214
}
218215
if (subparams && PyTuple_Check(subparams)) {
219216
Py_ssize_t len2 = PyTuple_GET_SIZE(subparams);
220-
Py_ssize_t needed = len2 - 1 - (iarg - iparam);
221-
if (needed > 0) {
222-
len += needed;
223-
if (_PyTuple_Resize(&parameters, len) < 0) {
224-
Py_DECREF(subparams);
225-
Py_DECREF(parameters);
226-
Py_XDECREF(tuple_args);
227-
return NULL;
228-
}
229-
}
230217
for (Py_ssize_t j = 0; j < len2; j++) {
231218
PyObject *t2 = PyTuple_GET_ITEM(subparams, j);
232-
iparam += tuple_add(parameters, iparam, t2);
219+
if (tuplewriter_add(parameters, t2) < 0) {
220+
Py_DECREF(subparams);
221+
goto error;
222+
}
233223
}
234224
}
235225
Py_XDECREF(subparams);
236226
}
237227
}
238-
if (iparam < len) {
239-
if (_PyTuple_Resize(&parameters, iparam) < 0) {
240-
Py_XDECREF(parameters);
241-
Py_XDECREF(tuple_args);
242-
return NULL;
243-
}
244-
}
245228
Py_XDECREF(tuple_args);
246-
return parameters;
229+
return PyTupleWriter_Finish(parameters);
230+
231+
error:
232+
PyTupleWriter_Discard(parameters);
233+
Py_XDECREF(tuple_args);
234+
return NULL;
247235
}
248236

249237
/* If obj is a generic alias, substitute type variables params

Objects/tupleobject.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,14 @@ PyTupleWriter_AddArray(PyTupleWriter *writer,
13751375
}
13761376

13771377

1378+
PyObject**
1379+
_PyTupleWriter_GetItems(PyTupleWriter *writer, Py_ssize_t *size)
1380+
{
1381+
*size = writer->size;
1382+
return writer->items;
1383+
}
1384+
1385+
13781386
static inline void
13791387
tuplewriter_free(PyTupleWriter *writer)
13801388
{

0 commit comments

Comments
 (0)