diff options
author | imunkin <imunkin@yandex-team.com> | 2024-11-08 10:00:23 +0300 |
---|---|---|
committer | imunkin <imunkin@yandex-team.com> | 2024-11-08 10:12:13 +0300 |
commit | a784a2f943d6e15caa6241e2e96d80aac6dbf375 (patch) | |
tree | 05f1e5366c916b988a8afb75bdab8ddeee0f6e6d /yql/essentials/udfs/common/python/bindings/py_utils.cpp | |
parent | d70137a7b530ccaa52834274913bbb5a3d1ca06e (diff) | |
download | ydb-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.cpp | 89 |
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 |