diff options
author | Zachary Turner <zturner@google.com> | 2015-11-11 19:42:27 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-11-11 19:42:27 +0000 |
commit | a140514733e0ab0310688c727b70ba3e2a4a8ddc (patch) | |
tree | 00c8c54435082bda6ae8c33cb9eac146fe31865a /lldb/unittests/ScriptInterpreter/Python | |
parent | 51c402838ca37b51701f7e03738f6e503c7d1c7e (diff) | |
download | bcm5719-llvm-a140514733e0ab0310688c727b70ba3e2a4a8ddc.tar.gz bcm5719-llvm-a140514733e0ab0310688c727b70ba3e2a4a8ddc.zip |
Create `PythonTuple` and `PythonCallable` wrapper classes.
This adds PythonTuple and PythonCallable classes to PythonDataObjects.
Additionally, unit tests are provided that exercise this functionality,
including invoking manipulating and checking for validity of tuples,
and invoking and checking for validity of callables using a variety
of different syntaxes.
The goal here is to eventually replace the code in python-wrapper.swig
that directly uses the Python C API to deal with callables and name
resolution with this code that can be more easily tested and debugged.
llvm-svn: 252787
Diffstat (limited to 'lldb/unittests/ScriptInterpreter/Python')
-rw-r--r-- | lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp | 143 |
1 files changed, 132 insertions, 11 deletions
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp index 728208be663..86e6125c869 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp @@ -35,16 +35,29 @@ class PythonDataObjectsTest : public testing::Test // Py_INCREF. So acquire the GIL for the entire duration of this // test suite. m_gil_state = PyGILState_Ensure(); + + PythonString sys_module("sys"); + m_sys_module.Reset(PyRefType::Owned, PyImport_Import(sys_module.get())); + m_main_module = PythonModule::MainModule(); + m_builtins_module = PythonModule::BuiltinsModule(); } void TearDown() override { + m_sys_module.Reset(); + m_main_module.Reset(); + m_builtins_module.Reset(); PyGILState_Release(m_gil_state); ScriptInterpreterPython::Terminate(); } + protected: + PythonModule m_sys_module; + PythonModule m_main_module; + PythonModule m_builtins_module; + private: PyGILState_STATE m_gil_state; }; @@ -98,16 +111,16 @@ TEST_F(PythonDataObjectsTest, TestBorrowedReferences) TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionNoDot) { - PythonObject sys_module = PythonObject::ResolveNameGlobal("sys"); + PythonObject sys_module = m_main_module.ResolveName("sys"); + EXPECT_EQ(m_sys_module.get(), sys_module.get()); EXPECT_TRUE(sys_module.IsAllocated()); EXPECT_TRUE(PythonModule::Check(sys_module.get())); } TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) { - PythonObject sys_module = PythonObject::ResolveNameGlobal("sys"); - PythonObject sys_path = sys_module.ResolveName("path"); - PythonObject sys_version_info = sys_module.ResolveName("version_info"); + PythonObject sys_path = m_sys_module.ResolveName("path"); + PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); EXPECT_TRUE(sys_path.IsAllocated()); EXPECT_TRUE(sys_version_info.IsAllocated()); @@ -116,8 +129,7 @@ TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) { - PythonObject sys_module = PythonObject::ResolveNameGlobal("sys"); - PythonObject sys_version_info = sys_module.ResolveName("version_info"); + PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); PythonObject version_info_type(PyRefType::Owned, PyObject_Type(sys_version_info.get())); EXPECT_TRUE(version_info_type.IsAllocated()); @@ -127,8 +139,7 @@ TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) { - PythonObject sys_module = PythonObject::ResolveNameGlobal("sys"); - PythonObject sys_version_info = sys_module.ResolveName("version_info"); + PythonObject sys_version_info = m_sys_module.ResolveName("version_info"); PythonObject major_version_field = sys_version_info.ResolveName("major"); PythonObject minor_version_field = sys_version_info.ResolveName("minor"); @@ -144,18 +155,35 @@ TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) { - PythonObject sys_path = PythonObject::ResolveNameGlobal("sys.path"); + PythonObject sys_path = m_main_module.ResolveName("sys.path"); EXPECT_TRUE(sys_path.IsAllocated()); EXPECT_TRUE(PythonList::Check(sys_path.get())); - PythonInteger version_major = PythonObject::ResolveNameGlobal("sys.version_info.major").AsType<PythonInteger>(); - PythonInteger version_minor = PythonObject::ResolveNameGlobal("sys.version_info.minor").AsType<PythonInteger>(); + PythonInteger version_major = m_main_module.ResolveName( + "sys.version_info.major").AsType<PythonInteger>(); + PythonInteger version_minor = m_main_module.ResolveName( + "sys.version_info.minor").AsType<PythonInteger>(); EXPECT_TRUE(version_major.IsAllocated()); EXPECT_TRUE(version_minor.IsAllocated()); EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger()); EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger()); } +TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) +{ + // Make up a custom dictionary with "sys" pointing to the `sys` module. + PythonDictionary dict(PyInitialValue::Empty); + dict.SetItemForKey(PythonString("sys"), m_sys_module); + + // Now use that dictionary to resolve `sys.version_info.major` + PythonInteger version_major = PythonObject::ResolveNameWithDictionary( + "sys.version_info.major", dict).AsType<PythonInteger>(); + PythonInteger version_minor = PythonObject::ResolveNameWithDictionary( + "sys.version_info.minor", dict).AsType<PythonInteger>(); + EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger()); + EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger()); +} + TEST_F(PythonDataObjectsTest, TestPythonInteger) { // Test that integers behave correctly when wrapped by a PythonInteger. @@ -333,6 +361,72 @@ TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) EXPECT_STREQ(string_value1, string_sp->GetValue().c_str()); } +TEST_F(PythonDataObjectsTest, TestPythonTupleSize) +{ + PythonTuple tuple(PyInitialValue::Empty); + EXPECT_EQ(0, tuple.GetSize()); + + tuple = PythonTuple(3); + EXPECT_EQ(3, tuple.GetSize()); +} + +TEST_F(PythonDataObjectsTest, TestPythonTupleValues) +{ + PythonTuple tuple(3); + + PythonInteger int_value(1); + PythonString string_value("Test"); + PythonObject none_value(PyRefType::Borrowed, Py_None); + + tuple.SetItemAtIndex(0, int_value); + tuple.SetItemAtIndex(1, string_value); + tuple.SetItemAtIndex(2, none_value); + + EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); +} + +TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList) +{ + PythonInteger int_value(1); + PythonString string_value("Test"); + PythonObject none_value(PyRefType::Borrowed, Py_None); + PythonTuple tuple{ int_value, string_value, none_value }; + EXPECT_EQ(3, tuple.GetSize()); + + EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); +} + +TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) +{ + PythonInteger int_value(1); + PythonString string_value("Test"); + PythonObject none_value(PyRefType::Borrowed, Py_None); + + PythonTuple tuple{ int_value.get(), string_value.get(), none_value.get() }; + EXPECT_EQ(3, tuple.GetSize()); + + EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get()); + EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get()); +} + +TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) +{ + PythonInteger int_value(1); + PythonString string_value("Test"); + + PythonTuple tuple{ int_value.get(), string_value.get() }; + + auto array_sp = tuple.CreateStructuredArray(); + EXPECT_EQ(tuple.GetSize(), array_sp->GetSize()); + EXPECT_EQ(StructuredData::Type::eTypeInteger, array_sp->GetItemAtIndex(0)->GetType()); + EXPECT_EQ(StructuredData::Type::eTypeString, array_sp->GetItemAtIndex(1)->GetType()); +} + TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) { // Test that a dictionary which is built through the native @@ -436,6 +530,33 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) EXPECT_EQ(int_value1, int_sp->GetValue()); } +TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) +{ + PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info"); + PythonObject none(PyRefType::Borrowed, Py_None); + + EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get())); + EXPECT_FALSE(PythonCallable::Check(none.get())); +} + +TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) +{ + auto list = m_builtins_module.ResolveName("list").AsType<PythonCallable>(); + PythonInteger one(1); + PythonString two("two"); + PythonTuple three = { one, two }; + + PythonTuple tuple_to_convert = { one, two, three }; + PythonObject result = list({ tuple_to_convert }); + + EXPECT_TRUE(PythonList::Check(result.get())); + auto list_result = result.AsType<PythonList>(); + EXPECT_EQ(3, list_result.GetSize()); + EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get()); + EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get()); + EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get()); +} + TEST_F(PythonDataObjectsTest, TestPythonFile) { File file(FileSystem::DEV_NULL, File::eOpenOptionRead); |