Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions Doc/c-api/tuple.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ Tuple Objects
.. versionchanged:: next
The function now fails if the tuple hash value was already computed.

.. soft-deprecated:: next
Use the :ref:`PyTupleWriter API <pytuplewriter>` instead.


.. _struct-sequence-objects:

Expand Down Expand Up @@ -293,3 +296,93 @@ type.

.. versionchanged:: 3.13
Now implemented as an alias to :c:func:`PyStructSequence_SetItem`.


.. _pytuplewriter:

PyTupleWriter
-------------

The ``PyTupleWriter`` API can be used to create a Python :class:`tuple` object
when the final size is not known in advance.

.. versionadded:: next

.. c:type:: PyTupleWriter

A tuple writer instance.

The instance must be destroyed by :c:func:`PyTupleWriter_Finish` on
success, or :c:func:`PyTupleWriter_Discard` on error.

The API is **not thread safe**. To share a writer with multiple threads, a
critical section or a lock is needed.

.. c:function:: PyTupleWriter* PyTupleWriter_Create(Py_ssize_t size)

Create a tuple writer instance.

*size* must be greater than or equal to ``0``.

If *size* is greater than ``0``, allocate an internal buffer of *size* items
and all items must be set with :c:func:`PyTupleWriter_SetItem` or
:c:func:`PyTupleWriter_SetItems`.

Set an exception and return ``NULL`` on error.

.. c:function:: PyObject* PyTupleWriter_Finish(PyTupleWriter *writer)

Return the final Python :class:`str` object and destroy the writer instance.

Set an exception and return ``NULL`` on error.

The writer instance is invalid after this call.

.. c:function:: PyObject* PyTupleWriter_FinishWithSize(PyTupleWriter *writer, Py_ssize_t final_size)

Similar to :c:func:`PyTupleWriter_FinishWithSize`, but first truncates
the tuple to *final_size* items.

On success, return a new tuple object.
On error, set an exception and return ``NULL``.

.. c:function:: void PyTupleWriter_Discard(PyTupleWriter *writer)

Discard the internal Tuple buffer and destroy the writer instance.

If *writer* is ``NULL``, no operation is performed.

The writer instance is invalid after this call.

.. c:function:: Py_ssize_t PyTupleWriter_GetSize(PyTupleWriter *writer)

Get the writer size.

The function cannot fail.

.. c:function:: int PyTupleWriter_SetItem(PyTupleWriter *writer, Py_ssize_t index, PyObject *item)

Set an item of a tuple writer start at position *index*.
Copy *item* reference.

An item must be set exactly once.

On success, return ``0``.
On error, set an exception and return ``-1``.

.. c:function:: int PyTupleWriter_SetItems(PyTupleWriter *writer, Py_ssize_t index, PyObject *const *items, Py_ssize_t nitem)

Set *nitem* items of a tuple writer start at position *index*.
Copy *items* references.

Items must be set exactly once.

On success, return ``0``.
On error, set an exception and return ``-1``.

.. c:function:: int PyTupleWriter_Resize(PyTupleWriter **writer, Py_ssize_t new_size)

Resize the tuple writer to *new_size* items.

On success, return ``0``.
On error, set an exception and return ``-1``.
18 changes: 18 additions & 0 deletions Doc/whatsnew/3.16.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,20 @@ New features
API.
(Contributed by Nathan Goldbaum and Victor Stinner in :gh:`158842`.)

* Add a new :ref:`PyTupleWriter API <pytuplewriter>` to create a :class:`tuple`
when the final size is not known in advance. Add functions:

* :c:func:`PyTupleWriter_Create`
* :c:func:`PyTupleWriter_Finish`
* :c:func:`PyTupleWriter_FinishWithSize`
* :c:func:`PyTupleWriter_Discard`
* :c:func:`PyTupleWriter_GetSize`
* :c:func:`PyTupleWriter_SetItem`
* :c:func:`PyTupleWriter_SetItems`
* :c:func:`PyTupleWriter_Resize`

(Contributed by Victor Stinner in :gh:`161694`.)

* Add the :ref:`PyUnicodeWriter API <pyunicodewriter>` to the limited C API.
(Contributed by Victor Stinner in :gh:`161172`.)

Expand Down Expand Up @@ -1450,6 +1464,10 @@ Deprecated C APIs
:c:func:`PyModule_GetFilenameObject` instead is still recommended.
(Contributed by Victor Stinner in :gh:`154757`.)

* Soft deprecate the :c:func:`_PyTuple_Resize` function: use the new
:ref:`PyTupleWriter API <pytuplewriter>` instead.
(Contributed by Victor Stinner in :gh:`161694`.)

* Soft deprecate functions modifying Unicode strings:
:c:func:`PyUnicode_New`, :c:func:`PyUnicode_CopyCharacters`,
:c:func:`PyUnicode_Fill`, :c:func:`PyUnicode_Resize`,
Expand Down
33 changes: 32 additions & 1 deletion Include/cpython/tupleobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) {

/* Function *only* to be used to fill in brand new tuples */
static inline void
PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value)
{
// For backward compatibility, accept mutating a tuple even if
// _PyObject_IsUniquelyReferenced(op) is false and/or tuple->ob_hash != -1.
// See for example _PyTuple_Recycle(). Accept also setting an item which
// was already set: the caller must Py_DECREF() the old value in this case.
PyTupleObject *tuple = _PyTuple_CAST(op);
assert(0 <= index);
assert(index < Py_SIZE(tuple));
Expand All @@ -42,3 +47,29 @@ PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
PyAPI_FUNC(PyObject*) PyTuple_FromArray(
PyObject *const *array,
Py_ssize_t size);


/* --- PyTupleWriter API -------------------------------------------------- */

struct PyTupleWriter;
typedef struct PyTupleWriter PyTupleWriter;

PyAPI_FUNC(PyTupleWriter*) PyTupleWriter_Create(Py_ssize_t size);
PyAPI_FUNC(PyObject*) PyTupleWriter_Finish(PyTupleWriter *writer);
PyAPI_FUNC(PyObject*) PyTupleWriter_FinishWithSize(
PyTupleWriter *writer,
Py_ssize_t final_size);
PyAPI_FUNC(void) PyTupleWriter_Discard(PyTupleWriter *writer);
PyAPI_FUNC(Py_ssize_t) PyTupleWriter_GetSize(PyTupleWriter *writer);
PyAPI_FUNC(int) PyTupleWriter_SetItem(
PyTupleWriter *writer,
Py_ssize_t index,
PyObject *item);
PyAPI_FUNC(int) PyTupleWriter_SetItems(
PyTupleWriter *writer,
Py_ssize_t index,
PyObject *const *items,
Py_ssize_t nitem);
PyAPI_FUNC(int) PyTupleWriter_Resize(
PyTupleWriter **writer,
Py_ssize_t new_size);
78 changes: 78 additions & 0 deletions Include/internal/pycore_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,84 @@
#endif
#define _PyTuple_HASH_EMPTY (_PyTuple_HASH_XXPRIME_5 + (_PyTuple_HASH_XXPRIME_5 ^ 3527539UL))


#ifndef NDEBUG
// Check that a tuple can be mutated in-place.
// Usage: assert(_PyTuple_CanMutate(v));
static int
_PyTuple_CanMutate(PyTupleObject *tuple)
{
assert(PyTuple_Check(tuple));

// Do not check _PyObject_IsUniquelyReferenced(): the function is called
// by _PyTupleWriter_CheckConsistency() and a tuple writer can be used by
// multiple threads using external locking.
assert(Py_REFCNT(tuple) == 1);

// The empty tuple must not be modified
assert(1 <= Py_SIZE(tuple));
assert(tuple != &_Py_SINGLETON(tuple_empty));

// The hash value must not be cached yet. Otherwise, it means that the
// tuple object was already used in Python somehow (ex: as a dictionary
// key).
assert(tuple->ob_hash == -1);

return 1;
}
#endif


/* --- PyTupleWriter API -------------------------------------------------- */

#ifndef NDEBUG
static inline int
_PyTupleWriter_CheckConsistency(PyTupleWriter *writer)
{
assert(writer != NULL);
assert(PyTuple_CheckExact(_PyObject_CAST(writer)));
PyTupleObject *tuple = (PyTupleObject*)writer;
assert(0 <= Py_SIZE(tuple));
if (Py_SIZE(tuple) != 0) {
// Do not use _PyObject_IsUniquelyReferenced(): the caller can have
// its own lock to prevent a writer from being used by two threads
// at the same time.
assert(Py_REFCNT(tuple) == 1);

assert(!_PyObject_GC_IS_TRACKED(tuple));
}
else {
assert(tuple == &_Py_SINGLETON(tuple_empty));
}
return 1;
}
#endif


static inline void
_PyTupleWriter_SET_ITEM_STEAL(PyTupleWriter *writer,
Py_ssize_t index, PyObject *item)
{
assert(_PyTupleWriter_CheckConsistency(writer));
PyTupleObject *tuple = _PyTuple_CAST(writer);
assert(item != NULL);

assert(_PyTuple_CanMutate(tuple));
assert(0 <= index && index < Py_SIZE(tuple));
assert(tuple->ob_item[index] == NULL);

tuple->ob_item[index] = item;
}


static inline void
_PyTupleWriter_SET_ITEM(PyTupleWriter *writer,
Py_ssize_t index, PyObject *item)
{
assert(item != NULL);
return _PyTupleWriter_SET_ITEM_STEAL(writer, index, Py_NewRef(item));

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, tail-call)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (x64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check warning on line 154 in Include/internal/pycore_tuple.h

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / Build and test (arm64, switch-case)

'_PyTupleWriter_SET_ITEM': 'void' function returning a value [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]
}

#ifdef __cplusplus
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Add a new :ref:`PyTupleWriter API <pytuplewriter>` to create a
:class:`tuple` when the final size is not known in advance. Add functions:

* :c:func:`PyTupleWriter_Create`
* :c:func:`PyTupleWriter_Finish`
* :c:func:`PyTupleWriter_FinishWithSize`
* :c:func:`PyTupleWriter_Discard`
* :c:func:`PyTupleWriter_GetSize`
* :c:func:`PyTupleWriter_SetItem`
* :c:func:`PyTupleWriter_SetItems`
* :c:func:`PyTupleWriter_Resize`

Patch by Victor Stinner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Soft deprecate the :c:func:`_PyTuple_Resize` function: use the new
:ref:`PyTupleWriter API <pytuplewriter>` instead. Patch by Victor Stinner.
21 changes: 9 additions & 12 deletions Modules/_tkinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Copyright (C) 1994 Steen Lumholt.
#endif

#include "pycore_long.h" // _PyLong_IsNegative()
#include "pycore_tuple.h" // _PyTupleWriter_SET_ITEM()
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8String

#include <signal.h> // SIGINT
Expand Down Expand Up @@ -3401,7 +3402,7 @@ Tkapp_Dealloc(PyObject *op)
/**** Tkinter Module ****/

typedef struct {
PyObject* tuple;
PyTupleWriter *writer;
Py_ssize_t size; /* current size */
Py_ssize_t maxsize; /* allocated size */
} FlattenContext;
Expand All @@ -3419,7 +3420,7 @@ _bump(FlattenContext* context, Py_ssize_t size)

context->maxsize = maxsize;

return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
return PyTupleWriter_Resize(&context->writer, maxsize) >= 0;
}

static int
Expand Down Expand Up @@ -3449,8 +3450,7 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
if (context->size + 1 > context->maxsize &&
!_bump(context, 1))
return 0;
PyTuple_SET_ITEM(context->tuple,
context->size++, Py_NewRef(o));
_PyTupleWriter_SET_ITEM(context->writer, context->size++, o);
}
}
} else {
Expand Down Expand Up @@ -3480,21 +3480,18 @@ _tkinter__flatten(PyObject *module, PyObject *item)
if (context.maxsize == 0)
return PyTuple_New(0);

context.tuple = PyTuple_New(context.maxsize);
if (!context.tuple)
context.writer = PyTupleWriter_Create(context.maxsize);
if (!context.writer) {
return NULL;

}
context.size = 0;

if (!_flatten1(&context, item, 0)) {
Py_XDECREF(context.tuple);
PyTupleWriter_Discard(context.writer);
return NULL;
}

if (_PyTuple_Resize(&context.tuple, context.size))
return NULL;

return context.tuple;
return PyTupleWriter_FinishWithSize(context.writer, context.size);
}

/*[clinic input]
Expand Down
Loading
Loading