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_tuple.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_tuple.cpp')
-rw-r--r-- | yql/essentials/udfs/common/python/bindings/py_tuple.cpp | 61 |
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); +} + +} |