diff options
author | vvvv <[email protected]> | 2025-10-06 13:26:25 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2025-10-06 14:06:25 +0300 |
commit | eca8ce9cb1613d5c983185c4e43c20651a9638aa (patch) | |
tree | 61ee5ae779948e61af9a7691d19eaa2c09869121 /yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp | |
parent | 4adf7eecae16a9b228b28cc5f64c27ef69ad5ec2 (diff) |
YQL-20086 udfs
init
commit_hash:f9684778bf1ea956965f2360b80b91edb7d4ffbe
Diffstat (limited to 'yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp')
-rw-r--r-- | yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp | 586 |
1 files changed, 272 insertions, 314 deletions
diff --git a/yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp b/yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp index b8662907907..5b5c1bfea6b 100644 --- a/yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp +++ b/yql/essentials/udfs/common/python/bindings/py_struct_ut.cpp @@ -2,329 +2,287 @@ #include <library/cpp/testing/unittest/registar.h> - using namespace NPython; Y_UNIT_TEST_SUITE(TPyStructTest) { - Y_UNIT_TEST(FromPyObject) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField<char*>("name", &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "class Person:\n" - " def __init__(self, age, name):\n" - " self.age = age\n" - " self.name = name\n" - "\n" - "def Test():\n" - " return Person(99, 'Jamel')\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Jamel"); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyObjectMissingOptionalField) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField("name", optionalStringType, &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "class Person:\n" - " def __init__(self, age):\n" - " self.age = age\n" - "\n" - "def Test():\n" - " return Person(99)\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT(!name); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyObjectBytesAttrWithNullCharacter) { - TPythonTestEngine engine; - - ui32 ageIdx = 0; - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("a\0ge", &ageIdx) - .Build(); - - engine.ToMiniKQL(personType, - "class Person:\n" - " def __init__(self, age):\n" - " setattr(self, 'a\\0ge', age)\n" - "\n" - "def Test():\n" - " return Person(99)\n", - [ageIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyDict) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField<char*>("name", &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "def Test():\n" - " return { 'name': 'Jamel', 'age': 99 }\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Jamel"); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyDictMissingOptionalField) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField("name", optionalStringType, &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "def Test():\n" - " return { 'age': 99 }\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT(!name); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyDictBytesKeyWithNullCharacter) { - TPythonTestEngine engine; - - ui32 ageIdx = 0; - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("a\0ge", &ageIdx) - .Build(); - - engine.ToMiniKQL(personType, - "def Test():\n" - " return { b'a\\0ge': 99 }\n", - [ageIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); - }); - } - - Y_UNIT_TEST(FromPyNamedTuple) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField<char*>("name", &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "from collections import namedtuple\n" - "def Test():\n" - " Person = namedtuple('Person', 'name age')\n" - " return Person(age=13, name='Tony')\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Tony"); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 13); - }); - } - - Y_UNIT_TEST(FromPyNamedTupleNoneOptionalField) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0; - auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<int>("age", &ageIdx) - .AddField("name", optionalStringType, &nameIdx) - .Build(); - - engine.ToMiniKQL(personType, - "from collections import namedtuple\n" - "def Test():\n" - " Pers = namedtuple('Person', 'name age')\n" - " return Pers(name=None, age=15)\n", - [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { - UNIT_ASSERT(value); - UNIT_ASSERT(value.IsBoxed()); - auto name = value.GetElement(nameIdx); - UNIT_ASSERT(!name); - auto age = value.GetElement(ageIdx); - UNIT_ASSERT_EQUAL(age.Get<ui32>(), 15); - }); - } - - Y_UNIT_TEST(FromPyEmptyStruct) { - TPythonTestEngine engine; - auto emptyStruct = engine.GetTypeBuilder().Struct()->Build(); - - engine.ToMiniKQL(emptyStruct, - "class Empty: pass\n" - "\n" - "def Test():\n" - " return Empty()\n", - [](const NUdf::TUnboxedValuePod&) {}); - } - - Y_UNIT_TEST(ToPyObject) { - TPythonTestEngine engine; - - ui32 ageIdx = 0, nameIdx = 0, addressIdx = 0, cityIdx = 0, streetIdx = 0, buildingIdx = 0; - auto addressType = engine.GetTypeBuilder().Struct()-> - AddField<NUdf::TUtf8>("city", &cityIdx) - .AddField<NUdf::TUtf8>("street", &streetIdx) - .AddField<ui16>("building", &buildingIdx) - .Build(); - - auto personType = engine.GetTypeBuilder().Struct()-> - AddField<ui16>("age", &ageIdx) - .AddField<NUdf::TUtf8>("name", &nameIdx) - .AddField("address", addressType, &addressIdx) - .Build(); - - - engine.ToPython(personType, - [=](const TType* type, const NUdf::IValueBuilder& vb) { - NUdf::TUnboxedValue* items = nullptr; - auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); - items[ageIdx] = NUdf::TUnboxedValuePod(ui16(97)); - items[nameIdx] = vb.NewString("Jamel"); - NUdf::TUnboxedValue* items2 = nullptr; - items[addressIdx] = vb.NewArray(static_cast<const TStructType*>(static_cast<const TStructType*>(type)->GetMemberType(addressIdx))->GetMembersCount(), items2); - items2[cityIdx] = vb.NewString("Moscow");; - items2[streetIdx] = vb.NewString("L'va Tolstogo"); - items2[buildingIdx] = NUdf::TUnboxedValuePod(ui16(16)); - return new_struct; - }, - "def Test(value):\n" - " assert isinstance(value, object)\n" - " assert value.name == 'Jamel'\n" - " assert value.age == 97\n" - " assert value.address.city == 'Moscow'\n" - " assert value.address.building == 16\n" - ); - } - - Y_UNIT_TEST(ToPyObjectKeywordsAsFields) { - TPythonTestEngine engine; - - ui32 passIdx = 0, whileIdx = 0, ifIdx = 0, notIdx = 0; - auto structType = engine.GetTypeBuilder().Struct()-> - AddField<NUdf::TUtf8>("pass", &passIdx) - .AddField<NUdf::TUtf8>("while", &whileIdx) - .AddField<NUdf::TUtf8>("if", &ifIdx) - .AddField<NUdf::TUtf8>("not", ¬Idx) - .Build(); - - engine.ToPython(structType, - [=](const TType* type, const NUdf::IValueBuilder& vb) { - NUdf::TUnboxedValue* items = nullptr; - auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); - items[ifIdx] = vb.NewString("You"); - items[whileIdx] = vb.NewString("Shall"); - items[notIdx] = vb.NewString("Not"); - items[passIdx] = vb.NewString("Pass"); - return new_struct; - }, - "def Test(value):\n" - " assert getattr(value, 'if') == 'You'\n" - " assert getattr(value, 'while') == 'Shall'\n" - " assert getattr(value, 'not') == 'Not'\n" - " assert getattr(value, 'pass') == 'Pass'\n" - ); - } +Y_UNIT_TEST(FromPyObject) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField<char*>("name", &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "class Person:\n" + " def __init__(self, age, name):\n" + " self.age = age\n" + " self.name = name\n" + "\n" + "def Test():\n" + " return Person(99, 'Jamel')\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Jamel"); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyObjectMissingOptionalField) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField("name", optionalStringType, &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "class Person:\n" + " def __init__(self, age):\n" + " self.age = age\n" + "\n" + "def Test():\n" + " return Person(99)\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT(!name); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyObjectBytesAttrWithNullCharacter) { + TPythonTestEngine engine; + + ui32 ageIdx = 0; + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("a\0ge", &ageIdx).Build(); + + engine.ToMiniKQL(personType, + "class Person:\n" + " def __init__(self, age):\n" + " setattr(self, 'a\\0ge', age)\n" + "\n" + "def Test():\n" + " return Person(99)\n", + [ageIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyDict) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField<char*>("name", &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "def Test():\n" + " return { 'name': 'Jamel', 'age': 99 }\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Jamel"); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyDictMissingOptionalField) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField("name", optionalStringType, &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "def Test():\n" + " return { 'age': 99 }\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT(!name); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyDictBytesKeyWithNullCharacter) { + TPythonTestEngine engine; + + ui32 ageIdx = 0; + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("a\0ge", &ageIdx).Build(); + + engine.ToMiniKQL(personType, + "def Test():\n" + " return { b'a\\0ge': 99 }\n", + [ageIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 99); + }); +} + +Y_UNIT_TEST(FromPyNamedTuple) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField<char*>("name", &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "from collections import namedtuple\n" + "def Test():\n" + " Person = namedtuple('Person', 'name age')\n" + " return Person(age=13, name='Tony')\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT_STRINGS_EQUAL(name.AsStringRef(), "Tony"); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 13); + }); +} + +Y_UNIT_TEST(FromPyNamedTupleNoneOptionalField) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0; + auto optionalStringType = engine.GetTypeBuilder().Optional()->Item<char*>().Build(); + auto personType = engine.GetTypeBuilder().Struct()->AddField<int>("age", &ageIdx).AddField("name", optionalStringType, &nameIdx).Build(); + + engine.ToMiniKQL(personType, + "from collections import namedtuple\n" + "def Test():\n" + " Pers = namedtuple('Person', 'name age')\n" + " return Pers(name=None, age=15)\n", + [ageIdx, nameIdx](const NUdf::TUnboxedValuePod& value) { + UNIT_ASSERT(value); + UNIT_ASSERT(value.IsBoxed()); + auto name = value.GetElement(nameIdx); + UNIT_ASSERT(!name); + auto age = value.GetElement(ageIdx); + UNIT_ASSERT_EQUAL(age.Get<ui32>(), 15); + }); +} + +Y_UNIT_TEST(FromPyEmptyStruct) { + TPythonTestEngine engine; + auto emptyStruct = engine.GetTypeBuilder().Struct()->Build(); + + engine.ToMiniKQL(emptyStruct, + "class Empty: pass\n" + "\n" + "def Test():\n" + " return Empty()\n", + [](const NUdf::TUnboxedValuePod&) {}); +} + +Y_UNIT_TEST(ToPyObject) { + TPythonTestEngine engine; + + ui32 ageIdx = 0, nameIdx = 0, addressIdx = 0, cityIdx = 0, streetIdx = 0, buildingIdx = 0; + auto addressType = engine.GetTypeBuilder().Struct()->AddField<NUdf::TUtf8>("city", &cityIdx).AddField<NUdf::TUtf8>("street", &streetIdx).AddField<ui16>("building", &buildingIdx).Build(); + + auto personType = engine.GetTypeBuilder().Struct()->AddField<ui16>("age", &ageIdx).AddField<NUdf::TUtf8>("name", &nameIdx).AddField("address", addressType, &addressIdx).Build(); + + engine.ToPython(personType, + [=](const TType* type, const NUdf::IValueBuilder& vb) { + NUdf::TUnboxedValue* items = nullptr; + auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); + items[ageIdx] = NUdf::TUnboxedValuePod(ui16(97)); + items[nameIdx] = vb.NewString("Jamel"); + NUdf::TUnboxedValue* items2 = nullptr; + items[addressIdx] = vb.NewArray(static_cast<const TStructType*>(static_cast<const TStructType*>(type)->GetMemberType(addressIdx))->GetMembersCount(), items2); + items2[cityIdx] = vb.NewString("Moscow"); + ; + items2[streetIdx] = vb.NewString("L'va Tolstogo"); + items2[buildingIdx] = NUdf::TUnboxedValuePod(ui16(16)); + return new_struct; + }, + "def Test(value):\n" + " assert isinstance(value, object)\n" + " assert value.name == 'Jamel'\n" + " assert value.age == 97\n" + " assert value.address.city == 'Moscow'\n" + " assert value.address.building == 16\n"); +} + +Y_UNIT_TEST(ToPyObjectKeywordsAsFields) { + TPythonTestEngine engine; + + ui32 passIdx = 0, whileIdx = 0, ifIdx = 0, notIdx = 0; + auto structType = engine.GetTypeBuilder().Struct()->AddField<NUdf::TUtf8>("pass", &passIdx).AddField<NUdf::TUtf8>("while", &whileIdx).AddField<NUdf::TUtf8>("if", &ifIdx).AddField<NUdf::TUtf8>("not", ¬Idx).Build(); + + engine.ToPython(structType, + [=](const TType* type, const NUdf::IValueBuilder& vb) { + NUdf::TUnboxedValue* items = nullptr; + auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); + items[ifIdx] = vb.NewString("You"); + items[whileIdx] = vb.NewString("Shall"); + items[notIdx] = vb.NewString("Not"); + items[passIdx] = vb.NewString("Pass"); + return new_struct; + }, + "def Test(value):\n" + " assert getattr(value, 'if') == 'You'\n" + " assert getattr(value, 'while') == 'Shall'\n" + " assert getattr(value, 'not') == 'Not'\n" + " assert getattr(value, 'pass') == 'Pass'\n"); +} #if PY_MAJOR_VERSION >= 3 // TODO: Fix for python 2 - Y_UNIT_TEST(ToPyObjectTryModify) { - TPythonTestEngine engine; - - ui32 field1Idx = 0, field2Idx = 0; - auto structType = engine.GetTypeBuilder().Struct()-> - AddField<NUdf::TUtf8>("field1", &field1Idx) - .AddField<NUdf::TUtf8>("field2", &field2Idx) - .Build(); - - engine.ToPython(structType, - [=](const TType* type, const NUdf::IValueBuilder& vb) { - NUdf::TUnboxedValue* items = nullptr; - auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); - items[field1Idx] = NUdf::TUnboxedValuePod::Zero(); - items[field2Idx] = NUdf::TUnboxedValuePod::Embedded("empty"); - return new_struct; - }, - "def Test(value):\n" - " try:\n" - " setattr(value, 'field1', 17)\n" - " except AttributeError:\n" - " pass\n" - " else:\n" - " assert False\n" - " try:\n" - " value.field2 = 18\n" - " except AttributeError:\n" - " pass\n" - " else:\n" - " assert False\n" - ); - } +Y_UNIT_TEST(ToPyObjectTryModify) { + TPythonTestEngine engine; + + ui32 field1Idx = 0, field2Idx = 0; + auto structType = engine.GetTypeBuilder().Struct()->AddField<NUdf::TUtf8>("field1", &field1Idx).AddField<NUdf::TUtf8>("field2", &field2Idx).Build(); + + engine.ToPython(structType, + [=](const TType* type, const NUdf::IValueBuilder& vb) { + NUdf::TUnboxedValue* items = nullptr; + auto new_struct = vb.NewArray(static_cast<const TStructType*>(type)->GetMembersCount(), items); + items[field1Idx] = NUdf::TUnboxedValuePod::Zero(); + items[field2Idx] = NUdf::TUnboxedValuePod::Embedded("empty"); + return new_struct; + }, + "def Test(value):\n" + " try:\n" + " setattr(value, 'field1', 17)\n" + " except AttributeError:\n" + " pass\n" + " else:\n" + " assert False\n" + " try:\n" + " value.field2 = 18\n" + " except AttributeError:\n" + " pass\n" + " else:\n" + " assert False\n"); +} #endif - Y_UNIT_TEST(ToPyObjectEmptyStruct) { - TPythonTestEngine engine; +Y_UNIT_TEST(ToPyObjectEmptyStruct) { + TPythonTestEngine engine; - auto personType = engine.GetTypeBuilder().Struct()->Build(); + auto personType = engine.GetTypeBuilder().Struct()->Build(); - engine.ToPython(personType, - [](const TType*, const NUdf::IValueBuilder& vb) { - return vb.NewEmptyList(); - }, - "def Test(value):\n" - " assert isinstance(value, object)\n" + engine.ToPython(personType, + [](const TType*, const NUdf::IValueBuilder& vb) { + return vb.NewEmptyList(); + }, + "def Test(value):\n" + " assert isinstance(value, object)\n" #if PY_MAJOR_VERSION >= 3 - " assert len(value) == 0\n" + " assert len(value) == 0\n" #endif - ); - } + ); } +} // Y_UNIT_TEST_SUITE(TPyStructTest) |