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_variant.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_variant.cpp')
-rw-r--r-- | yql/essentials/udfs/common/python/bindings/py_variant.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_variant.cpp b/yql/essentials/udfs/common/python/bindings/py_variant.cpp new file mode 100644 index 0000000000..ab222b3432 --- /dev/null +++ b/yql/essentials/udfs/common/python/bindings/py_variant.cpp @@ -0,0 +1,97 @@ +#include "py_variant.h" +#include "py_cast.h" +#include "py_errors.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> + + +using namespace NKikimr; + +namespace NPython { + +////////////////////////////////////////////////////////////////////////////// +// public functions +////////////////////////////////////////////////////////////////////////////// +TPyObjectPtr ToPyVariant( + const TPyCastContext::TPtr& castCtx, + const NUdf::TType* type, + const NUdf::TUnboxedValuePod& value) +{ + auto& th = *castCtx->PyCtx->TypeInfoHelper; + NUdf::TVariantTypeInspector varInsp(th, type); + const NUdf::TType* subType = varInsp.GetUnderlyingType(); + ui32 index = value.GetVariantIndex(); + auto item = value.GetVariantItem(); + + const NUdf::TType* itemType = nullptr; + if (auto tupleInsp = NUdf::TTupleTypeInspector(th, subType)) { + itemType = tupleInsp.GetElementType(index); + TPyObjectPtr pyIndex = PyCast<ui32>(index); + TPyObjectPtr pyItem = ToPyObject(castCtx, itemType, item); + return PyTuple_Pack(2, pyIndex.Get(), pyItem.Get()); + } else if (auto structInsp = NUdf::TStructTypeInspector(th, subType)) { + itemType = structInsp.GetMemberType(index); + TPyObjectPtr pyName = ToPyUnicode<NUdf::TStringRef>( + structInsp.GetMemberName(index)); + TPyObjectPtr pyItem = ToPyObject(castCtx, itemType, item); + return PyTuple_Pack(2, pyName.Get(), pyItem.Get()); + } + + throw yexception() << "Cannot get Variant item type"; +} + +NUdf::TUnboxedValue FromPyVariant( + const TPyCastContext::TPtr& castCtx, + const NUdf::TType* type, + PyObject* value) +{ + PY_ENSURE(PyTuple_Check(value), + "Expected to get Tuple, but got " << Py_TYPE(value)->tp_name); + + Py_ssize_t tupleSize = PyTuple_GET_SIZE(value); + PY_ENSURE(tupleSize == 2, + "Expected to get Tuple with 2 elements, but got " + << tupleSize << " elements"); + + auto& th = *castCtx->PyCtx->TypeInfoHelper; + NUdf::TVariantTypeInspector varInsp(th, type); + const NUdf::TType* subType = varInsp.GetUnderlyingType(); + + PyObject* el0 = PyTuple_GET_ITEM(value, 0); + PyObject* el1 = PyTuple_GET_ITEM(value, 1); + + ui32 index; + NUdf::TStringRef name; + if (TryPyCast(el0, index)) { + if (auto tupleInsp = NUdf::TTupleTypeInspector(th, subType)) { + PY_ENSURE(index < tupleInsp.GetElementsCount(), + "Index must be < " << tupleInsp.GetElementsCount() + << ", but got " << index); + auto* itemType = tupleInsp.GetElementType(index); + return castCtx->ValueBuilder->NewVariant(index, FromPyObject(castCtx, itemType, el1)); + } else { + throw yexception() << "Cannot convert " << PyObjectRepr(value) + << " underlying Variant type is not a Tuple"; + } + } else if (TryPyCast(el0, name)) { + if (auto structInsp = NUdf::TStructTypeInspector(th, subType)) { + ui32 index = structInsp.GetMemberIndex(name); + PY_ENSURE(index < structInsp.GetMembersCount(), + "Unknown member name: " << TStringBuf(name)); + auto* itemType = structInsp.GetMemberType(index); + return castCtx->ValueBuilder->NewVariant(index, FromPyObject(castCtx, itemType, el1)); + } else { + throw yexception() << "Cannot convert " << PyObjectRepr(value) + << " underlying Variant type is not a Struct"; + } + } else { + throw yexception() + << "Expected first Tuple element to either be an int " + "or a str, but got " << Py_TYPE(el0)->tp_name; + } +} + +} // namspace NPython |