aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/python/bindings/py_utils.cpp
diff options
context:
space:
mode:
authorimunkin <imunkin@yandex-team.com>2024-11-08 10:00:23 +0300
committerimunkin <imunkin@yandex-team.com>2024-11-08 10:12:13 +0300
commita784a2f943d6e15caa6241e2e96d80aac6dbf375 (patch)
tree05f1e5366c916b988a8afb75bdab8ddeee0f6e6d /yql/essentials/udfs/common/python/bindings/py_utils.cpp
parentd70137a7b530ccaa52834274913bbb5a3d1ca06e (diff)
downloadydb-a784a2f943d6e15caa6241e2e96d80aac6dbf375.tar.gz
Move yql/udfs/common/ to /yql/essentials YQL-19206
Except the following directories: * clickhouse/client * datetime * knn * roaring commit_hash:c7da95636144d28db109d6b17ddc762e9bacb59f
Diffstat (limited to 'yql/essentials/udfs/common/python/bindings/py_utils.cpp')
-rw-r--r--yql/essentials/udfs/common/python/bindings/py_utils.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_utils.cpp b/yql/essentials/udfs/common/python/bindings/py_utils.cpp
new file mode 100644
index 0000000000..d1e0e8b484
--- /dev/null
+++ b/yql/essentials/udfs/common/python/bindings/py_utils.cpp
@@ -0,0 +1,89 @@
+#include "py_utils.h"
+#include "py_cast.h"
+#include "py_errors.h"
+#include "py_gil.h"
+
+#include <util/generic/yexception.h>
+#include <util/string/split.h>
+
+#include <regex>
+
+
+namespace NPython {
+
+TPyObjectPtr PyRepr(TStringBuf asciiStr, bool intern) {
+ for (auto c : asciiStr) {
+ Y_ABORT_UNLESS((c&0x80) == 0, "expected ascii");
+ }
+
+ Py_ssize_t size = static_cast<Py_ssize_t>(asciiStr.size());
+#if PY_MAJOR_VERSION >= 3
+ TPyObjectPtr pyStr = PyUnicode_FromStringAndSize(asciiStr.data(), size);
+#else
+ TPyObjectPtr pyStr = PyString_FromStringAndSize(asciiStr.data(), size);
+#endif
+ Y_ABORT_UNLESS(pyStr, "Can't get repr string");
+ if (!intern) {
+ return pyStr;
+ }
+
+ PyObject* tmp = pyStr.Release();
+#if PY_MAJOR_VERSION >= 3
+ PyUnicode_InternInPlace(&tmp);
+#else
+ PyString_InternInPlace(&tmp);
+#endif
+ return TPyObjectPtr(tmp);
+}
+
+TString PyObjectRepr(PyObject* value) {
+ static constexpr size_t maxLen = 1000;
+ static constexpr std::string_view truncSuffix = "(truncated)";
+ const TPyObjectPtr repr(PyObject_Repr(value));
+ if (!repr) {
+ return TString("repr error: ") + GetLastErrorAsString();
+ }
+
+ TString string;
+ if (!TryPyCast(repr.Get(), string)) {
+ string = "can't get repr as string";
+ }
+ if (string.size() > maxLen) {
+ string.resize(maxLen - truncSuffix.size());
+ string += truncSuffix;
+ }
+ return string;
+}
+
+bool HasEncodingCookie(const TString& source) {
+ //
+ // To define a source code encoding, a magic comment must be placed
+ // into the source files either as first or second line in the file.
+ //
+ // See https://www.python.org/dev/peps/pep-0263 for more details.
+ //
+
+ static std::regex encodingRe(
+ "^[ \\t\\v]*#.*?coding[:=][ \\t]*[-_.a-zA-Z0-9]+.*");
+
+ int i = 0;
+ for (const auto& it: StringSplitter(source).Split('\n')) {
+ if (i++ == 2) break;
+
+ TStringBuf line = it.Token();
+ if (std::regex_match(line.begin(), line.end(), encodingRe)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void PyCleanup() {
+ TPyGilLocker lock;
+ PyErr_Clear();
+ PySys_SetObject("last_type", Py_None);
+ PySys_SetObject("last_value", Py_None);
+ PySys_SetObject("last_traceback", Py_None);
+}
+
+} // namspace NPython