Skip to content

Commit 5aad887

Browse files
committed
Cleanup error path
1 parent 4304c9e commit 5aad887

1 file changed

Lines changed: 41 additions & 12 deletions

File tree

Objects/dictobject.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3416,9 +3416,7 @@ PyObject *
34163416
_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
34173417
{
34183418
PyObject *it = NULL; /* iter(iterable) */
3419-
PyObject *key;
34203419
PyObject *d;
3421-
int status;
34223420
int need_copy = 0;
34233421

34243422
PyTypeObject *cls_type = _PyType_CAST(cls);
@@ -3429,6 +3427,8 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
34293427
d = frozendict_new_untracked(cls_type);
34303428
}
34313429
else {
3430+
// Dict subclass, or frozendict subclass which overrides
3431+
// the constructor.
34323432
d = _PyObject_CallNoArgs(cls);
34333433
}
34343434
if (d == NULL) {
@@ -3516,44 +3516,73 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
35163516
}
35173517

35183518
if (PyDict_CheckExact(d)) {
3519+
int status = 0;
3520+
35193521
Py_BEGIN_CRITICAL_SECTION(d);
3520-
while ((key = PyIter_Next(it)) != NULL) {
3522+
while (1) {
3523+
PyObject *key;
3524+
status = PyIter_NextItem(it, &key);
3525+
if (status <= 0) {
3526+
break;
3527+
}
3528+
35213529
status = setitem_lock_held((PyDictObject *)d, key, value);
35223530
Py_DECREF(key);
35233531
if (status < 0) {
3524-
assert(PyErr_Occurred());
3525-
goto dict_iter_exit;
3532+
break;
35263533
}
35273534
}
3528-
dict_iter_exit:;
35293535
Py_END_CRITICAL_SECTION();
3536+
3537+
if (status < 0) {
3538+
goto Fail;
3539+
}
35303540
}
35313541
else if (PyFrozenDict_Check(d)) {
3532-
while ((key = PyIter_Next(it)) != NULL) {
3542+
while (1) {
3543+
PyObject *key;
3544+
int status = PyIter_NextItem(it, &key);
3545+
if (status < 0) {
3546+
goto Fail;
3547+
}
3548+
if (status == 0) {
3549+
break;
3550+
}
3551+
35333552
// setitem_take2_lock_held consumes a reference to key
35343553
status = setitem_take2_lock_held((PyDictObject *)d,
35353554
key, Py_NewRef(value));
35363555
if (status < 0) {
3537-
assert(PyErr_Occurred());
35383556
goto Fail;
35393557
}
35403558
}
35413559
}
35423560
else {
3543-
while ((key = PyIter_Next(it)) != NULL) {
3561+
while (1) {
3562+
PyObject *key;
3563+
int status = PyIter_NextItem(it, &key);
3564+
if (status < 0) {
3565+
goto Fail;
3566+
}
3567+
if (status == 0) {
3568+
break;
3569+
}
3570+
35443571
status = PyObject_SetItem(d, key, value);
35453572
Py_DECREF(key);
3546-
if (status < 0)
3573+
if (status < 0) {
35473574
goto Fail;
3575+
}
35483576
}
3577+
35493578
}
35503579

3551-
if (PyErr_Occurred())
3552-
goto Fail;
3580+
assert(!PyErr_Occurred());
35533581
Py_DECREF(it);
35543582
goto Done;
35553583

35563584
Fail:
3585+
assert(PyErr_Occurred());
35573586
Py_XDECREF(it);
35583587
Py_DECREF(d);
35593588
return NULL;

0 commit comments

Comments
 (0)