diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yson/node/pybind/node.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yson/node/pybind/node.cpp')
-rw-r--r-- | library/cpp/yson/node/pybind/node.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/library/cpp/yson/node/pybind/node.cpp b/library/cpp/yson/node/pybind/node.cpp new file mode 100644 index 0000000000..79beba3647 --- /dev/null +++ b/library/cpp/yson/node/pybind/node.cpp @@ -0,0 +1,105 @@ +#include "node.h" + +#include <library/cpp/yson/node/node.h> + +#include <library/cpp/pybind/cast.h> + +#include <Python.h> + +namespace NYT { + + PyObject* BuildPyObject(const TNode& node) { + switch (node.GetType()) { + case TNode::Bool: + return NPyBind::BuildPyObject(node.AsBool()); + case TNode::Int64: + return NPyBind::BuildPyObject(node.AsInt64()); + case TNode::Uint64: + return NPyBind::BuildPyObject(node.AsUint64()); + case TNode::Double: + return NPyBind::BuildPyObject(node.AsDouble()); + case TNode::String: + return NPyBind::BuildPyObject(node.AsString()); + case TNode::List: + return NPyBind::BuildPyObject(node.AsList()); + case TNode::Map: + return NPyBind::BuildPyObject(node.AsMap()); + case TNode::Null: + Py_RETURN_NONE; + case TNode::Undefined: + ythrow TNode::TTypeError() << "BuildPyObject called for undefined TNode"; + } + } + +} // namespace NYT + +namespace NPyBind { + + template <> + bool FromPyObject(PyObject* obj, NYT::TNode& res) { + if (obj == Py_None) { + res = NYT::TNode::CreateEntity(); + return true; + } + if (PyBool_Check(obj)) { + res = false; + return FromPyObject(obj, res.As<bool>()); + } + if (PyFloat_Check(obj)) { + res = 0.0; + return FromPyObject(obj, res.As<double>()); + } +#if PY_MAJOR_VERSION < 3 + if (PyString_Check(obj)) { + res = TString(); + return FromPyObject(obj, res.As<TString>()); + } +#else + if (PyUnicode_Check(obj)) { + res = TString(); + return FromPyObject(obj, res.As<TString>()); + } + if (PyBytes_Check(obj)) { + res = TString(); + return FromPyObject(obj, res.As<TString>()); + } +#endif + if (PyList_Check(obj)) { + res = NYT::TNode::CreateList(); + return FromPyObject(obj, res.AsList()); + } + if (PyDict_Check(obj)) { + res = NYT::TNode::CreateMap(); + return FromPyObject(obj, res.AsMap()); + } +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(obj)) { + auto valAsLong = PyInt_AsLong(obj); + if (valAsLong == -1 && PyErr_Occurred()) { + return false; + } + res = valAsLong; + return true; + } +#endif + if (PyLong_Check(obj)) { + int overflow = 0; + auto valAsLong = PyLong_AsLongAndOverflow(obj, &overflow); + if (!overflow) { + if (valAsLong == -1 && PyErr_Occurred()) { + return false; + } + res = valAsLong; + return true; + } + auto valAsULong = PyLong_AsUnsignedLong(obj); + if (valAsULong == static_cast<decltype(valAsULong)>(-1) && PyErr_Occurred()) { + return false; + } + res = valAsULong; + return true; + } + return false; + } + +} // namespace NPyBind |