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_resource.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_resource.cpp')
-rw-r--r-- | yql/essentials/udfs/common/python/bindings/py_resource.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_resource.cpp b/yql/essentials/udfs/common/python/bindings/py_resource.cpp new file mode 100644 index 0000000000..ebb096029a --- /dev/null +++ b/yql/essentials/udfs/common/python/bindings/py_resource.cpp @@ -0,0 +1,116 @@ +#include "py_resource.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_type_inspection.h> + +using namespace NKikimr; + +namespace NPython { +namespace { + +void DestroyResourceCapsule(PyObject* obj) { + if (auto* ptr = PyCapsule_GetPointer(obj, ResourceCapsuleName)) { + delete reinterpret_cast<NUdf::TUnboxedValue*>(ptr); + } +} + +///////////////////////////////////////////////////////////////////////////// +// TResource +///////////////////////////////////////////////////////////////////////////// +class TResource final: public NUdf::TBoxedValue +{ +public: + TResource(PyObject* value, const NUdf::TStringRef& tag) + : Value_(value, TPyObjectPtr::ADD_REF), Tag_(tag) + { + } + + ~TResource() { + TPyGilLocker lock; + Value_.Reset(); + } + +private: + NUdf::TStringRef GetResourceTag() const override { + return Tag_; + } + + void* GetResource() final { + return Value_.Get(); + } + + TPyObjectPtr Value_; + const NUdf::TStringRef Tag_; +}; + +} // namespace + +const char ResourceCapsuleName[] = "YqlResourceCapsule"; + +TPyObjectPtr ToPyResource( + const TPyCastContext::TPtr& ctx, + const NUdf::TType* type, + const NUdf::TUnboxedValuePod& value) +{ +// TODO NILE-43 +#if false && UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15) + NUdf::TResourceTypeInspector inpector(*ctx->PyCtx->TypeInfoHelper, type); + auto tag = inpector.GetTag(); + if (tag == ctx->PyCtx->ResourceTag) { + PyObject* p = reinterpret_cast<PyObject*>(value.GetResource()); + return TPyObjectPtr(p, TPyObjectPtr::ADD_REF); + } +#else + Y_UNUSED(type); + if (value.GetResourceTag() == ctx->PyCtx->ResourceTag) { + PyObject* p = reinterpret_cast<PyObject*>(value.GetResource()); + return TPyObjectPtr(p, TPyObjectPtr::ADD_REF); + } +#endif + auto resource = MakeHolder<NUdf::TUnboxedValue>(value); + + return PyCapsule_New(resource.Release(), ResourceCapsuleName, &DestroyResourceCapsule); +} + +NUdf::TUnboxedValue FromPyResource( + const TPyCastContext::TPtr& ctx, + const NUdf::TType* type, PyObject* value) +{ +// TODO NILE-43 +#if false && UDF_ABI_COMPATIBILITY_VERSION_CURRENT >= UDF_ABI_COMPATIBILITY_VERSION(2, 15) + NUdf::TResourceTypeInspector inpector(*ctx->PyCtx->TypeInfoHelper, type); + auto tag = inpector.GetTag(); + if (tag == ctx->PyCtx->ResourceTag) { + return NUdf::TUnboxedValuePod(new TResource(value, ctx->PyCtx->ResourceTag)); + } + + if (PyCapsule_IsValid(value, ResourceCapsuleName)) { + auto* resource = reinterpret_cast<NUdf::TUnboxedValue*>(PyCapsule_GetPointer(value, ResourceCapsuleName)); + auto valueTag = resource->GetResourceTag(); + if (valueTag != tag) { + throw yexception() << "Mismatch of resource tag, expected: " + << tag << ", got: " << valueTag; + } + + return *resource; + } + + throw yexception() << "Python object " << PyObjectRepr(value) \ + << " is not a valid resource with tag " << tag; +#else + Y_UNUSED(type); + if (PyCapsule_CheckExact(value)) { + if (!PyCapsule_IsValid(value, ResourceCapsuleName)) { + throw yexception() << "Python object " << PyObjectRepr(value) << " is not a valid resource capsule"; + } + return *reinterpret_cast<NUdf::TUnboxedValue*>(PyCapsule_GetPointer(value, ResourceCapsuleName)); + } + return NUdf::TUnboxedValuePod(new TResource(value, ctx->PyCtx->ResourceTag)); +#endif +} + +} // namspace NPython |