@@ -4235,9 +4235,6 @@ static PyObject *
42354235dict_copy_impl (PyDictObject * self )
42364236/*[clinic end generated code: output=ffb782cf970a5c39 input=73935f042b639de4]*/
42374237{
4238- if (PyFrozenDict_CheckExact (self )) {
4239- return Py_NewRef (self );
4240- }
42414238 return PyDict_Copy ((PyObject * )self );
42424239}
42434240
@@ -4263,18 +4260,17 @@ copy_values(PyDictValues *values)
42634260}
42644261
42654262static PyObject *
4266- copy_lock_held (PyObject * o )
4263+ copy_lock_held (PyObject * o , int as_frozendict )
42674264{
42684265 PyObject * copy ;
42694266 PyDictObject * mp ;
4270- int frozendict = PyFrozenDict_Check (o );
42714267
42724268 ASSERT_DICT_LOCKED (o );
42734269
42744270 mp = (PyDictObject * )o ;
42754271 if (mp -> ma_used == 0 ) {
42764272 /* The dict is empty; just return a new dict. */
4277- if (frozendict ) {
4273+ if (as_frozendict ) {
42784274 return PyFrozenDict_New (NULL );
42794275 }
42804276 else {
@@ -4288,7 +4284,7 @@ copy_lock_held(PyObject *o)
42884284 if (newvalues == NULL ) {
42894285 return PyErr_NoMemory ();
42904286 }
4291- if (frozendict ) {
4287+ if (as_frozendict ) {
42924288 split_copy = (PyDictObject * )PyObject_GC_New (PyFrozenDictObject ,
42934289 & PyFrozenDict_Type );
42944290 }
@@ -4307,7 +4303,7 @@ copy_lock_held(PyObject *o)
43074303 split_copy -> ma_used = mp -> ma_used ;
43084304 split_copy -> _ma_watcher_tag = 0 ;
43094305 dictkeys_incref (mp -> ma_keys );
4310- if (frozendict ) {
4306+ if (as_frozendict ) {
43114307 PyFrozenDictObject * frozen = (PyFrozenDictObject * )split_copy ;
43124308 frozen -> ma_hash = -1 ;
43134309 }
@@ -4318,7 +4314,7 @@ copy_lock_held(PyObject *o)
43184314 if (Py_TYPE (mp )-> tp_iter == dict_iter &&
43194315 mp -> ma_values == NULL &&
43204316 (mp -> ma_used >= (mp -> ma_keys -> dk_nentries * 2 ) / 3 ) &&
4321- !frozendict )
4317+ !as_frozendict )
43224318 {
43234319 /* Use fast-copy if:
43244320
@@ -4350,7 +4346,7 @@ copy_lock_held(PyObject *o)
43504346 return (PyObject * )new ;
43514347 }
43524348
4353- if (frozendict ) {
4349+ if (as_frozendict ) {
43544350 copy = PyFrozenDict_New (NULL );
43554351 }
43564352 else {
@@ -4364,6 +4360,19 @@ copy_lock_held(PyObject *o)
43644360 return NULL ;
43654361}
43664362
4363+ // Similar to PyDict_Copy(), but copy also frozendict.
4364+ static PyObject *
4365+ _PyDict_Copy (PyObject * o )
4366+ {
4367+ assert (PyAnyDict_Check (o ));
4368+
4369+ PyObject * res ;
4370+ Py_BEGIN_CRITICAL_SECTION (o );
4371+ res = copy_lock_held (o , PyFrozenDict_Check (o ));
4372+ Py_END_CRITICAL_SECTION ();
4373+ return res ;
4374+ }
4375+
43674376PyObject *
43684377PyDict_Copy (PyObject * o )
43694378{
@@ -4372,11 +4381,22 @@ PyDict_Copy(PyObject *o)
43724381 return NULL ;
43734382 }
43744383
4375- PyObject * res ;
4376- Py_BEGIN_CRITICAL_SECTION (o );
4384+ if (PyFrozenDict_CheckExact (o )) {
4385+ return Py_NewRef (o );
4386+ }
4387+
4388+ return _PyDict_Copy (o );
4389+ }
43774390
4378- res = copy_lock_held (o );
4391+ // Similar to PyDict_Copy(), but return a dict if the argument is a frozendict.
4392+ PyObject *
4393+ _PyDict_CopyAsDict (PyObject * o )
4394+ {
4395+ assert (PyAnyDict_Check (o ));
43794396
4397+ PyObject * res ;
4398+ Py_BEGIN_CRITICAL_SECTION (o );
4399+ res = copy_lock_held (o , 0 );
43804400 Py_END_CRITICAL_SECTION ();
43814401 return res ;
43824402}
@@ -4925,7 +4945,7 @@ dict_or(PyObject *self, PyObject *other)
49254945 if (!PyAnyDict_Check (self ) || !PyAnyDict_Check (other )) {
49264946 Py_RETURN_NOTIMPLEMENTED ;
49274947 }
4928- PyObject * new = PyDict_Copy (self );
4948+ PyObject * new = _PyDict_Copy (self );
49294949 if (new == NULL ) {
49304950 return NULL ;
49314951 }
@@ -6479,7 +6499,7 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2)
64796499 ASSERT_DICT_LOCKED (d1 );
64806500 ASSERT_DICT_LOCKED (d2 );
64816501
6482- PyObject * temp_dict = copy_lock_held (d1 );
6502+ PyObject * temp_dict = copy_lock_held (d1 , PyFrozenDict_Check ( d1 ) );
64836503 if (temp_dict == NULL ) {
64846504 return NULL ;
64856505 }
0 commit comments