From d61ac9dd9c819e974d8edb98c7689df9b119dafe Mon Sep 17 00:00:00 2001 From: Bruce Merry Date: Mon, 6 Nov 2017 09:22:35 +0200 Subject: [PATCH 1/2] Document using atexit for module destructors None of the three currently recommended approaches works on PyPy, due to it not garbage collecting things when you want it to. Added an example showing how to get interpreter shutdown callbacks using the Python atexit module, and added a note that the other approaches are not portable. --- docs/advanced/misc.rst | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index 87481ba32f..e7ae81794f 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -172,9 +172,19 @@ Module Destructors ================== pybind11 does not provide an explicit mechanism to invoke cleanup code at -module destruction time. In rare cases where such functionality is required, it -is possible to emulate it using Python capsules or weak references with a -destruction callback. +module destruction time. The Python :py:mod:`atexit` module [#f7]_ can be used +to register functions to be called at shutdown. + +.. code-block:: cpp + + auto atexit = py::module::import("atexit"); + atexit.attr("register")(py::cpp_function([]() { + // perform cleanup here -- this function is called with the GIL held + })); + +In rare cases where such functionality is required and :py:mod:`atexit` is +insufficient, it is possible to emulate it using Python capsules or weak +references with a destruction callback. .. code-block:: cpp @@ -216,6 +226,13 @@ avoids this issue involves weak reference with a cleanup callback: // Create a weak reference with a cleanup callback and initially leak it (void) py::weakref(m.attr("BaseClass"), cleanup_callback).release(); +.. note:: + + Only the :py:mod:`atexit` approach works on PyPy. The other approaches rely + on implementation details of CPython's garbage collection. + +.. [#f7] https://docs.python.org/3/library/atexit.html + Generating documentation using Sphinx ===================================== From 37a03cbe1c6df0cca049d61e5666263f23af4331 Mon Sep 17 00:00:00 2001 From: Bruce Merry Date: Tue, 7 Nov 2017 16:33:22 +0200 Subject: [PATCH 2/2] Redo atexit documentation The atexit example code is now only in the ..note for PyPy. --- docs/advanced/misc.rst | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index e7ae81794f..5faf11f0d2 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -172,19 +172,9 @@ Module Destructors ================== pybind11 does not provide an explicit mechanism to invoke cleanup code at -module destruction time. The Python :py:mod:`atexit` module [#f7]_ can be used -to register functions to be called at shutdown. - -.. code-block:: cpp - - auto atexit = py::module::import("atexit"); - atexit.attr("register")(py::cpp_function([]() { - // perform cleanup here -- this function is called with the GIL held - })); - -In rare cases where such functionality is required and :py:mod:`atexit` is -insufficient, it is possible to emulate it using Python capsules or weak -references with a destruction callback. +module destruction time. In rare cases where such functionality is required, it +is possible to emulate it using Python capsules or weak references with a +destruction callback. .. code-block:: cpp @@ -228,10 +218,18 @@ avoids this issue involves weak reference with a cleanup callback: .. note:: - Only the :py:mod:`atexit` approach works on PyPy. The other approaches rely - on implementation details of CPython's garbage collection. + PyPy (at least version 5.9) does not garbage collect objects when the + interpreter exits. An alternative approach (which also works on CPython) is to use + the :py:mod:`atexit` module [#f7]_, for example: + + .. code-block:: cpp + + auto atexit = py::module::import("atexit"); + atexit.attr("register")(py::cpp_function([]() { + // perform cleanup here -- this function is called with the GIL held + })); -.. [#f7] https://docs.python.org/3/library/atexit.html + .. [#f7] https://docs.python.org/3/library/atexit.html Generating documentation using Sphinx