99#define Py_TPFLAGS_MAPPING (1 << 6)
1010#endif
1111
12+ // Caching _PyUnicode_FromId results for identifiers
13+ static PyObject * setdefault_id_unicode = NULL ;
14+ static PyObject * update_id_unicode = NULL ;
15+ static PyObject * keys_id_unicode = NULL ;
16+ static PyObject * values_id_unicode = NULL ;
17+ static PyObject * items_id_unicode = NULL ;
18+ static PyObject * clear_id_unicode = NULL ;
19+ static PyObject * copy_id_unicode = NULL ;
20+
1221// Dict subclasses like defaultdict override things in interesting
1322// ways, so we don't want to just directly use the dict methods. Not
1423// sure if it is actually worth doing all this stuff, but it saves
@@ -77,12 +86,14 @@ PyObject *CPyDict_SetDefault(PyObject *dict, PyObject *key, PyObject *value) {
7786 Py_XINCREF (ret );
7887 return ret ;
7988 }
80- _Py_IDENTIFIER (setdefault );
81- PyObject * name = _PyUnicode_FromId (& PyId_setdefault ); /* borrowed */
82- if (name == NULL ) {
83- return NULL ;
89+ if (setdefault_id_unicode == NULL ) {
90+ _Py_IDENTIFIER (setdefault );
91+ setdefault_id_unicode = _PyUnicode_FromId (& PyId_setdefault ); /* borrowed */
92+ if (setdefault_id_unicode == NULL ) {
93+ return NULL ;
94+ }
8495 }
85- return PyObject_CallMethodObjArgs (dict , name , key , value , NULL );
96+ return PyObject_CallMethodObjArgs (dict , setdefault_id_unicode , key , value , NULL );
8697}
8798
8899PyObject * CPyDict_SetDefaultWithNone (PyObject * dict , PyObject * key ) {
@@ -136,12 +147,14 @@ static inline int CPy_ObjectToStatus(PyObject *obj) {
136147}
137148
138149static int CPyDict_UpdateGeneral (PyObject * dict , PyObject * stuff ) {
139- _Py_IDENTIFIER (update );
140- PyObject * name = _PyUnicode_FromId (& PyId_update ); /* borrowed */
141- if (name == NULL ) {
142- return -1 ;
150+ if (update_id_unicode == NULL ) {
151+ _Py_IDENTIFIER (update );
152+ update_id_unicode = _PyUnicode_FromId (& PyId_update ); /* borrowed */
153+ if (update_id_unicode == NULL ) {
154+ return -1 ;
155+ }
143156 }
144- PyObject * res = PyObject_CallMethodOneArg (dict , name , stuff );
157+ PyObject * res = PyObject_CallMethodOneArg (dict , update_id_unicode , stuff );
145158 return CPy_ObjectToStatus (res );
146159}
147160
@@ -207,36 +220,42 @@ PyObject *CPyDict_KeysView(PyObject *dict) {
207220 if (PyDict_CheckExact (dict )){
208221 return _CPyDictView_New (dict , & PyDictKeys_Type );
209222 }
210- _Py_IDENTIFIER (keys );
211- PyObject * name = _PyUnicode_FromId (& PyId_keys ); /* borrowed */
212- if (name == NULL ) {
213- return NULL ;
223+ if (keys_id_unicode == NULL ) {
224+ _Py_IDENTIFIER (keys );
225+ keys_id_unicode = _PyUnicode_FromId (& PyId_keys ); /* borrowed */
226+ if (keys_id_unicode == NULL ) {
227+ return NULL ;
228+ }
214229 }
215- return PyObject_CallMethodNoArgs (dict , name );
230+ return PyObject_CallMethodNoArgs (dict , keys_id_unicode );
216231}
217232
218233PyObject * CPyDict_ValuesView (PyObject * dict ) {
219234 if (PyDict_CheckExact (dict )){
220235 return _CPyDictView_New (dict , & PyDictValues_Type );
221236 }
222- _Py_IDENTIFIER (values );
223- PyObject * name = _PyUnicode_FromId (& PyId_values ); /* borrowed */
224- if (name == NULL ) {
225- return NULL ;
237+ if (values_id_unicode == NULL ) {
238+ _Py_IDENTIFIER (values );
239+ values_id_unicode = _PyUnicode_FromId (& PyId_values ); /* borrowed */
240+ if (values_id_unicode == NULL ) {
241+ return NULL ;
242+ }
226243 }
227- return PyObject_CallMethodNoArgs (dict , name );
244+ return PyObject_CallMethodNoArgs (dict , values_id_unicode );
228245}
229246
230247PyObject * CPyDict_ItemsView (PyObject * dict ) {
231248 if (PyDict_CheckExact (dict )){
232249 return _CPyDictView_New (dict , & PyDictItems_Type );
233250 }
234- _Py_IDENTIFIER (items );
235- PyObject * name = _PyUnicode_FromId (& PyId_items ); /* borrowed */
236- if (name == NULL ) {
237- return NULL ;
251+ if (items_id_unicode == NULL ) {
252+ _Py_IDENTIFIER (items );
253+ items_id_unicode = _PyUnicode_FromId (& PyId_items ); /* borrowed */
254+ if (items_id_unicode == NULL ) {
255+ return NULL ;
256+ }
238257 }
239- return PyObject_CallMethodNoArgs (dict , name );
258+ return PyObject_CallMethodNoArgs (dict , items_id_unicode );
240259}
241260
242261PyObject * CPyDict_Keys (PyObject * dict ) {
@@ -245,12 +264,14 @@ PyObject *CPyDict_Keys(PyObject *dict) {
245264 }
246265 // Inline generic fallback logic to also return a list.
247266 PyObject * list = PyList_New (0 );
248- _Py_IDENTIFIER (keys );
249- PyObject * name = _PyUnicode_FromId (& PyId_keys ); /* borrowed */
250- if (name == NULL ) {
251- return NULL ;
267+ if (keys_id_unicode == NULL ) {
268+ _Py_IDENTIFIER (keys );
269+ keys_id_unicode = _PyUnicode_FromId (& PyId_keys ); /* borrowed */
270+ if (keys_id_unicode == NULL ) {
271+ return NULL ;
272+ }
252273 }
253- PyObject * view = PyObject_CallMethodNoArgs (dict , name );
274+ PyObject * view = PyObject_CallMethodNoArgs (dict , keys_id_unicode );
254275 if (view == NULL ) {
255276 return NULL ;
256277 }
@@ -268,12 +289,14 @@ PyObject *CPyDict_Values(PyObject *dict) {
268289 }
269290 // Inline generic fallback logic to also return a list.
270291 PyObject * list = PyList_New (0 );
271- _Py_IDENTIFIER (values );
272- PyObject * name = _PyUnicode_FromId (& PyId_values ); /* borrowed */
273- if (name == NULL ) {
274- return NULL ;
292+ if (values_id_unicode == NULL ) {
293+ _Py_IDENTIFIER (values );
294+ values_id_unicode = _PyUnicode_FromId (& PyId_values ); /* borrowed */
295+ if (values_id_unicode == NULL ) {
296+ return NULL ;
297+ }
275298 }
276- PyObject * view = PyObject_CallMethodNoArgs (dict , name );
299+ PyObject * view = PyObject_CallMethodNoArgs (dict , values_id_unicode );
277300 if (view == NULL ) {
278301 return NULL ;
279302 }
@@ -291,12 +314,14 @@ PyObject *CPyDict_Items(PyObject *dict) {
291314 }
292315 // Inline generic fallback logic to also return a list.
293316 PyObject * list = PyList_New (0 );
294- _Py_IDENTIFIER (items );
295- PyObject * name = _PyUnicode_FromId (& PyId_items ); /* borrowed */
296- if (name == NULL ) {
297- return NULL ;
317+ if (items_id_unicode == NULL ) {
318+ _Py_IDENTIFIER (items );
319+ items_id_unicode = _PyUnicode_FromId (& PyId_items ); /* borrowed */
320+ if (items_id_unicode == NULL ) {
321+ return NULL ;
322+ }
298323 }
299- PyObject * view = PyObject_CallMethodNoArgs (dict , name );
324+ PyObject * view = PyObject_CallMethodNoArgs (dict , items_id_unicode );
300325 if (view == NULL ) {
301326 return NULL ;
302327 }
@@ -312,12 +337,14 @@ char CPyDict_Clear(PyObject *dict) {
312337 if (PyDict_CheckExact (dict )) {
313338 PyDict_Clear (dict );
314339 } else {
315- _Py_IDENTIFIER (clear );
316- PyObject * name = _PyUnicode_FromId (& PyId_clear ); /* borrowed */
317- if (name == NULL ) {
318- return 0 ;
340+ if (clear_id_unicode == NULL ) {
341+ _Py_IDENTIFIER (clear );
342+ clear_id_unicode = _PyUnicode_FromId (& PyId_clear ); /* borrowed */
343+ if (clear_id_unicode == NULL ) {
344+ return 0 ;
345+ }
319346 }
320- PyObject * res = PyObject_CallMethodNoArgs (dict , name );
347+ PyObject * res = PyObject_CallMethodNoArgs (dict , clear_id_unicode );
321348 if (res == NULL ) {
322349 return 0 ;
323350 }
@@ -329,12 +356,14 @@ PyObject *CPyDict_Copy(PyObject *dict) {
329356 if (PyDict_CheckExact (dict )) {
330357 return PyDict_Copy (dict );
331358 }
332- _Py_IDENTIFIER (copy );
333- PyObject * name = _PyUnicode_FromId (& PyId_copy ); /* borrowed */
334- if (name == NULL ) {
335- return NULL ;
359+ if (copy_id_unicode == NULL ) {
360+ _Py_IDENTIFIER (copy );
361+ copy_id_unicode = _PyUnicode_FromId (& PyId_copy ); /* borrowed */
362+ if (copy_id_unicode == NULL ) {
363+ return NULL ;
364+ }
336365 }
337- return PyObject_CallMethodNoArgs (dict , name );
366+ return PyObject_CallMethodNoArgs (dict , copy_id_unicode );
338367}
339368
340369PyObject * CPyDict_GetKeysIter (PyObject * dict ) {
@@ -352,12 +381,14 @@ PyObject *CPyDict_GetItemsIter(PyObject *dict) {
352381 Py_INCREF (dict );
353382 return dict ;
354383 }
355- _Py_IDENTIFIER (items );
356- PyObject * name = _PyUnicode_FromId (& PyId_items ); /* borrowed */
357- if (name == NULL ) {
358- return NULL ;
384+ if (items_id_unicode == NULL ) {
385+ _Py_IDENTIFIER (items );
386+ items_id_unicode = _PyUnicode_FromId (& PyId_items ); /* borrowed */
387+ if (items_id_unicode == NULL ) {
388+ return NULL ;
389+ }
359390 }
360- PyObject * view = PyObject_CallMethodNoArgs (dict , name );
391+ PyObject * view = PyObject_CallMethodNoArgs (dict , items_id_unicode );
361392 if (view == NULL ) {
362393 return NULL ;
363394 }
@@ -372,12 +403,14 @@ PyObject *CPyDict_GetValuesIter(PyObject *dict) {
372403 Py_INCREF (dict );
373404 return dict ;
374405 }
375- _Py_IDENTIFIER (values );
376- PyObject * name = _PyUnicode_FromId (& PyId_values ); /* borrowed */
377- if (name == NULL ) {
378- return NULL ;
406+ if (values_id_unicode == NULL ) {
407+ _Py_IDENTIFIER (values );
408+ values_id_unicode = _PyUnicode_FromId (& PyId_values ); /* borrowed */
409+ if (values_id_unicode == NULL ) {
410+ return NULL ;
411+ }
379412 }
380- PyObject * view = PyObject_CallMethodNoArgs (dict , name );
413+ PyObject * view = PyObject_CallMethodNoArgs (dict , values_id_unicode );
381414 if (view == NULL ) {
382415 return NULL ;
383416 }
0 commit comments