Skip to content

Commit aaa8afe

Browse files
committed
[3.12] pythongh-113993: Don't immortalize in PyUnicode_InternInPlace; keep immortalizing in other API (pythonGH-121364)
* Switch PyUnicode_InternInPlace to _PyUnicode_InternMortal, clarify docs * Document immortality in some functions that take `const char *` This is PyUnicode_InternFromString; PyDict_SetItemString, PyObject_SetAttrString; PyObject_DelAttrString; PyUnicode_InternFromString; and the PyModule_Add convenience functions. Always point out a non-immortalizing alternative. * Don't immortalize user-provided attr names in _ctypes (cherry picked from commit b4aedb2)
1 parent 1b8c12e commit aaa8afe

File tree

6 files changed

+84
-10
lines changed

6 files changed

+84
-10
lines changed

Doc/c-api/module.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,14 @@ state:
526526
Note that ``Py_XDECREF()`` should be used instead of ``Py_DECREF()`` in
527527
this case, since *obj* can be ``NULL``.
528528
529+
The number of different *name* strings passed to this function
530+
should be kept small, usually by only using statically allocated strings
531+
as *name*.
532+
For names that aren't known at compile time, prefer calling
533+
:c:func:`PyUnicode_FromString` and :c:func:`PyObject_SetAttr` directly.
534+
For more details, see :c:func:`PyUnicode_InternFromString`, which may be
535+
used internally to create a key object.
536+
529537
.. versionadded:: 3.10
530538
531539
@@ -590,6 +598,9 @@ state:
590598
used from the module's initialization function.
591599
Return ``-1`` with an exception set on error, ``0`` on success.
592600
601+
This is a convenience function that calls :c:func:`PyLong_FromLong` and
602+
:c:func:`PyModule_AddObjectRef`; see their documentation for details.
603+
593604
594605
.. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
595606
@@ -598,6 +609,10 @@ state:
598609
``NULL``-terminated.
599610
Return ``-1`` with an exception set on error, ``0`` on success.
600611
612+
This is a convenience function that calls
613+
:c:func:`PyUnicode_InternFromString` and :c:func:`PyModule_AddObjectRef`;
614+
see their documentation for details.
615+
601616
602617
.. c:macro:: PyModule_AddIntMacro(module, macro)
603618

Doc/c-api/object.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ Object Protocol
107107
If *v* is ``NULL``, the attribute is deleted, but this feature is
108108
deprecated in favour of using :c:func:`PyObject_DelAttrString`.
109109
110+
The number of different attribute names passed to this function
111+
should be kept small, usually by using a statically allocated string
112+
as *attr_name*.
113+
For attribute names that aren't known at compile time, prefer calling
114+
:c:func:`PyUnicode_FromString` and :c:func:`PyObject_SetAttr` directly.
115+
For more details, see :c:func:`PyUnicode_InternFromString`, which may be
116+
used internally to create a key object.
110117
111118
.. c:function:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
112119
@@ -132,6 +139,14 @@ Object Protocol
132139
specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
133140
rather than a :c:expr:`PyObject*`.
134141
142+
The number of different attribute names passed to this function
143+
should be kept small, usually by using a statically allocated string
144+
as *attr_name*.
145+
For attribute names that aren't known at compile time, prefer calling
146+
:c:func:`PyUnicode_FromString` and :c:func:`PyObject_DelAttr` directly.
147+
For more details, see :c:func:`PyUnicode_InternFromString`, which may be
148+
used internally to create a key object for lookup.
149+
135150
136151
.. c:function:: PyObject* PyObject_GenericGetDict(PyObject *o, void *context)
137152

Doc/c-api/unicode.rst

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,15 +1452,41 @@ They all return ``NULL`` or ``-1`` if an exception occurs.
14521452
existing interned string that is the same as :c:expr:`*p_unicode`, it sets :c:expr:`*p_unicode` to
14531453
it (releasing the reference to the old string object and creating a new
14541454
:term:`strong reference` to the interned string object), otherwise it leaves
1455-
:c:expr:`*p_unicode` alone and interns it (creating a new :term:`strong reference`).
1455+
:c:expr:`*p_unicode` alone and interns it.
1456+
14561457
(Clarification: even though there is a lot of talk about references, think
1457-
of this function as reference-neutral; you own the object after the call
1458-
if and only if you owned it before the call.)
1458+
of this function as reference-neutral. You must own the object you pass in;
1459+
after the call you no longer own the passed-in reference, but you newly own
1460+
the result.)
1461+
1462+
This function never raises an exception.
1463+
On error, it leaves its argument unchanged without interning it.
1464+
1465+
Instances of subclasses of :py:class:`str` may not be interned, that is,
1466+
:c:expr:`PyUnicode_CheckExact(*p_unicode)` must be true. If it is not,
1467+
then -- as with any other error -- the argument is left unchanged.
1468+
1469+
Note that interned strings are not “immortal”.
1470+
You must keep a reference to the result to benefit from interning.
14591471
14601472
14611473
.. c:function:: PyObject* PyUnicode_InternFromString(const char *str)
14621474
14631475
A combination of :c:func:`PyUnicode_FromString` and
1464-
:c:func:`PyUnicode_InternInPlace`, returning either a new Unicode string
1465-
object that has been interned, or a new ("owned") reference to an earlier
1466-
interned string object with the same value.
1476+
:c:func:`PyUnicode_InternInPlace`, meant for statically allocated strings.
1477+
1478+
Return a new ("owned") reference to either a new Unicode string object
1479+
that has been interned, or an earlier interned string object with the
1480+
same value.
1481+
1482+
Python may keep a reference to the result, or make it :term:`immortal`,
1483+
preventing it from being garbage-collected promptly.
1484+
For interning an unbounded number of different strings, such as ones coming
1485+
from user input, prefer calling :c:func:`PyUnicode_FromString` and
1486+
:c:func:`PyUnicode_InternInPlace` directly.
1487+
1488+
.. impl-detail::
1489+
1490+
Strings interned this way are made :term:`immortal`.
1491+
1492+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
:c:func:`PyUnicode_InternInPlace` no longer prevents its argument from being
2+
garbage collected.
3+
4+
Several functions that take ``char *`` are now
5+
documented as possibly preventing string objects from being garbage
6+
collected; refer to their documentation for details:
7+
:c:func:`PyUnicode_InternFromString`,
8+
:c:func:`PyDict_SetItemString`,
9+
:c:func:`PyObject_SetAttrString`,
10+
:c:func:`PyObject_DelAttrString`,
11+
:c:func:`PyUnicode_InternFromString`,
12+
and ``PyModule_Add*`` convenience functions.

Modules/_ctypes/_ctypes.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,9 +2164,15 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
21642164
Py_DECREF(result);
21652165
return NULL;
21662166
}
2167-
x = PyDict_SetItemString(result->tp_dict,
2168-
ml->ml_name,
2169-
meth);
2167+
PyObject *name = PyUnicode_FromString(ml->ml_name);
2168+
if (name == NULL) {
2169+
Py_DECREF(meth);
2170+
Py_DECREF(result);
2171+
return NULL;
2172+
}
2173+
PyUnicode_InternInPlace(&name);
2174+
x = PyDict_SetItem(result->tp_dict, name, meth);
2175+
Py_DECREF(name);
21702176
Py_DECREF(meth);
21712177
if (x == -1) {
21722178
Py_DECREF(result);

Objects/unicodeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15108,7 +15108,7 @@ void
1510815108
PyUnicode_InternInPlace(PyObject **p)
1510915109
{
1511015110
PyInterpreterState *interp = _PyInterpreterState_GET();
15111-
_PyUnicode_InternImmortal(interp, p);
15111+
_PyUnicode_InternMortal(interp, p);
1511215112
}
1511315113

1511415114
// Public-looking name kept for the stable ABI; user should not call this:

0 commit comments

Comments
 (0)