This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author hniksic
Recipients
Date 2007-03-20.14:25:59
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
Thanks for the detailed analysis.  I missed this case and I retract the patch until I think of a way to resolve this problem.  The obvious possibility is to always copy subtype instances before attempting to intern them, but right now I don't have the time to investigate if this slows things down.

As for using s = intern(str(s)) in Python, it's a start, but it does somewhat more than I'd like -- for example, it "interns" all kinds of objects, which is not desirable.  My patch was written with the intention of making PyString_InternInPlace more robust wrt string subtype instances, so that all the code in core and extensions that simply calls PyString_InternInPlace keeps working without modification.

In the long run, the interface of PyString_InternInPlace is a bit too undeterministic for my taste.  It has no error reporting, so it silently ignores some kinds of errors (not enough memory), throws fatal error on others (non-string being passed), and also completely ignores string subtypes.  In my code I use this utility function:

int
intern_force(PyObject **s)
{
  if (PyString_CheckExact(*s))
    /* Most likely case: we're passed an exact string. */
    PyString_InternInPlace(s);
  else if (PyString_Check(*s))
    {
      /* The case we're covering with this function: we got a string
         subtype.  Intern a copy.  */
      PyObject *copy;
      copy = PyString_FromStringAndSize(PyString_AS_STRING(*s),
                                        PyString_GET_SIZE(*s));
      if (!copy)
        return -1;
      Py_DECREF(*s);
      *s = copy;
      PyString_InternInPlace(s);
    }
  else
    {
      PyErr_SetString(PyExc_TypeError, "intern_force passed a non-string");
      return -1;
    }

  if (!PyString_CHECK_INTERNED(s))
    {
      /* PyString_InternInPlace failed and cleared the exception, most
         likely due to insufficient memory. */
      PyErr_Format(PyExc_RuntimeError, "failed to intern string '%s'",
                   PyString_AS_STRING(*s));
      return -1;
    }
  return 0;
}

I don't expect a function like this one to become a part of Python, but PyString_InternInPlace could be usefully improved even without breaking compatibility.
History
Date User Action Args
2007-08-23 15:56:32adminlinkissue1658799 messages
2007-08-23 15:56:32admincreate