]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-146056: Fix repr() for lists containing NULLs (GH-146129) (GH-146155) ...
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 22 Mar 2026 08:06:17 +0000 (10:06 +0200)
committerGitHub <noreply@github.com>
Sun, 22 Mar 2026 08:06:17 +0000 (08:06 +0000)
(cherry picked from commit 0f2246b1553f401da5ade47e0fd1c80ad7a8dfa5)
(cherry picked from commit 796513306fdc1184452ea644b485f83511f39528)

Co-authored-by: Victor Stinner <vstinner@python.org>
Doc/c-api/file.rst
Doc/c-api/object.rst
Lib/test/test_capi/test_list.py
Lib/test/test_capi/test_tuple.py
Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-18-52-00.gh-issue-146056.r1tVSo.rst [new file with mode: 0644]
Objects/listobject.c

index 9d01254ddb2a11f06e93b3a799b977309510bdc1..1bb5c1b768510f4143fd5f584bd3ad21cdacea2d 100644 (file)
@@ -123,9 +123,12 @@ the :mod:`io` APIs instead.
 
    Write object *obj* to file object *p*.  The only supported flag for *flags* is
    :c:macro:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written
-   instead of the :func:`repr`.  Return ``0`` on success or ``-1`` on failure; the
-   appropriate exception will be set.
+   instead of the :func:`repr`.
+
+   If *obj* is ``NULL``, write the string ``"<NULL>"``.
 
+   Return ``0`` on success or ``-1`` on failure; the
+   appropriate exception will be set.
 
 .. c:function:: int PyFile_WriteString(const char *s, PyObject *p)
 
index 416465c2a4209683821de6e573f58721ddb85e48..be4e5847022f33b86c315600b4a7d74f40849e7f 100644 (file)
@@ -319,6 +319,8 @@ Object Protocol
    representation on success, ``NULL`` on failure.  This is the equivalent of the
    Python expression ``repr(o)``.  Called by the :func:`repr` built-in function.
 
+   If argument is ``NULL``, return the string ``'<NULL>'``.
+
    .. versionchanged:: 3.4
       This function now includes a debug assertion to help ensure that it
       does not silently discard an active exception.
@@ -333,6 +335,8 @@ Object Protocol
    a string similar to that returned by :c:func:`PyObject_Repr` in Python 2.
    Called by the :func:`ascii` built-in function.
 
+   If argument is ``NULL``, return the string ``'<NULL>'``.
+
    .. index:: string; PyObject_Str (C function)
 
 
@@ -343,6 +347,8 @@ Object Protocol
    Python expression ``str(o)``.  Called by the :func:`str` built-in function
    and, therefore, by the :func:`print` function.
 
+   If argument is ``NULL``, return the string ``'<NULL>'``.
+
    .. versionchanged:: 3.4
       This function now includes a debug assertion to help ensure that it
       does not silently discard an active exception.
@@ -358,6 +364,8 @@ Object Protocol
    a TypeError is raised when *o* is an integer instead of a zero-initialized
    bytes object.
 
+   If argument is ``NULL``, return the :class:`bytes` object ``b'<NULL>'``.
+
 
 .. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls)
 
index 52d8bf3ff47f2315b1b185ccc5be1864bbe85c78..bb330e177396335027a3f84123317b5bc94256c8 100644 (file)
@@ -352,6 +352,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES list_extend(NULL, [])
         # CRASHES list_extend([], NULL)
 
+    def test_uninitialized_list_repr(self):
+        lst = _testlimitedcapi.list_new(3)
+        self.assertEqual(repr(lst), '[<NULL>, <NULL>, <NULL>]')
+
 
 if __name__ == "__main__":
     unittest.main()
index e6b49caeb51f325c014d93759c05e8dad9c68584..eaeb99cf153506c26ac7f852487dd9d8c9314133 100644 (file)
@@ -257,5 +257,10 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, resize, [1, 2, 3], 0, False)
         self.assertRaises(SystemError, resize, NULL, 0, False)
 
+    def test_uninitialized_tuple_repr(self):
+        tup = _testlimitedcapi.tuple_new(3)
+        self.assertEqual(repr(tup), '(<NULL>, <NULL>, <NULL>)')
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-18-52-00.gh-issue-146056.r1tVSo.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-18-18-52-00.gh-issue-146056.r1tVSo.rst
new file mode 100644 (file)
index 0000000..5d97886
--- /dev/null
@@ -0,0 +1 @@
+Fix :func:`repr` for lists containing ``NULL``\ s.
index 8af6964189ec3edec37f9469b81edf0157c4ef0a..f5acc5c1bef4ee1748816b8eeeaa4f8677cdf419 100644 (file)
@@ -604,7 +604,7 @@ list_repr_impl(PyListObject *v)
        so must refetch the list size on each iteration. */
     for (i = 0; i < Py_SIZE(v); ++i) {
         /* Hold a strong reference since repr(item) can mutate the list */
-        item = Py_NewRef(v->ob_item[i]);
+        item = Py_XNewRef(v->ob_item[i]);
 
         if (i > 0) {
             if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)