From c5083652ad1ba10d4d1703b42ba6674409aab6fc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 28 Dec 2020 21:05:03 +0100 Subject: [PATCH 1/9] bpo-42048: Document AC's defining_class converter --- Doc/howto/clinic.rst | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 50041829b8c388..2c5c226d47afd7 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1206,6 +1206,41 @@ type for ``self``, it's best to create your own converter, subclassing [clinic start generated code]*/ +Using a "defining class" converter +---------------------------------- + +Argument Clinic facilitates gaining access to the defining class of a method. +This is useful for heap type methods that need to fetch module level state. +Example from `Modules/zlibmodule.c`:: + + /*[clinic input] + zlib.Compress.compress + + cls: defining_class + data: Py_buffer + / + ... + [clinic start generated code]*/ + static PyObject * + zlib_Compress_compress_impl(...) + /*[clinic end generated code ...]*/ + { + zlibstate *state = PyType_GetModuleState(cls) + + +Each method may only have one argument using this converter, and it must appear +after `self`, or, if `self` is not used, as the first argument. The argument +will be of type `PyTypeObject *`. + +When used, Argument Clinic will select `METH_FASTCALL | METH_KEYWORDS | +METH_METHOD` as the calling convention. The argument will not appear in +`__text_signature__`. + +The `defining_class` converter is not compatible with `__init__` and `__new__` +methods, which cannot use the `METH_METHOD` convention. + +See also PEP 573. + Writing a custom converter -------------------------- From dedc1150ddce380e9daa266c7e24597c1df4f1d8 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 28 Dec 2020 22:15:17 +0100 Subject: [PATCH 2/9] Fix inline literals --- Doc/howto/clinic.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2c5c226d47afd7..a9ed20ae795779 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1211,7 +1211,7 @@ Using a "defining class" converter Argument Clinic facilitates gaining access to the defining class of a method. This is useful for heap type methods that need to fetch module level state. -Example from `Modules/zlibmodule.c`:: +Example from ``Modules/zlibmodule.c``:: /*[clinic input] zlib.Compress.compress @@ -1229,15 +1229,15 @@ Example from `Modules/zlibmodule.c`:: Each method may only have one argument using this converter, and it must appear -after `self`, or, if `self` is not used, as the first argument. The argument -will be of type `PyTypeObject *`. +after ``self``, or, if ``self`` is not used, as the first argument. The argument +will be of type ``PyTypeObject *``. -When used, Argument Clinic will select `METH_FASTCALL | METH_KEYWORDS | -METH_METHOD` as the calling convention. The argument will not appear in -`__text_signature__`. +When used, Argument Clinic will select ``METH_FASTCALL | METH_KEYWORDS | +METH_METHOD`` as the calling convention. The argument will not appear in +``__text_signature__``. -The `defining_class` converter is not compatible with `__init__` and `__new__` -methods, which cannot use the `METH_METHOD` convention. +The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` +methods, which cannot use the ``METH_METHOD`` convention. See also PEP 573. From 38df615fb81f10566d467875486745cd807386c9 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 20 Jan 2021 10:28:54 +0100 Subject: [PATCH 3/9] Use PEP marker Co-authored-by: Victor Stinner --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a9ed20ae795779..86b8886a3d2b7d 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1239,7 +1239,7 @@ METH_METHOD`` as the calling convention. The argument will not appear in The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` methods, which cannot use the ``METH_METHOD`` convention. -See also PEP 573. +See also :pep:`573`. Writing a custom converter From acf0f7e1d3475a2bfa8c2c7835fc4f7b4bd4ec24 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 11:00:47 +0100 Subject: [PATCH 4/9] Address review --- Doc/howto/clinic.rst | 59 +++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 86b8886a3d2b7d..462d37d8e885c1 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1210,35 +1210,64 @@ Using a "defining class" converter ---------------------------------- Argument Clinic facilitates gaining access to the defining class of a method. -This is useful for heap type methods that need to fetch module level state. -Example from ``Modules/zlibmodule.c``:: +This is useful for :ref:`heap type ` methods that need to fetch +module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new +heap type with a module. You can now use :c:func:`PyType_GetModuleState` on +the defining class to fetch the module state, for example from a module method. + +Example from ``Modules/zlibmodule.c``. First, ``defining_class`` is added to +the clinic input:: /*[clinic input] zlib.Compress.compress - cls: defining_class - data: Py_buffer - / - ... + cls: defining_class + data: Py_buffer + Binary data to be compressed. + / + + +After running the Argument Clinic tool, the following function signature is +generated:: + [clinic start generated code]*/ static PyObject * - zlib_Compress_compress_impl(...) - /*[clinic end generated code ...]*/ - { - zlibstate *state = PyType_GetModuleState(cls) + zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, + Py_buffer *data) + /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ -Each method may only have one argument using this converter, and it must appear -after ``self``, or, if ``self`` is not used, as the first argument. The argument -will be of type ``PyTypeObject *``. +The follwing code can now use ``PyType_GetModuleState(cls)`` to fetch the +module state:: -When used, Argument Clinic will select ``METH_FASTCALL | METH_KEYWORDS | -METH_METHOD`` as the calling convention. The argument will not appear in + zlibstate *state = PyType_GetModuleState(cls); + + +Each method may only have one argument using this converter, and it must appear +after ``self``, or, if ``self`` is not used, as the first argument. The argument +will be of type ``PyTypeObject *``. The argument will not appear in the ``__text_signature__``. The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` methods, which cannot use the ``METH_METHOD`` convention. +It is not possible to use ``defining_class`` with slot methods. In order to +fetch the module state from such methods, use ``_PyType_GetModuleByDef`` to +look up the module and then :c:func:`PyModule_GetState` to fetch the module +state. Example from the `setattro` slot method in +``Modules/_threadmodule.c``:: + + static int + local_setattro(localobject *self, PyObject *name, PyObject *v) + { + PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + thread_module_state *state = get_thread_state(module); + + +Note that ``_PyType_GetModuleByDef`` traverses the MRO cache, and therefore has +performance impact. + + See also :pep:`573`. From 08a7132d99e757b8d2bca10c8c6518ea121b288d Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 20 Jan 2021 11:27:11 +0100 Subject: [PATCH 5/9] Close the braces Co-authored-by: Victor Stinner --- Doc/howto/clinic.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 462d37d8e885c1..f8903793e70c83 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1262,6 +1262,8 @@ state. Example from the `setattro` slot method in { PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); thread_module_state *state = get_thread_state(module); + ... + } Note that ``_PyType_GetModuleByDef`` traverses the MRO cache, and therefore has From 580d00479b4f75f73bbcd63b2bbff2230de7640c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 11:28:55 +0100 Subject: [PATCH 6/9] Address review: Move note about _PyType_GetModuleByDef being slow --- Doc/howto/clinic.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index f8903793e70c83..5907e4f8a1045e 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1266,10 +1266,6 @@ state. Example from the `setattro` slot method in } -Note that ``_PyType_GetModuleByDef`` traverses the MRO cache, and therefore has -performance impact. - - See also :pep:`573`. From 19b306f6cdd7034ea71ecfd4412e224cd1334206 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 11:33:29 +0100 Subject: [PATCH 7/9] Fix .rst bug --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 5907e4f8a1045e..2712ef1d4e49e2 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1230,7 +1230,7 @@ the clinic input:: After running the Argument Clinic tool, the following function signature is generated:: - [clinic start generated code]*/ + /*[clinic start generated code]*/ static PyObject * zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, Py_buffer *data) From 97ec8e8707f42718782c02bc566e0dff1a101661 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 20 Jan 2021 12:01:19 +0100 Subject: [PATCH 8/9] Fix typo: follwing => following Co-authored-by: Victor Stinner --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2712ef1d4e49e2..5951c5214f04e0 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1237,7 +1237,7 @@ generated:: /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ -The follwing code can now use ``PyType_GetModuleState(cls)`` to fetch the +The following code can now use ``PyType_GetModuleState(cls)`` to fetch the module state:: zlibstate *state = PyType_GetModuleState(cls); From 50a9143e113d7c4505f93f054fe1e550023d2d15 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 12:02:30 +0100 Subject: [PATCH 9/9] Fix .rst bug: default role used --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 5951c5214f04e0..3a3653a5ee3a3e 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1254,7 +1254,7 @@ methods, which cannot use the ``METH_METHOD`` convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use ``_PyType_GetModuleByDef`` to look up the module and then :c:func:`PyModule_GetState` to fetch the module -state. Example from the `setattro` slot method in +state. Example from the ``setattro`` slot method in ``Modules/_threadmodule.c``:: static int