diff options
author | prettyboy <prettyboy@yandex-team.com> | 2023-09-08 00:22:12 +0300 |
---|---|---|
committer | prettyboy <prettyboy@yandex-team.com> | 2023-09-08 00:46:04 +0300 |
commit | 3a6cd865171eed9b89bf536cd242285f8b583a91 (patch) | |
tree | 25e2756c125f7484fb118e0d5724212199662389 /library/cpp/pybind/module.cpp | |
parent | 67f3f216950849664a29035458cfaa5d12a62846 (diff) | |
download | ydb-3a6cd865171eed9b89bf536cd242285f8b583a91.tar.gz |
[build/plugins/ytest] Allow prebuilt linters for opensource
Без этого, ydb или не сможет запускать flake8 с помощью ya make.
Или к ним поедет сборка flake8.
Возможно последнее и не так плохо, но сейчас предлагается пока так
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 |