xref: /llvm-project/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp (revision 9ea64dd8781328d831d7c69a586f0c84dece1c11)
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 //===----------------------------------------------------------------------===//
8 
9 #include "Plugins/ScriptInterpreter/Python/lldb-python.h"
10 #include "gtest/gtest.h"
11 
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"
20 
21 #include "PythonTestSuite.h"
22 
23 #include <variant>
24 
25 using namespace lldb_private;
26 using namespace lldb_private::python;
27 using llvm::Expected;
28 
29 class PythonDataObjectsTest : public PythonTestSuite {
30   SubsystemRAII<FileSystem> subsystems;
31 
32 public:
33   void SetUp() override {
34     PythonTestSuite::SetUp();
35 
36     m_sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
37     m_main_module = PythonModule::MainModule();
38     m_builtins_module = PythonModule::BuiltinsModule();
39   }
40 
41   void TearDown() override {
42     m_sys_module.Reset();
43     m_main_module.Reset();
44     m_builtins_module.Reset();
45 
46     PythonTestSuite::TearDown();
47   }
48 
49 protected:
50   PythonModule m_sys_module;
51   PythonModule m_main_module;
52   PythonModule m_builtins_module;
53 };
54 
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);
60 
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);
65 
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);
70 
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);
75 }
76 
77 TEST_F(PythonDataObjectsTest, TestResetting) {
78   PythonDictionary dict(PyInitialValue::Empty);
79 
80   PyObject *new_dict = PyDict_New();
81   dict = Take<PythonDictionary>(new_dict);
82   EXPECT_EQ(new_dict, dict.get());
83 
84   dict = Take<PythonDictionary>(PyDict_New());
85   EXPECT_NE(nullptr, dict.get());
86   dict.Reset();
87   EXPECT_EQ(nullptr, dict.get());
88 }
89 
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);
95 
96   PythonByteArray borrowed_byte(PyRefType::Borrowed, byte_value.get());
97   Py_ssize_t borrowed_refcnt = Py_REFCNT(borrowed_byte.get());
98 
99   EXPECT_EQ(original_refcnt + 1, borrowed_refcnt);
100 }
101 
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()));
107 }
108 
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());
114 
115   EXPECT_TRUE(PythonList::Check(sys_path.get()));
116 }
117 
118 TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) {
119   PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
120 
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());
126 }
127 
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");
132 
133   EXPECT_TRUE(major_version_field.IsAllocated());
134   EXPECT_TRUE(minor_version_field.IsAllocated());
135 
136   auto major_version_value = As<long long>(major_version_field);
137   auto minor_version_value = As<long long>(minor_version_field);
138 
139   EXPECT_THAT_EXPECTED(major_version_value, llvm::HasValue(PY_MAJOR_VERSION));
140   EXPECT_THAT_EXPECTED(minor_version_value, llvm::HasValue(PY_MINOR_VERSION));
141 }
142 
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()));
147 
148   auto version_major =
149       As<long long>(m_main_module.ResolveName("sys.version_info.major"));
150 
151   auto version_minor =
152       As<long long>(m_main_module.ResolveName("sys.version_info.minor"));
153 
154   EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
155   EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
156 }
157 
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);
162 
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));
166 
167   auto version_minor = As<long long>(
168       PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict));
169 
170   EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
171   EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
172 }
173 
174 TEST_F(PythonDataObjectsTest, TestPythonInteger) {
175   // Test that integers behave correctly when wrapped by a PythonInteger.
176 
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());
182 
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));
187 
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));
193 }
194 
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());
200 
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());
205 
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());
212   };
213 
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'.
218 }
219 
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);
225 
226   EXPECT_FALSE(PythonString::Check(py_bytes));
227   EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
228 
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()));
232 }
233 
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());
242 
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()));
246 }
247 
248 TEST_F(PythonDataObjectsTest, TestPythonString) {
249   // Test that strings behave correctly when wrapped by a PythonString.
250 
251   static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
252   static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";
253 
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());
260 
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());
265 }
266 
267 TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
268   const char *GetString = "PythonDataObjectsTest::TestPythonStringToStr";
269 
270   PythonString str(GetString);
271   EXPECT_EQ(GetString, str.GetString());
272 
273   PythonString str_str = str.Str();
274   EXPECT_EQ(GetString, str_str.GetString());
275 }
276 
277 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}
278 
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());
287 }
288 
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());
296 }
297 
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());
304 }
305 
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";
312 
313   PyObject *py_list = PyList_New(2);
314   EXPECT_TRUE(PythonList::Check(py_list));
315   PythonList list(PyRefType::Owned, py_list);
316 
317   PythonObject list_items[list_size];
318   list_items[0] = PythonInteger(long_value0);
319   list_items[1] = PythonString(string_value1);
320 
321   for (unsigned i = 0; i < list_size; ++i)
322     list.SetItemAtIndex(i, list_items[i]);
323 
324   EXPECT_EQ(list_size, list.GetSize());
325   EXPECT_EQ(PyObjectType::List, list.GetObjectType());
326 
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()));
332 
333   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
334   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
335 
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());
339 }
340 
341 TEST_F(PythonDataObjectsTest, TestPythonListManipulation) {
342   // Test that manipulation of a PythonList behaves correctly when
343   // wrapped by a PythonDictionary.
344 
345   static const long long_value0 = 5;
346   static const char *const string_value1 = "String Index 1";
347 
348   PythonList list(PyInitialValue::Empty);
349   PythonInteger integer(long_value0);
350   PythonString string(string_value1);
351 
352   list.AppendItem(integer);
353   list.AppendItem(string);
354   EXPECT_EQ(2U, list.GetSize());
355 
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()));
361 
362   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
363   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
364 
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());
368 }
369 
370 TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
371   static const long long_value0 = 5;
372   static const char *const string_value1 = "String Index 1";
373 
374   PythonList list(PyInitialValue::Empty);
375   list.AppendItem(PythonInteger(long_value0));
376   list.AppendItem(PythonString(string_value1));
377 
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());
383 
384   auto int_sp = array_sp->GetItemAtIndex(0)->GetAsUnsignedInteger();
385   auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
386 
387   EXPECT_EQ(long_value0, long(int_sp->GetValue()));
388   EXPECT_EQ(string_value1, string_sp->GetValue());
389 }
390 
391 TEST_F(PythonDataObjectsTest, TestPythonTupleSize) {
392   PythonTuple tuple(PyInitialValue::Empty);
393   EXPECT_EQ(0U, tuple.GetSize());
394 
395   tuple = PythonTuple(3);
396   EXPECT_EQ(3U, tuple.GetSize());
397 }
398 
399 TEST_F(PythonDataObjectsTest, TestPythonTupleValues) {
400   PythonTuple tuple(3);
401 
402   PythonInteger int_value(1);
403   PythonString string_value("Test");
404   PythonObject none_value(PyRefType::Borrowed, Py_None);
405 
406   tuple.SetItemAtIndex(0, int_value);
407   tuple.SetItemAtIndex(1, string_value);
408   tuple.SetItemAtIndex(2, none_value);
409 
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());
413 }
414 
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());
421 
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());
425 }
426 
427 TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) {
428   PythonInteger int_value(1);
429   PythonString string_value("Test");
430   PythonObject none_value(PyRefType::Borrowed, Py_None);
431 
432   PythonTuple tuple{int_value.get(), string_value.get(), none_value.get()};
433   EXPECT_EQ(3U, tuple.GetSize());
434 
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());
438 }
439 
440 TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) {
441   PythonInteger int_value(1);
442   PythonString string_value("Test");
443 
444   PythonTuple tuple{int_value.get(), string_value.get()};
445 
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());
452 }
453 
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";
462 
463   PythonObject py_keys[dict_entries];
464   PythonObject py_values[dict_entries];
465 
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);
470 
471   PyObject *py_dict = PyDict_New();
472   EXPECT_TRUE(PythonDictionary::Check(py_dict));
473   PythonDictionary dict(PyRefType::Owned, py_dict);
474 
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());
479 
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()));
485 
486   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
487   auto chkint = As<long long>(chk_value1);
488 
489   EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
490   EXPECT_EQ(value_1, chk_str.GetString());
491 }
492 
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;
497 
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";
502 
503   PythonString keys[dict_entries];
504   PythonObject values[dict_entries];
505 
506   keys[0] = PythonString(key_0);
507   keys[1] = PythonString(key_1);
508   values[0] = PythonInteger(value_0);
509   values[1] = PythonString(value_1);
510 
511   PythonDictionary dict(PyInitialValue::Empty);
512   for (int i = 0; i < 2; ++i)
513     dict.SetItemForKey(keys[i], values[i]);
514 
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));
519 
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()));
525 
526   auto chkint = As<long long>(chk_value1);
527   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
528 
529   EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
530   EXPECT_EQ(value_1, chk_str.GetString());
531 }
532 
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";
536 
537   static const char *const string_value0 = "String Value 0";
538   static const long int_value1 = 7;
539 
540   PythonDictionary dict(PyInitialValue::Empty);
541   dict.SetItemForKey(PythonString(string_key0), PythonString(string_value0));
542   dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1));
543 
544   auto dict_sp = dict.CreateStructuredDictionary();
545   EXPECT_EQ(2U, dict_sp->GetSize());
546 
547   EXPECT_TRUE(dict_sp->HasKey(string_key0));
548   EXPECT_TRUE(dict_sp->HasKey(string_key1));
549 
550   auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
551   auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsUnsignedInteger();
552 
553   EXPECT_EQ(string_value0, string_sp->GetValue());
554   EXPECT_EQ(int_value1, long(int_sp->GetValue()));
555 }
556 
557 TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) {
558   PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info");
559   PythonObject none(PyRefType::Borrowed, Py_None);
560 
561   EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get()));
562   EXPECT_FALSE(PythonCallable::Check(none.get()));
563 }
564 
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};
570 
571   PythonTuple tuple_to_convert = {one, two, three};
572   PythonObject result = list({tuple_to_convert});
573 
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());
580 }
581 
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()));
589 }
590 
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"));
595 
596   auto numerator_attr = As<long long>(py_int.GetAttributeValue("numerator"));
597 
598   EXPECT_THAT_EXPECTED(numerator_attr, llvm::HasValue(42));
599 }
600 
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);
623     }
624   }
625 }
626 
627 TEST_F(PythonDataObjectsTest, TestCallable) {
628 
629   PythonDictionary globals(PyInitialValue::Empty);
630   auto builtins = PythonModule::BuiltinsModule();
631   llvm::Error error = globals.SetItem("__builtins__", builtins);
632   ASSERT_FALSE(error);
633 
634   {
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);
642   }
643 
644   {
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);
652   }
653 
654   {
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);
662   }
663 
664   {
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);
673   }
674 
675   {
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);
684   }
685 
686   {
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
704 
705 
706 class OldStyle:
707   def __init__(self, one, two, three):
708     pass
709 
710 class NewStyle(object):
711   def __init__(self, one, two, three):
712     pass
713 
714 )";
715     PyObject *o =
716         PyRun_String(script, Py_file_input, globals.get(), globals.get());
717     ASSERT_FALSE(o == NULL);
718     Take<PythonObject>(o);
719 
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);
725 
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);
731 
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);
737 
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);
743 
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);
749 
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);
755 
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);
761   }
762 
763   {
764     auto builtins = PythonModule::BuiltinsModule();
765     auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
766     ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());
767     auto arginfo = hex.get().GetArgInfo();
768     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
769     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
770   }
771 }
772 
773 TEST_F(PythonDataObjectsTest, TestScript) {
774 
775   static const char script[] = R"(
776 def factorial(n):
777   if n > 1:
778     return n * factorial(n-1)
779   else:
780     return 1;
781 main = factorial
782 )";
783 
784   PythonScript factorial(script);
785 
786   EXPECT_THAT_EXPECTED(As<long long>(factorial(5ll)), llvm::HasValue(120));
787 }
788 
789 TEST_F(PythonDataObjectsTest, TestExceptions) {
790 
791   static const char script[] = R"(
792 def foo():
793   return bar()
794 def bar():
795   return baz()
796 def baz():
797   return 1 / 0
798 main = foo
799 )";
800 
801   PythonScript foo(script);
802 
803   EXPECT_THAT_EXPECTED(
804       foo(), llvm::Failed<PythonException>(testing::Property(
805                  &PythonException::ReadBacktrace,
806                  testing::AllOf(testing::ContainsRegex("line 3, in foo"),
807                                 testing::ContainsRegex("line 5, in bar"),
808                                 testing::ContainsRegex("line 7, in baz"),
809                                 testing::ContainsRegex("ZeroDivisionError")))));
810 
811 #if !((defined(_WIN32) || defined(_WIN64)) &&                                  \
812       (defined(__aarch64__) || defined(_M_ARM64)))
813 
814   static const char script2[] = R"(
815 class MyError(Exception):
816   def __str__(self):
817     return self.my_message
818 
819 def main():
820   raise MyError("lol")
821 
822 )";
823 
824   PythonScript lol(script2);
825 
826   EXPECT_THAT_EXPECTED(
827       lol(),
828       llvm::Failed<PythonException>(testing::Property(
829           &PythonException::ReadBacktrace,
830           testing::AnyOf(
831               testing::ContainsRegex("MyError: <exception str\\(\\) failed>"),
832               testing::ContainsRegex("unprintable MyError")))));
833 
834 #endif
835 }
836 
837 TEST_F(PythonDataObjectsTest, TestRun) {
838 
839   PythonDictionary globals(PyInitialValue::Empty);
840 
841   auto x = As<long long>(runStringOneLine("40 + 2", globals, globals));
842   ASSERT_THAT_EXPECTED(x, llvm::Succeeded());
843   EXPECT_EQ(x.get(), 42l);
844 
845   Expected<PythonObject> r = runStringOneLine("n = 42", globals, globals);
846   ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
847   auto y = As<long long>(globals.GetItem("n"));
848   ASSERT_THAT_EXPECTED(y, llvm::Succeeded());
849   EXPECT_EQ(y.get(), 42l);
850 
851   const char script[] = R"(
852 def foobar():
853   return "foo" + "bar" + "baz"
854 g = foobar()
855 )";
856 
857   r = runStringMultiLine(script, globals, globals);
858   ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
859   auto g = As<std::string>(globals.GetItem("g"));
860   ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz"));
861 }
862