aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/pybind/module.cpp
diff options
context:
space:
mode:
authorprettyboy <prettyboy@yandex-team.com>2023-09-08 00:22:12 +0300
committerprettyboy <prettyboy@yandex-team.com>2023-09-08 00:46:04 +0300
commit3a6cd865171eed9b89bf536cd242285f8b583a91 (patch)
tree25e2756c125f7484fb118e0d5724212199662389 /library/cpp/pybind/module.cpp
parent67f3f216950849664a29035458cfaa5d12a62846 (diff)
downloadydb-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.cpp72
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