@@ -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
35563584Fail :
3585+ assert (PyErr_Occurred ());
35573586 Py_XDECREF (it );
35583587 Py_DECREF (d );
35593588 return NULL ;
0 commit comments