py_tuple.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include "py_tuple.h"
  2. #include "py_cast.h"
  3. #include "py_errors.h"
  4. #include "py_gil.h"
  5. #include "py_utils.h"
  6. #include <yql/essentials/public/udf/udf_value.h>
  7. #include <yql/essentials/public/udf/udf_value_builder.h>
  8. #include <yql/essentials/public/udf/udf_type_inspection.h>
  9. #include <yql/essentials/public/udf/udf_terminator.h>
  10. using namespace NKikimr;
  11. namespace NPython {
  12. TPyObjectPtr ToPyTuple(const TPyCastContext::TPtr& ctx, const NUdf::TType* type, const NUdf::TUnboxedValuePod& value)
  13. {
  14. const NUdf::TTupleTypeInspector inspector(*ctx->PyCtx->TypeInfoHelper, type);
  15. const auto elementsCount = inspector.GetElementsCount();
  16. const TPyObjectPtr tuple(PyTuple_New(elementsCount));
  17. if (auto ptr = value.GetElements()) {
  18. for (ui32 i = 0U; i < elementsCount; ++i) {
  19. auto item = ToPyObject(ctx, inspector.GetElementType(i), *ptr++);
  20. PyTuple_SET_ITEM(tuple.Get(), i, item.Release());
  21. }
  22. } else {
  23. for (ui32 i = 0U; i < elementsCount; ++i) {
  24. auto item = ToPyObject(ctx, inspector.GetElementType(i), value.GetElement(i));
  25. PyTuple_SET_ITEM(tuple.Get(), i, item.Release());
  26. }
  27. }
  28. return tuple;
  29. }
  30. NUdf::TUnboxedValue FromPyTuple(const TPyCastContext::TPtr& ctx, const NUdf::TType* type, PyObject* value)
  31. {
  32. const NUdf::TTupleTypeInspector inspector(*ctx->PyCtx->TypeInfoHelper, type);
  33. if (const TPyObjectPtr fast = PySequence_Fast(value, "Expected tuple or list.")) {
  34. const Py_ssize_t itemsCount = PySequence_Fast_GET_SIZE(fast.Get());
  35. if (itemsCount < 0 || inspector.GetElementsCount() != itemsCount) {
  36. throw yexception() << "Tuple elements count mismatch.";
  37. }
  38. NUdf::TUnboxedValue* tuple_items = nullptr;
  39. const auto tuple = ctx->ValueBuilder->NewArray(inspector.GetElementsCount(), tuple_items);
  40. for (Py_ssize_t i = 0; i < itemsCount; i++) {
  41. const auto item = PySequence_Fast_GET_ITEM(fast.Get(), i);
  42. *tuple_items++ = FromPyObject(ctx, inspector.GetElementType(i), item);
  43. }
  44. return tuple;
  45. }
  46. throw yexception() << "Expected Tuple or Sequence but got: " << PyObjectRepr(value);
  47. }
  48. }