]> granicus.if.org Git - python/commitdiff
If interning an instance of a string subclass, intern a real string object
authorTim Peters <tim.peters@gmail.com>
Wed, 12 Sep 2001 07:54:51 +0000 (07:54 +0000)
committerTim Peters <tim.peters@gmail.com>
Wed, 12 Sep 2001 07:54:51 +0000 (07:54 +0000)
with the same value instead.  This ensures that a string (or string
subclass) object's ob_sinterned pointer is always a str (or NULL), and
that the dict of interned strings only has strs as keys.

Lib/test/test_descr.py
Objects/stringobject.c

index 8d9e81e12e05c4569d7b94d467e15e88d4eeefaf..b0299790ac0399fb92601201815f31027f1b0f65 100644 (file)
@@ -1529,6 +1529,20 @@ def inherits():
     verify(s.lower().__class__ is str)
     verify(s.lower() == base)
 
+    s = madstring("x y")
+    verify(intern(s).__class__ is str)
+    verify(intern(s) is intern("x y"))
+    verify(intern(s) == "x y")
+
+    i = intern("y x")
+    s = madstring("y x")
+    verify(intern(s).__class__ is str)
+    verify(intern(s) is i)
+
+    s = madstring(i)
+    verify(intern(s).__class__ is str)
+    verify(intern(s) is i)
+
     class madunicode(unicode):
         _rev = None
         def rev(self):
index 3c03b9ee2a09f1fd09711e11e7c2e08682c704d4..99a16ed174a82808f6c203b0d26f589a17f49267 100644 (file)
@@ -3553,10 +3553,26 @@ PyString_InternInPlace(PyObject **p)
                Py_DECREF(s);
                return;
        }
-       t = (PyObject *)s;
-       if (PyDict_SetItem(interned, t, t) == 0) {
-               s->ob_sinterned = t;
-               return;
+       /* Ensure that only true string objects appear in the intern dict,
+          and as the value of ob_sinterned. */
+       if (PyString_CheckExact(s)) {
+               t = (PyObject *)s;
+               if (PyDict_SetItem(interned, t, t) == 0) {
+                       s->ob_sinterned = t;
+                       return;
+               }
+       }
+       else {
+               t = PyString_FromStringAndSize(PyString_AS_STRING(s),
+                                               PyString_GET_SIZE(s));
+               if (t != NULL) {
+                       if (PyDict_SetItem(interned, t, t) == 0) {
+                               *p = s->ob_sinterned = t;
+                               Py_DECREF(s);
+                               return;
+                       }
+                       Py_DECREF(t);
+               }
        }
        PyErr_Clear();
 }