Message352072
Joannah Nanjekye asked me to have a look at this issue.
The existing Py_AtExit() C function is very low-level: it's called very late in Py_Finalize(), when the Python runtime is already destroyed.
I understand that the need here is to call C code which would still like to access the Python C API.
I propose the following C API:
void Py_AtExitRegister(PyObject* (*func) (void *data), void *data)
which would call func(data).
The return type is void since I don't see any practical way to log an useful warning if a function fails: we only gets its memory address, we cannot log that. The callback function ('func') should be responsible to log errors itself (ex: using PySys_WriteStderr which writes into sys.stderr).
Neil:
> It would be handy to have a C API that registered an atexit function, similar to what calling atexit.register does. This API could be used by C extension modules to register atexit functions.
The PyModuleDef already has 2 slots to call code at Python exit:
void m_clear(PyObject *module)
and:
void m_free(void *data).
But these callbacks can be late in Py_Finalize(), while Python runtime is being destroyed: when all modules are unloaded.
atexit.register() callbacks are different: they are called "early" in Py_Finalize(), when Python is still fully working.
I guess that Py_AtExitRegister() callbacks should also be called when Python is still fully working, right?
Apart C extensions, Py_AtExitRegister() also sounds interesting when Python is embedded in an application. For example, if you call Py_Main() or Py_RunMain(), you cannot easily execute arbitrary C code just before Py_Finalize().
Antoine:
> Calling "atexit.register" using the C API isn't very difficult. The annoying part is to wrap a simple C function pointer in a callable PyObject (I don't think there is a simple C API for that).
We could store C callbacks as C function pointers. We can have 2 lists of functions in the atexit module: one for Python function, one for C functions (registered using the C API). I would suggest to call Python functions first, and then call C functions.
--
I changed my mind, and I now consider that adding a public function would be useful. Sorry, first I misunderstood the use cases. |
|
| Date |
User |
Action |
Args |
| 2019-09-12 09:27:32 | vstinner | set | recipients:
+ vstinner, nascheme, pitrou, eric.snow, serhiy.storchaka, pablogsal |
| 2019-09-12 09:27:32 | vstinner | set | messageid: <1568280452.15.0.878770501973.issue32312@roundup.psfhosted.org> |
| 2019-09-12 09:27:32 | vstinner | link | issue32312 messages |
| 2019-09-12 09:27:31 | vstinner | create | |
|