static PyObject * call_state_registration_func(PyObject *mod, PyObject *args) { int i, ret; PyModuleDef *def = PyModule_GetDef(mod); if (def == NULL) { return NULL; } if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i)) return NULL; switch (i) { case 0: mod = PyState_FindModule(def); if (mod == NULL) { Py_RETURN_NONE; } return mod; case 1: ret = PyState_AddModule(mod, def); if (ret != 0) { return NULL; } break; case 2: ret = PyState_RemoveModule(def); if (ret != 0) { return NULL; } break; } Py_RETURN_NONE; }
static void atexit_callfuncs(void) { PyObject *exc_type = NULL, *exc_value, *exc_tb, *r; atexit_callback *cb; PyObject *module; atexitmodule_state *modstate; int i; module = PyState_FindModule(&atexitmodule); if (module == NULL) return; modstate = GET_ATEXIT_STATE(module); if (modstate->ncallbacks == 0) return; for (i = modstate->ncallbacks - 1; i >= 0; i--) { cb = modstate->atexit_callbacks[i]; if (cb == NULL) continue; r = PyObject_Call(cb->func, cb->args, cb->kwargs); Py_XDECREF(r); if (r == NULL) { /* Maintain the last exception, but don't leak if there are multiple exceptions. */ if (exc_type) { Py_DECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); } PyErr_Fetch(&exc_type, &exc_value, &exc_tb); if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { PySys_WriteStderr("Error in atexit._run_exitfuncs:\n"); PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); PyErr_Display(exc_type, exc_value, exc_tb); } } } atexit_cleanup(modstate); if (exc_type) PyErr_Restore(exc_type, exc_value, exc_tb); }