diff options
author | say <say@yandex-team.com> | 2023-02-14 17:24:43 +0300 |
---|---|---|
committer | say <say@yandex-team.com> | 2023-02-14 17:24:43 +0300 |
commit | e0094c4ad6964e11564777bc0d859c68d8aa9de2 (patch) | |
tree | 5d2ad1a4df88da1f74385888891a2a5f9fbbc3ef /library/cpp/pybind/module.cpp | |
parent | 65a08c9fdece8dba50da8beb4d7c81447211dd45 (diff) | |
download | ydb-e0094c4ad6964e11564777bc0d859c68d8aa9de2.tar.gz |
Migrate black linter on custom_lint pipeline
Diffstat (limited to 'library/cpp/pybind/module.cpp')
-rw-r--r-- | library/cpp/pybind/module.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/library/cpp/pybind/module.cpp b/library/cpp/pybind/module.cpp new file mode 100644 index 0000000000..b7b003d3b0 --- /dev/null +++ b/library/cpp/pybind/module.cpp @@ -0,0 +1,72 @@ +#include "module.h" +#include "ptr.h" + +#include <util/generic/adaptor.h> + +namespace NPyBind { + +#if PY_MAJOR_VERSION >= 3 + namespace NPrivate { + struct TFinCallBacksHolder { + static TVector<TFinalizationCallBack>& GetCallBacks() { + static TVector<TFinalizationCallBack> res; + return res; + } + }; + + TAtExitRegistrar::TAtExitRegistrar(TPyObjectPtr module) { + TPyObjectPtr atExitModuleName(Py_BuildValue("s", "atexit"), true); + TPyObjectPtr atExitModule(PyImport_Import(atExitModuleName.Get())); + Y_VERIFY(atExitModule); + TPyObjectPtr finalizerFunc(PyObject_GetAttrString(module.Get(), "finalizer"), true); + Y_VERIFY(finalizerFunc); + TPyObjectPtr registerName(Py_BuildValue("s", "register"), true); + PyObject_CallMethodObjArgs(atExitModule.Get(), registerName.Get(), finalizerFunc.Get(), nullptr); + } + + TPyBindModuleRegistrar::TPyBindModuleRegistrar() { + TPyObjectPtr modules(PySys_GetObject("modules")); + Y_ENSURE(modules.Get()); + if (Module = NPrivate::CreatePyBindModule()) { + Y_VERIFY(0 == PyDict_SetItemString(modules.Get(), "pybind", Module.RefGet())); + } + AddFinalizationCallBack([this]() { + auto ptr = Module; + Y_UNUSED(ptr); + TPyObjectPtr modules(PySys_GetObject("modules")); + Y_ENSURE(modules.Get()); + TPyObjectPtr pyBindName(Py_BuildValue("s", "pybind")); + if (PyDict_Contains(modules.Get(), pyBindName.Get()) == 1) { + Y_VERIFY(0==PyDict_DelItemString(modules.Get(), "pybind")); + } + if (Module) { + //We have to untrack the module because some refs from him refers to gc-leaked errors + //see exceptions.cpp fore more info + PyObject_GC_UnTrack(Module.Get()); + Module.Drop(); + } + }); + } + + void AddFinalizationCallBack(TFinalizationCallBack callback) { + TFinCallBacksHolder::GetCallBacks().push_back(callback); + } + + int FinalizeAll() { + for (auto callback: Reversed(NPrivate::TFinCallBacksHolder::GetCallBacks())) { + callback(); + } + return 0; + } + } +#endif + + + TModuleHolder::TModuleHolder() + : Methods(1, new TVector<TMethodDef>) + { +#if PY_MAJOR_VERSION >= 3 + AddModuleMethod<TModuleMethodCaller<decltype(&NPrivate::FinalizeAll), &NPrivate::FinalizeAll>::Call>("finalizer"); +#endif + } +}//NPyBind |