4
4
.. toctree ::
5
5
:maxdepth: 3
6
6
7
+
8
+ ..
9
+ Links, mostly to the Python documentation:
10
+
11
+ .. _PyTuple_SetItem() : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SetItem
12
+ .. _PyTuple_SET_ITEM() : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SET_ITEM
13
+ .. _Py_BuildValue() : https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
14
+ .. _PyTuple_Pack() : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_Pack
15
+
7
16
.. _chapter_refcount_and_containers :
8
17
9
18
======================================
@@ -56,7 +65,7 @@ Here is an example of exploring reference counts and tuples.
56
65
assert(Py_REFCNT(container) == 1);
57
66
58
67
/* Create a new string. */
59
- PyObject *value_0 = new_unique_string(__FUNCTION__);
68
+ PyObject *value_0 = new_unique_string(__FUNCTION__, NULL );
60
69
assert(Py_REFCNT(value_0) == 1);
61
70
62
71
/* Set it as tuple[0].
@@ -101,10 +110,10 @@ The Python documentation for the `Tuple API <https://docs.python.org/3/c-api/tup
101
110
* - Python C API
102
111
- Behaviour
103
112
- Notes
104
- * - `PyTuple_SetItem() < https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SetItem > `_
113
+ * - `PyTuple_SetItem() `_
105
114
- Steals, decrements the reference count of the original.
106
115
- More stuff.
107
- * - `PyTuple_SET_ITEM() < https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SET_ITEM > `_
116
+ * - `PyTuple_SET_ITEM() `_
108
117
- Steals, leaks original.
109
118
- **Contrary ** to the documentation this leaks.
110
119
* - ``Py_BuildValue("(s)", val) ``
@@ -115,29 +124,67 @@ The Python documentation for the `Tuple API <https://docs.python.org/3/c-api/tup
115
124
``PyTuple_SetItem() ``
116
125
---------------------
117
126
118
- `PyTuple_SetItem() <https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SetItem >`_
127
+ Basic Usage
128
+ ^^^^^^^^^^^
129
+
130
+ `PyTuple_SetItem() `_ *steals * a reference.
131
+
132
+ .. code-block :: c
133
+
134
+ PyObject *container = PyTuple_New(1); /* Reference count will be 1. */
135
+ PyObject *value = new_unique_string(__FUNCTION__, NULL); /* Ref count will be 1. */
136
+ PyTuple_SetItem(container, 0, value); /* Ref count of value will be 1. */
137
+ /* get_item == value and Ref count will be 1. */
138
+ PyObject *get_item = PyTuple_GET_ITEM(container, 0);
139
+ Py_DECREF(container); /* The contents of the container, value, will be decref'd */
140
+ /* Do not do this as the container deals with this. */
141
+ /* Py_DECREF(value); */
142
+
143
+ For code tests see:
144
+
145
+ * ``dbg_PyTuple_SetItem_steals `` in ``src/cpy/Containers/DebugContainers.c ``.
146
+ * ``test_PyTuple_SetItem_steals `` in ``src/cpy/RefCount/cRefCount.c ``.
147
+ * ``tests.unit.test_c_ref_count.test_test_PyTuple_SetItem_steals ``.
148
+
149
+ Replacement
150
+ ^^^^^^^^^^^
151
+
152
+ What happens when you use `PyTuple_SetItem() `_ to replace an existing element in a tuple.
153
+ `PyTuple_SetItem() `_ still *steals * a reference, but what happens to the original reference?
154
+
155
+ .. code-block :: c
156
+
157
+ PyObject *container = PyTuple_New(1); /* Reference count will be 1. */
158
+ PyObject *value_a = new_unique_string(__FUNCTION__, NULL); /* Ref count will be 1. */
159
+ PyTuple_SetItem(container, 0, value_a); /* Ref count of value_a will be 1. */
160
+ PyObject *value_b = new_unique_string(__FUNCTION__, NULL); /* Ref count will be 1. */
161
+ PyTuple_SetItem(container, 0, value_b);
162
+ /* Ref count of value_b will be 1, value_a ref count will be decremented. */
163
+
164
+ For code tests see:
165
+
166
+ * ``dbg_PyTuple_SetItem_steals_replace `` in ``src/cpy/Containers/DebugContainers.c ``.
167
+ * ``test_PyTuple_SetItem_steals_replace `` in ``src/cpy/RefCount/cRefCount.c ``.
168
+ * ``tests.unit.test_c_ref_count.test_test_PyTuple_SetItem_steals_replece ``.
169
+
119
170
120
171
121
172
``PyTuple_SET_ITEM() ``
122
- ---------------------
173
+ ----------------------
123
174
124
- `PyTuple_SetItem() < https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SET_ITEM > `_
175
+ `PyTuple_SET_ITEM() `_
125
176
126
177
127
178
``Py_BuildValue() ``
128
179
-------------------
129
180
130
- `Py_BuildValue() < https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue > `_
181
+ `Py_BuildValue() `_
131
182
132
183
133
184
``PyTuple_Pack() ``
134
185
------------------
135
186
136
- `PyTuple_Pack() <https://docs.python.org/3/c-api/tuple.html#c.PyTuple_Pack >`_
137
- is a wrapper around
138
- `Py_BuildValue() <https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue >`_
139
- so is not explored any further.
140
-
187
+ `PyTuple_Pack() `_ is a wrapper around `Py_BuildValue() `_ so is not explored any further.
141
188
142
189
-----------------------
143
190
List
0 commit comments