Skip to content

Commit 8ad05dc

Browse files
committed
Add index experiments. WIP on refcount_and_containers.rst
1 parent 2ed1177 commit 8ad05dc

File tree

3 files changed

+88
-12
lines changed

3 files changed

+88
-12
lines changed

doc/sphinx/source/_index_styles.rst

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
..
3+
Explore different index styles.
4+
5+
======================================
6+
Index Styles
7+
======================================
8+
9+
See: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-index
10+
11+
.. index::
12+
single: execution; context
13+
pair: module; __main__
14+
pair: module; sys
15+
triple: module; search; path
16+
seealso: scope
17+
18+
19+
----------------------
20+
Inline Index Entries
21+
----------------------
22+
23+
This is a normal reStructuredText :index:`paragraph` that contains several :index:`index entries <pair: index; entry>`.
24+
25+
26+

doc/sphinx/source/index.rst

+3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ Coding Patterns for Python Extensions
3535
miscellaneous
3636
further_reading
3737
todo
38+
_index_styles
3839
HISTORY
3940

4041
Search
4142
==================
4243

44+
* :ref:`genindex`
45+
* :ref:`modindex`
4346
* :ref:`search`

doc/sphinx/source/refcount_and_containers.rst

+59-12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
.. toctree::
55
:maxdepth: 3
66

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+
716
.. _chapter_refcount_and_containers:
817

918
======================================
@@ -56,7 +65,7 @@ Here is an example of exploring reference counts and tuples.
5665
assert(Py_REFCNT(container) == 1);
5766
5867
/* Create a new string. */
59-
PyObject *value_0 = new_unique_string(__FUNCTION__);
68+
PyObject *value_0 = new_unique_string(__FUNCTION__, NULL);
6069
assert(Py_REFCNT(value_0) == 1);
6170
6271
/* Set it as tuple[0].
@@ -101,10 +110,10 @@ The Python documentation for the `Tuple API <https://docs.python.org/3/c-api/tup
101110
* - Python C API
102111
- Behaviour
103112
- Notes
104-
* - `PyTuple_SetItem() <https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SetItem>`_
113+
* - `PyTuple_SetItem()`_
105114
- Steals, decrements the reference count of the original.
106115
- More stuff.
107-
* - `PyTuple_SET_ITEM() <https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SET_ITEM>`_
116+
* - `PyTuple_SET_ITEM()`_
108117
- Steals, leaks original.
109118
- **Contrary** to the documentation this leaks.
110119
* - ``Py_BuildValue("(s)", val)``
@@ -115,29 +124,67 @@ The Python documentation for the `Tuple API <https://docs.python.org/3/c-api/tup
115124
``PyTuple_SetItem()``
116125
---------------------
117126

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+
119170

120171

121172
``PyTuple_SET_ITEM()``
122-
---------------------
173+
----------------------
123174

124-
`PyTuple_SetItem() <https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SET_ITEM>`_
175+
`PyTuple_SET_ITEM()`_
125176

126177

127178
``Py_BuildValue()``
128179
-------------------
129180

130-
`Py_BuildValue() <https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue>`_
181+
`Py_BuildValue()`_
131182

132183

133184
``PyTuple_Pack()``
134185
------------------
135186

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.
141188

142189
-----------------------
143190
List

0 commit comments

Comments
 (0)