Skip to content

Commit 47d44b3

Browse files
corona10hugovkezio-melottierlend-aaslandAlexWaygood
authored
Add "how to" for the setter Argument Clinic directive (#1245)
--------- Co-authored-by: Hugo van Kemenade <[email protected]> Co-authored-by: Ezio Melotti <[email protected]> Co-authored-by: Erlend E. Aasland <[email protected]> Co-authored-by: Alex Waygood <[email protected]>
1 parent 2be71b8 commit 47d44b3

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

Diff for: development-tools/clinic.rst

+41-17
Original file line numberDiff line numberDiff line change
@@ -2030,52 +2030,76 @@ The generated glue code looks like this:
20302030
.. versionadded:: 3.13
20312031

20322032

2033-
.. _clinic-howto-getter:
2033+
.. _clinic-howto-pygetsetdef:
20342034

2035-
How to generate a getter
2036-
------------------------
2035+
How to declare ``PyGetSetDef`` ("getter/setter") functions
2036+
----------------------------------------------------------
20372037

2038-
"Getters" are C functions that facilitate property-like access for a class.
2039-
See :c:type:`getter <PyGetSetDef>` for details.
2040-
You can use the ``@getter`` directive to generate an "impl" function for a
2041-
getter using Argument Clinic.
2038+
"Getters" and "setters" are C functions defined in a :c:type:`PyGetSetDef` struct
2039+
that facilitate :py:class:`property`-like access for a class.
2040+
You can use the ``@getter`` and ``@setter`` directives to generate
2041+
"impl" functions using Argument Clinic.
20422042

2043-
This example -- taken from :cpy-file:`Modules/_io/bufferedio.c` --
2044-
shows the use of ``@getter`` in combination with
2043+
This example --- taken from :cpy-file:`Modules/_io/textio.c` ---
2044+
shows the use of ``@getter`` and ``@setter`` in combination with
20452045
the :ref:`@critical_section <clinic-howto-critical-sections>` directive
20462046
(which achieves thread safety without causing deadlocks between threads)::
20472047

20482048
/*[clinic input]
20492049
@critical_section
20502050
@getter
2051-
_io._Buffered.closed
2051+
_io.TextIOWrapper._CHUNK_SIZE
2052+
[clinic start generated code]*/
2053+
2054+
/*[clinic input]
2055+
@critical_section
2056+
@setter
2057+
_io.TextIOWrapper._CHUNK_SIZE
20522058
[clinic start generated code]*/
20532059

20542060
The generated glue code looks like this:
20552061

20562062
.. code-block:: c
20572063
20582064
static PyObject *
2059-
_io__Buffered_closed_get(buffered *self, void *context)
2065+
_io_TextIOWrapper__CHUNK_SIZE_get(textio *self, void *Py_UNUSED(context))
20602066
{
20612067
PyObject *return_value = NULL;
20622068
20632069
Py_BEGIN_CRITICAL_SECTION(self);
2064-
return_value = _io__Buffered_closed_get_impl(self);
2070+
return_value = _io_TextIOWrapper__CHUNK_SIZE_get_impl(self);
20652071
Py_END_CRITICAL_SECTION();
20662072
20672073
return return_value;
20682074
}
20692075
2076+
static int
2077+
_io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED(context))
2078+
{
2079+
int return_value;
2080+
Py_BEGIN_CRITICAL_SECTION(self);
2081+
return_value = _io_TextIOWrapper__CHUNK_SIZE_set_impl(self, value);
2082+
Py_END_CRITICAL_SECTION();
2083+
return return_value;
2084+
}
2085+
2086+
.. note::
2087+
2088+
Getters and setters must be declared as separate functions.
2089+
The *value* parameter for a "setter" is added implicitly by Argument Clinic.
2090+
20702091
And then the implementation will work the same as a Python method which is
2071-
decorated by :py:class:`property`.
2092+
decorated by :py:class:`property`:
20722093

20732094
.. code-block:: pycon
20742095
2075-
>>> import _io
2076-
>>> a = _io._BufferedIOBase()
2077-
>>> a.closed
2078-
False
2096+
>>> import sys, _io
2097+
>>> a = _io.TextIOWrapper(sys.stdout)
2098+
>>> a._CHUNK_SIZE
2099+
8192
2100+
>>> a._CHUNK_SIZE = 30
2101+
>>> a._CHUNK_SIZE
2102+
30
20792103
20802104
.. versionadded:: 3.13
20812105

0 commit comments

Comments
 (0)