@@ -113,7 +113,7 @@ PyCode_ClearWatcher(int watcher_id)
113113
114114#define _PyCodeObject_CAST (op ) (assert(PyCode_Check(op)), (PyCodeObject *)(op))
115115
116- static int
116+ static inline int
117117should_intern_string (PyObject * o )
118118{
119119#ifdef Py_GIL_DISABLED
@@ -196,17 +196,45 @@ intern_strings(PyObject *tuple)
196196 return 0 ;
197197}
198198
199+ static inline PyObject *
200+ get_interned_string (PyObject * interned_dict , PyObject * s ) {
201+ if (!PyUnicode_CheckExact (s )) {
202+ return NULL ;
203+ }
204+
205+ PyObject * existing = PyDict_GetItemWithError (interned_dict , s );
206+ if (existing == NULL ) {
207+ if (PyErr_Occurred ()) {
208+ return NULL ;
209+ }
210+ return NULL ;
211+ }
212+ return existing ;
213+ }
214+
199215/* Intern constants. In the default build, this interns selected string
200216 constants. In the free-threaded build, this also interns non-string
201217 constants. */
202218static int
203219intern_constants (PyObject * tuple , int * modified )
204220{
205221 PyInterpreterState * interp = _PyInterpreterState_GET ();
222+ PyObject * interned_dict = _Py_INTERP_CACHED_OBJECT (interp , interned_strings );
206223 for (Py_ssize_t i = PyTuple_GET_SIZE (tuple ); -- i >= 0 ; ) {
207224 PyObject * v = PyTuple_GET_ITEM (tuple , i );
208- if (PyUnicode_CheckExact (v )) {
209- if (should_intern_string (v )) {
225+ if (PyUnicode_CheckExact (v ) && PyUnicode_GET_LENGTH (v ) > 1 ) {
226+ if (PyUnicode_CHECK_INTERNED (v ) != 0 ) {
227+ continue ;
228+ }
229+ PyObject * interned = get_interned_string (interned_dict , v );
230+ if (interned != NULL && interned != v ) {
231+ Py_INCREF (interned );
232+ PyTuple_SET_ITEM (tuple , i , interned );
233+ Py_DECREF (v );
234+ if (modified ) {
235+ * modified = 1 ;
236+ }
237+ } else if (should_intern_string (v )) {
210238 PyObject * w = v ;
211239 _PyUnicode_InternMortal (interp , & v );
212240 if (w != v ) {
0 commit comments