@@ -5169,15 +5169,47 @@ dict_vectorcall(PyObject *type, PyObject * const*args,
51695169 return NULL ;
51705170 }
51715171
5172- PyObject * self ;
5173- if (Py_Is ((PyTypeObject * )type , & PyFrozenDict_Type )
5174- || PyType_IsSubtype ((PyTypeObject * )type , & PyFrozenDict_Type ))
5175- {
5176- self = frozendict_new (_PyType_CAST (type ), NULL , NULL );
5172+ PyObject * self = dict_new (_PyType_CAST (type ), NULL , NULL );
5173+ if (self == NULL ) {
5174+ return NULL ;
51775175 }
5178- else {
5179- self = dict_new (_PyType_CAST (type ), NULL , NULL );
5176+ if (nargs == 1 ) {
5177+ if (dict_update_arg (self , args [0 ]) < 0 ) {
5178+ Py_DECREF (self );
5179+ return NULL ;
5180+ }
5181+ args ++ ;
51805182 }
5183+ if (kwnames != NULL ) {
5184+ for (Py_ssize_t i = 0 ; i < PyTuple_GET_SIZE (kwnames ); i ++ ) {
5185+ PyObject * key = PyTuple_GET_ITEM (kwnames , i ); // borrowed
5186+ if (PyDict_SetItem (self , key , args [i ]) < 0 ) {
5187+ Py_DECREF (self );
5188+ return NULL ;
5189+ }
5190+ }
5191+ }
5192+ return self ;
5193+ }
5194+
5195+ static PyObject *
5196+ frozendict_vectorcall (PyObject * type , PyObject * const * args ,
5197+ size_t nargsf , PyObject * kwnames )
5198+ {
5199+ Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
5200+ if (!_PyArg_CheckPositional ("frozendict" , nargs , 0 , 1 )) {
5201+ return NULL ;
5202+ }
5203+
5204+ if (nargs == 1 && kwnames == NULL
5205+ && PyFrozenDict_CheckExact (args [0 ])
5206+ && Py_Is ((PyTypeObject * )type , & PyFrozenDict_Type ))
5207+ {
5208+ // frozendict(frozendict) returns the same object unmodified
5209+ return Py_NewRef (args [0 ]);
5210+ }
5211+
5212+ PyObject * self = frozendict_new (_PyType_CAST (type ), NULL , NULL );
51815213 if (self == NULL ) {
51825214 return NULL ;
51835215 }
@@ -8171,6 +8203,11 @@ PyObject*
81718203PyFrozenDict_New (PyObject * iterable )
81728204{
81738205 if (iterable != NULL ) {
8206+ if (PyFrozenDict_CheckExact (iterable )) {
8207+ // PyFrozenDict_New(frozendict) returns the same object unmodified
8208+ return Py_NewRef (iterable );
8209+ }
8210+
81748211 PyObject * args = PyTuple_Pack (1 , iterable );
81758212 if (args == NULL ) {
81768213 return NULL ;
@@ -8228,6 +8265,6 @@ PyTypeObject PyFrozenDict_Type = {
82288265 .tp_alloc = _PyType_AllocNoTrack ,
82298266 .tp_new = frozendict_new ,
82308267 .tp_free = PyObject_GC_Del ,
8231- .tp_vectorcall = dict_vectorcall ,
8268+ .tp_vectorcall = frozendict_vectorcall ,
82328269 .tp_version_tag = _Py_TYPE_VERSION_FROZENDICT ,
82338270};
0 commit comments