@@ -138,6 +138,7 @@ As a consequence of this, split keys have a maximum size of 16.
138138// Forward declarations
139139static PyObject * frozendict_new (PyTypeObject * type , PyObject * args ,
140140 PyObject * kwds );
141+ static int dict_merge (PyObject * a , PyObject * b , int override );
141142
142143
143144/*[clinic input]
@@ -3286,9 +3287,31 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
32863287 int status ;
32873288
32883289 d = _PyObject_CallNoArgs (cls );
3289- if (d == NULL )
3290+ if (d == NULL ) {
32903291 return NULL ;
3292+ }
32913293
3294+ // If cls is a frozendict subclass with overridden constructor,
3295+ // copy the frozendict.
3296+ PyTypeObject * cls_type = _PyType_CAST (cls );
3297+ if (PyFrozenDict_Check (d )
3298+ && PyObject_IsSubclass (cls , (PyObject * )& PyFrozenDict_Type )
3299+ && cls_type -> tp_new != frozendict_new )
3300+ {
3301+ // Subclass-friendly copy
3302+ PyObject * copy = frozendict_new (cls_type , NULL , NULL );
3303+ if (copy == NULL ) {
3304+ Py_DECREF (d );
3305+ return NULL ;
3306+ }
3307+ if (dict_merge (copy , d , 1 ) < 0 ) {
3308+ Py_DECREF (d );
3309+ Py_DECREF (copy );
3310+ return NULL ;
3311+ }
3312+ Py_SETREF (d , copy );
3313+ }
3314+ assert (!PyFrozenDict_Check (d ) || Py_REFCNT (d ) == 1 );
32923315
32933316 if (PyDict_CheckExact (d )) {
32943317 if (PyDict_CheckExact (iterable )) {
@@ -3359,7 +3382,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
33593382dict_iter_exit :;
33603383 Py_END_CRITICAL_SECTION ();
33613384 }
3362- else if (PyFrozenDict_CheckExact (d )) {
3385+ else if (PyFrozenDict_Check (d )) {
33633386 while ((key = PyIter_Next (it )) != NULL ) {
33643387 // anydict_setitem_take2 consumes a reference to key
33653388 status = anydict_setitem_take2 ((PyDictObject * )d ,
@@ -7994,6 +8017,8 @@ frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
79948017 if (d == NULL ) {
79958018 return NULL ;
79968019 }
8020+ assert (Py_REFCNT (d ) == 1 );
8021+
79978022 PyFrozenDictObject * self = _PyFrozenDictObject_CAST (d );
79988023 self -> ma_hash = -1 ;
79998024
0 commit comments