aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/python/bindings/py_tuple.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_tuple.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_tuple.cpp')
-rw-r--r--yql/essentials/udfs/common/python/bindings/py_tuple.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_tuple.cpp b/yql/essentials/udfs/common/python/bindings/py_tuple.cpp
new file mode 100644
index 0000000000..6cef25ea47
--- /dev/null
+++ b/yql/essentials/udfs/common/python/bindings/py_tuple.cpp
@@ -0,0 +1,61 @@
+#include "py_tuple.h"
+#include "py_cast.h"
+#include "py_errors.h"
+#include "py_gil.h"
+#include "py_utils.h"
+
+#include <yql/essentials/public/udf/udf_value.h>
+#include <yql/essentials/public/udf/udf_value_builder.h>
+#include <yql/essentials/public/udf/udf_type_inspection.h>
+#include <yql/essentials/public/udf/udf_terminator.h>
+
+using namespace NKikimr;
+
+namespace NPython {
+
+TPyObjectPtr ToPyTuple(const TPyCastContext::TPtr& ctx, const NUdf::TType* type, const NUdf::TUnboxedValuePod& value)
+{
+ const NUdf::TTupleTypeInspector inspector(*ctx->PyCtx->TypeInfoHelper, type);
+ const auto elementsCount = inspector.GetElementsCount();
+
+ const TPyObjectPtr tuple(PyTuple_New(elementsCount));
+
+ if (auto ptr = value.GetElements()) {
+ for (ui32 i = 0U; i < elementsCount; ++i) {
+ auto item = ToPyObject(ctx, inspector.GetElementType(i), *ptr++);
+ PyTuple_SET_ITEM(tuple.Get(), i, item.Release());
+ }
+ } else {
+ for (ui32 i = 0U; i < elementsCount; ++i) {
+ auto item = ToPyObject(ctx, inspector.GetElementType(i), value.GetElement(i));
+ PyTuple_SET_ITEM(tuple.Get(), i, item.Release());
+ }
+ }
+
+ return tuple;
+}
+
+NUdf::TUnboxedValue FromPyTuple(const TPyCastContext::TPtr& ctx, const NUdf::TType* type, PyObject* value)
+{
+ const NUdf::TTupleTypeInspector inspector(*ctx->PyCtx->TypeInfoHelper, type);
+ if (const TPyObjectPtr fast = PySequence_Fast(value, "Expected tuple or list.")) {
+ const Py_ssize_t itemsCount = PySequence_Fast_GET_SIZE(fast.Get());
+
+ if (itemsCount < 0 || inspector.GetElementsCount() != itemsCount) {
+ throw yexception() << "Tuple elements count mismatch.";
+ }
+
+ NUdf::TUnboxedValue* tuple_items = nullptr;
+ const auto tuple = ctx->ValueBuilder->NewArray(inspector.GetElementsCount(), tuple_items);
+ for (Py_ssize_t i = 0; i < itemsCount; i++) {
+ const auto item = PySequence_Fast_GET_ITEM(fast.Get(), i);
+ *tuple_items++ = FromPyObject(ctx, inspector.GetElementType(i), item);
+ }
+
+ return tuple;
+ }
+
+ throw yexception() << "Expected Tuple or Sequence but got: " << PyObjectRepr(value);
+}
+
+}