From e0094c4ad6964e11564777bc0d859c68d8aa9de2 Mon Sep 17 00:00:00 2001
From: say <say@yandex-team.com>
Date: Tue, 14 Feb 2023 17:24:43 +0300
Subject: Migrate black linter on custom_lint pipeline

---
 library/cpp/pybind/module.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 library/cpp/pybind/module.cpp

(limited to 'library/cpp/pybind/module.cpp')

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
-- 
cgit v1.2.3