[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / unittests / ScriptInterpreter / Python / PythonDataObjectsTests.cpp
blob365ebc8e52c2469fec32adb90151837666afb17e
1 //===-- PythonDataObjectsTests.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Plugins/ScriptInterpreter/Python/lldb-python.h"
10 #include "gtest/gtest.h"
12 #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
13 #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
14 #include "TestingSupport/SubsystemRAII.h"
15 #include "lldb/Host/File.h"
16 #include "lldb/Host/FileSystem.h"
17 #include "lldb/Host/HostInfo.h"
18 #include "lldb/lldb-enumerations.h"
19 #include "llvm/Testing/Support/Error.h"
21 #include "PythonTestSuite.h"
23 #include <variant>
25 using namespace lldb_private;
26 using namespace lldb_private::python;
27 using llvm::Expected;
29 class PythonDataObjectsTest : public PythonTestSuite {
30 SubsystemRAII<FileSystem> subsystems;
32 public:
33 void SetUp() override {
34 PythonTestSuite::SetUp();
36 m_sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
37 m_main_module = PythonModule::MainModule();
38 m_builtins_module = PythonModule::BuiltinsModule();
41 void TearDown() override {
42 m_sys_module.Reset();
43 m_main_module.Reset();
44 m_builtins_module.Reset();
46 PythonTestSuite::TearDown();
49 protected:
50 PythonModule m_sys_module;
51 PythonModule m_main_module;
52 PythonModule m_builtins_module;
55 TEST_F(PythonDataObjectsTest, TestOwnedReferences) {
56 // After creating a new object, the refcount should be >= 1
57 PyObject *obj = PyBytes_FromString("foo");
58 Py_ssize_t original_refcnt = Py_REFCNT(obj);
59 EXPECT_LE(1, original_refcnt);
61 // If we take an owned reference, the refcount should be the same
62 PythonObject owned(PyRefType::Owned, obj);
63 Py_ssize_t owned_refcnt = Py_REFCNT(owned.get());
64 EXPECT_EQ(original_refcnt, owned_refcnt);
66 // Take another reference and verify that the refcount increases by 1
67 PythonObject strong_ref(owned);
68 Py_ssize_t strong_refcnt = Py_REFCNT(strong_ref.get());
69 EXPECT_EQ(original_refcnt + 1, strong_refcnt);
71 // If we reset the first one, the refcount should be the original value.
72 owned.Reset();
73 strong_refcnt = Py_REFCNT(strong_ref.get());
74 EXPECT_EQ(original_refcnt, strong_refcnt);
77 TEST_F(PythonDataObjectsTest, TestResetting) {
78 PythonDictionary dict(PyInitialValue::Empty);
80 PyObject *new_dict = PyDict_New();
81 dict = Take<PythonDictionary>(new_dict);
82 EXPECT_EQ(new_dict, dict.get());
84 dict = Take<PythonDictionary>(PyDict_New());
85 EXPECT_NE(nullptr, dict.get());
86 dict.Reset();
87 EXPECT_EQ(nullptr, dict.get());
90 TEST_F(PythonDataObjectsTest, TestBorrowedReferences) {
91 PythonByteArray byte_value(PyRefType::Owned,
92 PyByteArray_FromStringAndSize("foo", 3));
93 Py_ssize_t original_refcnt = Py_REFCNT(byte_value.get());
94 EXPECT_LE(1, original_refcnt);
96 PythonByteArray borrowed_byte(PyRefType::Borrowed, byte_value.get());
97 Py_ssize_t borrowed_refcnt = Py_REFCNT(borrowed_byte.get());
99 EXPECT_EQ(original_refcnt + 1, borrowed_refcnt);
102 TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionNoDot) {
103 PythonObject sys_module = m_main_module.ResolveName("sys");
104 EXPECT_EQ(m_sys_module.get(), sys_module.get());
105 EXPECT_TRUE(sys_module.IsAllocated());
106 EXPECT_TRUE(PythonModule::Check(sys_module.get()));
109 TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) {
110 PythonObject sys_path = m_sys_module.ResolveName("path");
111 PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
112 EXPECT_TRUE(sys_path.IsAllocated());
113 EXPECT_TRUE(sys_version_info.IsAllocated());
115 EXPECT_TRUE(PythonList::Check(sys_path.get()));
118 TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) {
119 PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
121 PythonObject version_info_type(PyRefType::Owned,
122 PyObject_Type(sys_version_info.get()));
123 EXPECT_TRUE(version_info_type.IsAllocated());
124 PythonObject major_version_field = version_info_type.ResolveName("major");
125 EXPECT_TRUE(major_version_field.IsAllocated());
128 TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) {
129 PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
130 PythonObject major_version_field = sys_version_info.ResolveName("major");
131 PythonObject minor_version_field = sys_version_info.ResolveName("minor");
133 EXPECT_TRUE(major_version_field.IsAllocated());
134 EXPECT_TRUE(minor_version_field.IsAllocated());
136 auto major_version_value = As<long long>(major_version_field);
137 auto minor_version_value = As<long long>(minor_version_field);
139 EXPECT_THAT_EXPECTED(major_version_value, llvm::HasValue(PY_MAJOR_VERSION));
140 EXPECT_THAT_EXPECTED(minor_version_value, llvm::HasValue(PY_MINOR_VERSION));
143 TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) {
144 PythonObject sys_path = m_main_module.ResolveName("sys.path");
145 EXPECT_TRUE(sys_path.IsAllocated());
146 EXPECT_TRUE(PythonList::Check(sys_path.get()));
148 auto version_major =
149 As<long long>(m_main_module.ResolveName("sys.version_info.major"));
151 auto version_minor =
152 As<long long>(m_main_module.ResolveName("sys.version_info.minor"));
154 EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
155 EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
158 TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) {
159 // Make up a custom dictionary with "sys" pointing to the `sys` module.
160 PythonDictionary dict(PyInitialValue::Empty);
161 dict.SetItemForKey(PythonString("sys"), m_sys_module);
163 // Now use that dictionary to resolve `sys.version_info.major`
164 auto version_major = As<long long>(
165 PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict));
167 auto version_minor = As<long long>(
168 PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict));
170 EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
171 EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
174 TEST_F(PythonDataObjectsTest, TestPythonInteger) {
175 // Test that integers behave correctly when wrapped by a PythonInteger.
177 // Verify that `PythonInteger` works correctly when given a PyLong object.
178 PyObject *py_long = PyLong_FromLong(12);
179 EXPECT_TRUE(PythonInteger::Check(py_long));
180 PythonInteger python_long(PyRefType::Owned, py_long);
181 EXPECT_EQ(PyObjectType::Integer, python_long.GetObjectType());
183 // Verify that you can reset the value and that it is reflected properly.
184 python_long.SetInteger(40);
185 auto e = As<long long>(python_long);
186 EXPECT_THAT_EXPECTED(e, llvm::HasValue(40));
188 // Test that creating a `PythonInteger` object works correctly with the
189 // int constructor.
190 PythonInteger constructed_int(7);
191 auto value = As<long long>(constructed_int);
192 EXPECT_THAT_EXPECTED(value, llvm::HasValue(7));
195 TEST_F(PythonDataObjectsTest, TestPythonBoolean) {
196 // Test PythonBoolean constructed from Py_True
197 EXPECT_TRUE(PythonBoolean::Check(Py_True));
198 PythonBoolean python_true(PyRefType::Owned, Py_True);
199 EXPECT_EQ(PyObjectType::Boolean, python_true.GetObjectType());
201 // Test PythonBoolean constructed from Py_False
202 EXPECT_TRUE(PythonBoolean::Check(Py_False));
203 PythonBoolean python_false(PyRefType::Owned, Py_False);
204 EXPECT_EQ(PyObjectType::Boolean, python_false.GetObjectType());
206 auto test_from_long = [](long value) {
207 PyObject *py_bool = PyBool_FromLong(value);
208 EXPECT_TRUE(PythonBoolean::Check(py_bool));
209 PythonBoolean python_boolean(PyRefType::Owned, py_bool);
210 EXPECT_EQ(PyObjectType::Boolean, python_boolean.GetObjectType());
211 EXPECT_EQ(bool(value), python_boolean.GetValue());
214 // Test PythonBoolean constructed from long integer values.
215 test_from_long(0); // Test 'false' value.
216 test_from_long(1); // Test 'true' value.
217 test_from_long(~0); // Any value != 0 is 'true'.
220 TEST_F(PythonDataObjectsTest, TestPythonBytes) {
221 static const char *test_bytes = "PythonDataObjectsTest::TestPythonBytes";
222 PyObject *py_bytes = PyBytes_FromString(test_bytes);
223 EXPECT_TRUE(PythonBytes::Check(py_bytes));
224 PythonBytes python_bytes(PyRefType::Owned, py_bytes);
226 EXPECT_FALSE(PythonString::Check(py_bytes));
227 EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
229 llvm::ArrayRef<uint8_t> bytes = python_bytes.GetBytes();
230 EXPECT_EQ(bytes.size(), strlen(test_bytes));
231 EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
234 TEST_F(PythonDataObjectsTest, TestPythonByteArray) {
235 static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
236 llvm::StringRef orig_bytes(test_bytes);
237 PyObject *py_bytes =
238 PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
239 EXPECT_TRUE(PythonByteArray::Check(py_bytes));
240 PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
241 EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());
243 llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
244 EXPECT_EQ(after_bytes.size(), orig_bytes.size());
245 EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
248 TEST_F(PythonDataObjectsTest, TestPythonString) {
249 // Test that strings behave correctly when wrapped by a PythonString.
251 static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
252 static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";
254 // Verify that `PythonString` works correctly when given a PyUnicode object.
255 PyObject *py_unicode = PyUnicode_FromString(test_string);
256 EXPECT_TRUE(PythonString::Check(py_unicode));
257 PythonString python_unicode(PyRefType::Owned, py_unicode);
258 EXPECT_EQ(PyObjectType::String, python_unicode.GetObjectType());
259 EXPECT_STREQ(test_string, python_unicode.GetString().data());
261 // Test that creating a `PythonString` object works correctly with the
262 // string constructor
263 PythonString constructed_string(test_string2);
264 EXPECT_EQ(test_string2, constructed_string.GetString());
267 TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
268 const char *GetString = "PythonDataObjectsTest::TestPythonStringToStr";
270 PythonString str(GetString);
271 EXPECT_EQ(GetString, str.GetString());
273 PythonString str_str = str.Str();
274 EXPECT_EQ(GetString, str_str.GetString());
277 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}
279 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredUnsignedInteger) {
280 PythonInteger integer(7);
281 auto int_sp = integer.CreateStructuredInteger();
282 EXPECT_TRUE(
283 std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp));
284 StructuredData::UnsignedIntegerSP uint_sp =
285 std::get<StructuredData::UnsignedIntegerSP>(int_sp);
286 EXPECT_EQ(7U, uint_sp->GetValue());
289 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredSignedInteger) {
290 PythonInteger integer(-42);
291 auto int_sp = integer.CreateStructuredInteger();
292 EXPECT_TRUE(std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp));
293 StructuredData::SignedIntegerSP sint_sp =
294 std::get<StructuredData::SignedIntegerSP>(int_sp);
295 EXPECT_EQ(-42, sint_sp->GetValue());
298 TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) {
299 static const char *test_string =
300 "PythonDataObjectsTest::TestPythonStringToStructuredString";
301 PythonString constructed_string(test_string);
302 auto string_sp = constructed_string.CreateStructuredString();
303 EXPECT_EQ(test_string, string_sp->GetStringValue());
306 TEST_F(PythonDataObjectsTest, TestPythonListValueEquality) {
307 // Test that a list which is built through the native
308 // Python API behaves correctly when wrapped by a PythonList.
309 static const unsigned list_size = 2;
310 static const long long_value0 = 5;
311 static const char *const string_value1 = "String Index 1";
313 PyObject *py_list = PyList_New(2);
314 EXPECT_TRUE(PythonList::Check(py_list));
315 PythonList list(PyRefType::Owned, py_list);
317 PythonObject list_items[list_size];
318 list_items[0] = PythonInteger(long_value0);
319 list_items[1] = PythonString(string_value1);
321 for (unsigned i = 0; i < list_size; ++i)
322 list.SetItemAtIndex(i, list_items[i]);
324 EXPECT_EQ(list_size, list.GetSize());
325 EXPECT_EQ(PyObjectType::List, list.GetObjectType());
327 // Verify that the values match
328 PythonObject chk_value1 = list.GetItemAtIndex(0);
329 PythonObject chk_value2 = list.GetItemAtIndex(1);
330 EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
331 EXPECT_TRUE(PythonString::Check(chk_value2.get()));
333 PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
334 PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
336 auto chkint = As<long long>(chk_value1);
337 ASSERT_THAT_EXPECTED(chkint, llvm::HasValue(long_value0));
338 EXPECT_EQ(string_value1, chk_str.GetString());
341 TEST_F(PythonDataObjectsTest, TestPythonListManipulation) {
342 // Test that manipulation of a PythonList behaves correctly when
343 // wrapped by a PythonDictionary.
345 static const long long_value0 = 5;
346 static const char *const string_value1 = "String Index 1";
348 PythonList list(PyInitialValue::Empty);
349 PythonInteger integer(long_value0);
350 PythonString string(string_value1);
352 list.AppendItem(integer);
353 list.AppendItem(string);
354 EXPECT_EQ(2U, list.GetSize());
356 // Verify that the values match
357 PythonObject chk_value1 = list.GetItemAtIndex(0);
358 PythonObject chk_value2 = list.GetItemAtIndex(1);
359 EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
360 EXPECT_TRUE(PythonString::Check(chk_value2.get()));
362 PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
363 PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
365 auto e = As<long long>(chk_int);
366 EXPECT_THAT_EXPECTED(e, llvm::HasValue(long_value0));
367 EXPECT_EQ(string_value1, chk_str.GetString());
370 TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
371 static const long long_value0 = 5;
372 static const char *const string_value1 = "String Index 1";
374 PythonList list(PyInitialValue::Empty);
375 list.AppendItem(PythonInteger(long_value0));
376 list.AppendItem(PythonString(string_value1));
378 auto array_sp = list.CreateStructuredArray();
379 EXPECT_EQ(lldb::eStructuredDataTypeInteger,
380 array_sp->GetItemAtIndex(0)->GetType());
381 EXPECT_EQ(lldb::eStructuredDataTypeString,
382 array_sp->GetItemAtIndex(1)->GetType());
384 auto int_sp = array_sp->GetItemAtIndex(0)->GetAsUnsignedInteger();
385 auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
387 EXPECT_EQ(long_value0, long(int_sp->GetValue()));
388 EXPECT_EQ(string_value1, string_sp->GetValue());
391 TEST_F(PythonDataObjectsTest, TestPythonTupleSize) {
392 PythonTuple tuple(PyInitialValue::Empty);
393 EXPECT_EQ(0U, tuple.GetSize());
395 tuple = PythonTuple(3);
396 EXPECT_EQ(3U, tuple.GetSize());
399 TEST_F(PythonDataObjectsTest, TestPythonTupleValues) {
400 PythonTuple tuple(3);
402 PythonInteger int_value(1);
403 PythonString string_value("Test");
404 PythonObject none_value(PyRefType::Borrowed, Py_None);
406 tuple.SetItemAtIndex(0, int_value);
407 tuple.SetItemAtIndex(1, string_value);
408 tuple.SetItemAtIndex(2, none_value);
410 EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
411 EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
412 EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
415 TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList) {
416 PythonInteger int_value(1);
417 PythonString string_value("Test");
418 PythonObject none_value(PyRefType::Borrowed, Py_None);
419 PythonTuple tuple{int_value, string_value, none_value};
420 EXPECT_EQ(3U, tuple.GetSize());
422 EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
423 EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
424 EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
427 TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) {
428 PythonInteger int_value(1);
429 PythonString string_value("Test");
430 PythonObject none_value(PyRefType::Borrowed, Py_None);
432 PythonTuple tuple{int_value.get(), string_value.get(), none_value.get()};
433 EXPECT_EQ(3U, tuple.GetSize());
435 EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
436 EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
437 EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
440 TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) {
441 PythonInteger int_value(1);
442 PythonString string_value("Test");
444 PythonTuple tuple{int_value.get(), string_value.get()};
446 auto array_sp = tuple.CreateStructuredArray();
447 EXPECT_EQ(tuple.GetSize(), array_sp->GetSize());
448 EXPECT_EQ(lldb::eStructuredDataTypeInteger,
449 array_sp->GetItemAtIndex(0)->GetType());
450 EXPECT_EQ(lldb::eStructuredDataTypeString,
451 array_sp->GetItemAtIndex(1)->GetType());
454 TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) {
455 // Test that a dictionary which is built through the native
456 // Python API behaves correctly when wrapped by a PythonDictionary.
457 static const unsigned dict_entries = 2;
458 const char *key_0 = "Key 0";
459 int key_1 = 1;
460 const int value_0 = 0;
461 const char *value_1 = "Value 1";
463 PythonObject py_keys[dict_entries];
464 PythonObject py_values[dict_entries];
466 py_keys[0] = PythonString(key_0);
467 py_keys[1] = PythonInteger(key_1);
468 py_values[0] = PythonInteger(value_0);
469 py_values[1] = PythonString(value_1);
471 PyObject *py_dict = PyDict_New();
472 EXPECT_TRUE(PythonDictionary::Check(py_dict));
473 PythonDictionary dict(PyRefType::Owned, py_dict);
475 for (unsigned i = 0; i < dict_entries; ++i)
476 PyDict_SetItem(py_dict, py_keys[i].get(), py_values[i].get());
477 EXPECT_EQ(dict.GetSize(), dict_entries);
478 EXPECT_EQ(PyObjectType::Dictionary, dict.GetObjectType());
480 // Verify that the values match
481 PythonObject chk_value1 = dict.GetItemForKey(py_keys[0]);
482 PythonObject chk_value2 = dict.GetItemForKey(py_keys[1]);
483 EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
484 EXPECT_TRUE(PythonString::Check(chk_value2.get()));
486 PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
487 auto chkint = As<long long>(chk_value1);
489 EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
490 EXPECT_EQ(value_1, chk_str.GetString());
493 TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation) {
494 // Test that manipulation of a dictionary behaves correctly when wrapped
495 // by a PythonDictionary.
496 static const unsigned dict_entries = 2;
498 const char *const key_0 = "Key 0";
499 const char *const key_1 = "Key 1";
500 const long value_0 = 1;
501 const char *const value_1 = "Value 1";
503 PythonString keys[dict_entries];
504 PythonObject values[dict_entries];
506 keys[0] = PythonString(key_0);
507 keys[1] = PythonString(key_1);
508 values[0] = PythonInteger(value_0);
509 values[1] = PythonString(value_1);
511 PythonDictionary dict(PyInitialValue::Empty);
512 for (int i = 0; i < 2; ++i)
513 dict.SetItemForKey(keys[i], values[i]);
515 EXPECT_EQ(dict_entries, dict.GetSize());
516 EXPECT_FALSE(dict.HasKey("not_in_dict"));
517 EXPECT_TRUE(dict.HasKey(key_0));
518 EXPECT_TRUE(dict.HasKey(key_1));
520 // Verify that the keys and values match
521 PythonObject chk_value1 = dict.GetItemForKey(keys[0]);
522 PythonObject chk_value2 = dict.GetItemForKey(keys[1]);
523 EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
524 EXPECT_TRUE(PythonString::Check(chk_value2.get()));
526 auto chkint = As<long long>(chk_value1);
527 PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
529 EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
530 EXPECT_EQ(value_1, chk_str.GetString());
533 TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) {
534 static const char *const string_key0 = "String Key 0";
535 static const char *const string_key1 = "String Key 1";
537 static const char *const string_value0 = "String Value 0";
538 static const long int_value1 = 7;
540 PythonDictionary dict(PyInitialValue::Empty);
541 dict.SetItemForKey(PythonString(string_key0), PythonString(string_value0));
542 dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1));
544 auto dict_sp = dict.CreateStructuredDictionary();
545 EXPECT_EQ(2U, dict_sp->GetSize());
547 EXPECT_TRUE(dict_sp->HasKey(string_key0));
548 EXPECT_TRUE(dict_sp->HasKey(string_key1));
550 auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
551 auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsUnsignedInteger();
553 EXPECT_EQ(string_value0, string_sp->GetValue());
554 EXPECT_EQ(int_value1, long(int_sp->GetValue()));
557 TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) {
558 PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info");
559 PythonObject none(PyRefType::Borrowed, Py_None);
561 EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get()));
562 EXPECT_FALSE(PythonCallable::Check(none.get()));
565 TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) {
566 auto list = m_builtins_module.ResolveName("list").AsType<PythonCallable>();
567 PythonInteger one(1);
568 PythonString two("two");
569 PythonTuple three = {one, two};
571 PythonTuple tuple_to_convert = {one, two, three};
572 PythonObject result = list({tuple_to_convert});
574 EXPECT_TRUE(PythonList::Check(result.get()));
575 auto list_result = result.AsType<PythonList>();
576 EXPECT_EQ(3U, list_result.GetSize());
577 EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get());
578 EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get());
579 EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get());
582 TEST_F(PythonDataObjectsTest, TestPythonFile) {
583 auto file = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL),
584 File::eOpenOptionReadOnly);
585 ASSERT_THAT_EXPECTED(file, llvm::Succeeded());
586 auto py_file = PythonFile::FromFile(*file.get(), "r");
587 ASSERT_THAT_EXPECTED(py_file, llvm::Succeeded());
588 EXPECT_TRUE(PythonFile::Check(py_file.get().get()));
591 TEST_F(PythonDataObjectsTest, TestObjectAttributes) {
592 PythonInteger py_int(42);
593 EXPECT_TRUE(py_int.HasAttribute("numerator"));
594 EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist"));
596 auto numerator_attr = As<long long>(py_int.GetAttributeValue("numerator"));
598 EXPECT_THAT_EXPECTED(numerator_attr, llvm::HasValue(42));
601 TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
602 // Make up a custom dictionary with "sys" pointing to the `sys` module.
603 const char *key_name = "addr";
604 const uint64_t value = 0xf000000000000000ull;
605 PythonDictionary python_dict(PyInitialValue::Empty);
606 PythonInteger python_ull_value(PyRefType::Owned,
607 PyLong_FromUnsignedLongLong(value));
608 python_dict.SetItemForKey(PythonString(key_name), python_ull_value);
609 StructuredData::ObjectSP structured_data_sp =
610 python_dict.CreateStructuredObject();
611 EXPECT_TRUE((bool)structured_data_sp);
612 if (structured_data_sp) {
613 StructuredData::Dictionary *structured_dict_ptr =
614 structured_data_sp->GetAsDictionary();
615 EXPECT_TRUE(structured_dict_ptr != nullptr);
616 if (structured_dict_ptr) {
617 StructuredData::ObjectSP structured_addr_value_sp =
618 structured_dict_ptr->GetValueForKey(key_name);
619 EXPECT_TRUE((bool)structured_addr_value_sp);
620 const uint64_t extracted_value =
621 structured_addr_value_sp->GetUnsignedIntegerValue(123);
622 EXPECT_TRUE(extracted_value == value);
627 TEST_F(PythonDataObjectsTest, TestCallable) {
629 PythonDictionary globals(PyInitialValue::Empty);
630 auto builtins = PythonModule::BuiltinsModule();
631 llvm::Error error = globals.SetItem("__builtins__", builtins);
632 ASSERT_FALSE(error);
635 PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
636 globals.get());
637 ASSERT_FALSE(o == NULL);
638 auto lambda = Take<PythonCallable>(o);
639 auto arginfo = lambda.GetArgInfo();
640 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
641 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
645 PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
646 globals.get());
647 ASSERT_FALSE(o == NULL);
648 auto lambda = Take<PythonCallable>(o);
649 auto arginfo = lambda.GetArgInfo();
650 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
651 EXPECT_EQ(arginfo.get().max_positional_args, 2u);
655 PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
656 globals.get(), globals.get());
657 ASSERT_FALSE(o == NULL);
658 auto lambda = Take<PythonCallable>(o);
659 auto arginfo = lambda.GetArgInfo();
660 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
661 EXPECT_EQ(arginfo.get().max_positional_args, 2u);
665 PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(),
666 globals.get());
667 ASSERT_FALSE(o == NULL);
668 auto lambda = Take<PythonCallable>(o);
669 auto arginfo = lambda.GetArgInfo();
670 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
671 EXPECT_EQ(arginfo.get().max_positional_args,
672 PythonCallable::ArgInfo::UNBOUNDED);
676 PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
677 globals.get(), globals.get());
678 ASSERT_FALSE(o == NULL);
679 auto lambda = Take<PythonCallable>(o);
680 auto arginfo = lambda.GetArgInfo();
681 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
682 EXPECT_EQ(arginfo.get().max_positional_args,
683 PythonCallable::ArgInfo::UNBOUNDED);
687 const char *script = R"(
688 class Foo:
689 def bar(self, x):
690 return x
691 @classmethod
692 def classbar(cls, x):
693 return x
694 @staticmethod
695 def staticbar(x):
696 return x
697 def __call__(self, x):
698 return x
699 obj = Foo()
700 bar_bound = Foo().bar
701 bar_class = Foo().classbar
702 bar_static = Foo().staticbar
703 bar_unbound = Foo.bar
706 class OldStyle:
707 def __init__(self, one, two, three):
708 pass
710 class NewStyle(object):
711 def __init__(self, one, two, three):
712 pass
715 PyObject *o =
716 PyRun_String(script, Py_file_input, globals.get(), globals.get());
717 ASSERT_FALSE(o == NULL);
718 Take<PythonObject>(o);
720 auto bar_bound = As<PythonCallable>(globals.GetItem("bar_bound"));
721 ASSERT_THAT_EXPECTED(bar_bound, llvm::Succeeded());
722 auto arginfo = bar_bound.get().GetArgInfo();
723 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
724 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
726 auto bar_unbound = As<PythonCallable>(globals.GetItem("bar_unbound"));
727 ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
728 arginfo = bar_unbound.get().GetArgInfo();
729 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
730 EXPECT_EQ(arginfo.get().max_positional_args, 2u);
732 auto bar_class = As<PythonCallable>(globals.GetItem("bar_class"));
733 ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
734 arginfo = bar_class.get().GetArgInfo();
735 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
736 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
738 auto bar_static = As<PythonCallable>(globals.GetItem("bar_static"));
739 ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
740 arginfo = bar_static.get().GetArgInfo();
741 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
742 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
744 auto obj = As<PythonCallable>(globals.GetItem("obj"));
745 ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
746 arginfo = obj.get().GetArgInfo();
747 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
748 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
750 auto oldstyle = As<PythonCallable>(globals.GetItem("OldStyle"));
751 ASSERT_THAT_EXPECTED(oldstyle, llvm::Succeeded());
752 arginfo = oldstyle.get().GetArgInfo();
753 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
754 EXPECT_EQ(arginfo.get().max_positional_args, 3u);
756 auto newstyle = As<PythonCallable>(globals.GetItem("NewStyle"));
757 ASSERT_THAT_EXPECTED(newstyle, llvm::Succeeded());
758 arginfo = newstyle.get().GetArgInfo();
759 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
760 EXPECT_EQ(arginfo.get().max_positional_args, 3u);
763 #if PY_VERSION_HEX >= 0x03030000
765 // the old implementation of GetArgInfo just doesn't work on builtins.
768 auto builtins = PythonModule::BuiltinsModule();
769 auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
770 ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());
771 auto arginfo = hex.get().GetArgInfo();
772 ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
773 EXPECT_EQ(arginfo.get().max_positional_args, 1u);
776 #endif
779 TEST_F(PythonDataObjectsTest, TestScript) {
781 static const char script[] = R"(
782 def factorial(n):
783 if n > 1:
784 return n * factorial(n-1)
785 else:
786 return 1;
787 main = factorial
790 PythonScript factorial(script);
792 EXPECT_THAT_EXPECTED(As<long long>(factorial(5ll)), llvm::HasValue(120));
795 TEST_F(PythonDataObjectsTest, TestExceptions) {
797 static const char script[] = R"(
798 def foo():
799 return bar()
800 def bar():
801 return baz()
802 def baz():
803 return 1 / 0
804 main = foo
807 PythonScript foo(script);
809 EXPECT_THAT_EXPECTED(
810 foo(), llvm::Failed<PythonException>(testing::Property(
811 &PythonException::ReadBacktrace,
812 testing::AllOf(testing::ContainsRegex("line 3, in foo"),
813 testing::ContainsRegex("line 5, in bar"),
814 testing::ContainsRegex("line 7, in baz"),
815 testing::ContainsRegex("ZeroDivisionError")))));
817 #if !((defined(_WIN32) || defined(_WIN64)) && \
818 (defined(__aarch64__) || defined(_M_ARM64)))
820 static const char script2[] = R"(
821 class MyError(Exception):
822 def __str__(self):
823 return self.my_message
825 def main():
826 raise MyError("lol")
830 PythonScript lol(script2);
832 EXPECT_THAT_EXPECTED(
833 lol(),
834 llvm::Failed<PythonException>(testing::Property(
835 &PythonException::ReadBacktrace,
836 testing::AnyOf(
837 testing::ContainsRegex("MyError: <exception str\\(\\) failed>"),
838 testing::ContainsRegex("unprintable MyError")))));
840 #endif
843 TEST_F(PythonDataObjectsTest, TestRun) {
845 PythonDictionary globals(PyInitialValue::Empty);
847 auto x = As<long long>(runStringOneLine("40 + 2", globals, globals));
848 ASSERT_THAT_EXPECTED(x, llvm::Succeeded());
849 EXPECT_EQ(x.get(), 42l);
851 Expected<PythonObject> r = runStringOneLine("n = 42", globals, globals);
852 ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
853 auto y = As<long long>(globals.GetItem("n"));
854 ASSERT_THAT_EXPECTED(y, llvm::Succeeded());
855 EXPECT_EQ(y.get(), 42l);
857 const char script[] = R"(
858 def foobar():
859 return "foo" + "bar" + "baz"
860 g = foobar()
863 r = runStringMultiLine(script, globals, globals);
864 ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
865 auto g = As<std::string>(globals.GetItem("g"));
866 ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz"));