xref: /llvm-project/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp (revision 04edd1893c2d0f35880fd5f81e78dc23979df0b9)
1 //===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===//
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 "lldb/Host/File.h"
15 #include "lldb/Host/FileSystem.h"
16 #include "lldb/Host/HostInfo.h"
17 #include "lldb/lldb-enumerations.h"
18 #include "llvm/Testing/Support/Error.h"
19 
20 #include "PythonTestSuite.h"
21 
22 using namespace lldb_private;
23 using namespace lldb_private::python;
24 using llvm::Error;
25 using llvm::Expected;
26 
27 class PythonDataObjectsTest : public PythonTestSuite {
28 public:
29   void SetUp() override {
30     PythonTestSuite::SetUp();
31 
32     m_sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
33     m_main_module = PythonModule::MainModule();
34     m_builtins_module = PythonModule::BuiltinsModule();
35   }
36 
37   void TearDown() override {
38     m_sys_module.Reset();
39     m_main_module.Reset();
40     m_builtins_module.Reset();
41 
42     PythonTestSuite::TearDown();
43   }
44 
45 protected:
46   PythonModule m_sys_module;
47   PythonModule m_main_module;
48   PythonModule m_builtins_module;
49 };
50 
51 TEST_F(PythonDataObjectsTest, TestOwnedReferences) {
52   // After creating a new object, the refcount should be >= 1
53   PyObject *obj = PyLong_FromLong(3);
54   Py_ssize_t original_refcnt = obj->ob_refcnt;
55   EXPECT_LE(1, original_refcnt);
56 
57   // If we take an owned reference, the refcount should be the same
58   PythonObject owned_long(PyRefType::Owned, obj);
59   EXPECT_EQ(original_refcnt, owned_long.get()->ob_refcnt);
60 
61   // Take another reference and verify that the refcount increases by 1
62   PythonObject strong_ref(owned_long);
63   EXPECT_EQ(original_refcnt + 1, strong_ref.get()->ob_refcnt);
64 
65   // If we reset the first one, the refcount should be the original value.
66   owned_long.Reset();
67   EXPECT_EQ(original_refcnt, strong_ref.get()->ob_refcnt);
68 }
69 
70 TEST_F(PythonDataObjectsTest, TestResetting) {
71   PythonDictionary dict(PyInitialValue::Empty);
72 
73   PyObject *new_dict = PyDict_New();
74   dict = Take<PythonDictionary>(new_dict);
75   EXPECT_EQ(new_dict, dict.get());
76 
77   dict = Take<PythonDictionary>(PyDict_New());
78   EXPECT_NE(nullptr, dict.get());
79   dict.Reset();
80   EXPECT_EQ(nullptr, dict.get());
81 }
82 
83 TEST_F(PythonDataObjectsTest, TestBorrowedReferences) {
84   PythonInteger long_value(PyRefType::Owned, PyLong_FromLong(3));
85   Py_ssize_t original_refcnt = long_value.get()->ob_refcnt;
86   EXPECT_LE(1, original_refcnt);
87 
88   PythonInteger borrowed_long(PyRefType::Borrowed, long_value.get());
89   EXPECT_EQ(original_refcnt + 1, borrowed_long.get()->ob_refcnt);
90 }
91 
92 TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionNoDot) {
93   PythonObject sys_module = m_main_module.ResolveName("sys");
94   EXPECT_EQ(m_sys_module.get(), sys_module.get());
95   EXPECT_TRUE(sys_module.IsAllocated());
96   EXPECT_TRUE(PythonModule::Check(sys_module.get()));
97 }
98 
99 TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) {
100   PythonObject sys_path = m_sys_module.ResolveName("path");
101   PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
102   EXPECT_TRUE(sys_path.IsAllocated());
103   EXPECT_TRUE(sys_version_info.IsAllocated());
104 
105   EXPECT_TRUE(PythonList::Check(sys_path.get()));
106 }
107 
108 TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) {
109   PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
110 
111   PythonObject version_info_type(PyRefType::Owned,
112                                  PyObject_Type(sys_version_info.get()));
113   EXPECT_TRUE(version_info_type.IsAllocated());
114   PythonObject major_version_field = version_info_type.ResolveName("major");
115   EXPECT_TRUE(major_version_field.IsAllocated());
116 }
117 
118 TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) {
119   PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
120   PythonObject major_version_field = sys_version_info.ResolveName("major");
121   PythonObject minor_version_field = sys_version_info.ResolveName("minor");
122 
123   EXPECT_TRUE(major_version_field.IsAllocated());
124   EXPECT_TRUE(minor_version_field.IsAllocated());
125 
126   PythonInteger major_version_value =
127       major_version_field.AsType<PythonInteger>();
128   PythonInteger minor_version_value =
129       minor_version_field.AsType<PythonInteger>();
130 
131   EXPECT_EQ(PY_MAJOR_VERSION, major_version_value.GetInteger());
132   EXPECT_EQ(PY_MINOR_VERSION, minor_version_value.GetInteger());
133 }
134 
135 TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) {
136   PythonObject sys_path = m_main_module.ResolveName("sys.path");
137   EXPECT_TRUE(sys_path.IsAllocated());
138   EXPECT_TRUE(PythonList::Check(sys_path.get()));
139 
140   PythonInteger version_major =
141       m_main_module.ResolveName("sys.version_info.major")
142           .AsType<PythonInteger>();
143   PythonInteger version_minor =
144       m_main_module.ResolveName("sys.version_info.minor")
145           .AsType<PythonInteger>();
146   EXPECT_TRUE(version_major.IsAllocated());
147   EXPECT_TRUE(version_minor.IsAllocated());
148   EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger());
149   EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger());
150 }
151 
152 TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) {
153   // Make up a custom dictionary with "sys" pointing to the `sys` module.
154   PythonDictionary dict(PyInitialValue::Empty);
155   dict.SetItemForKey(PythonString("sys"), m_sys_module);
156 
157   // Now use that dictionary to resolve `sys.version_info.major`
158   PythonInteger version_major =
159       PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict)
160           .AsType<PythonInteger>();
161   PythonInteger version_minor =
162       PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict)
163           .AsType<PythonInteger>();
164   EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger());
165   EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger());
166 }
167 
168 TEST_F(PythonDataObjectsTest, TestPythonInteger) {
169   // Test that integers behave correctly when wrapped by a PythonInteger.
170 
171 #if PY_MAJOR_VERSION < 3
172   // Verify that `PythonInt` works correctly when given a PyInt object.
173   // Note that PyInt doesn't exist in Python 3.x, so this is only for 2.x
174   PyObject *py_int = PyInt_FromLong(12);
175   EXPECT_TRUE(PythonInteger::Check(py_int));
176   PythonInteger python_int(PyRefType::Owned, py_int);
177 
178   EXPECT_EQ(PyObjectType::Integer, python_int.GetObjectType());
179   EXPECT_EQ(12, python_int.GetInteger());
180 #endif
181 
182   // Verify that `PythonInteger` works correctly when given a PyLong object.
183   PyObject *py_long = PyLong_FromLong(12);
184   EXPECT_TRUE(PythonInteger::Check(py_long));
185   PythonInteger python_long(PyRefType::Owned, py_long);
186   EXPECT_EQ(PyObjectType::Integer, python_long.GetObjectType());
187 
188   // Verify that you can reset the value and that it is reflected properly.
189   python_long.SetInteger(40);
190   EXPECT_EQ(40, python_long.GetInteger());
191 
192   // Test that creating a `PythonInteger` object works correctly with the
193   // int constructor.
194   PythonInteger constructed_int(7);
195   EXPECT_EQ(7, constructed_int.GetInteger());
196 }
197 
198 TEST_F(PythonDataObjectsTest, TestPythonBoolean) {
199   // Test PythonBoolean constructed from Py_True
200   EXPECT_TRUE(PythonBoolean::Check(Py_True));
201   PythonBoolean python_true(PyRefType::Owned, Py_True);
202   EXPECT_EQ(PyObjectType::Boolean, python_true.GetObjectType());
203 
204   // Test PythonBoolean constructed from Py_False
205   EXPECT_TRUE(PythonBoolean::Check(Py_False));
206   PythonBoolean python_false(PyRefType::Owned, Py_False);
207   EXPECT_EQ(PyObjectType::Boolean, python_false.GetObjectType());
208 
209   auto test_from_long = [](long value) {
210     PyObject *py_bool = PyBool_FromLong(value);
211     EXPECT_TRUE(PythonBoolean::Check(py_bool));
212     PythonBoolean python_boolean(PyRefType::Owned, py_bool);
213     EXPECT_EQ(PyObjectType::Boolean, python_boolean.GetObjectType());
214     EXPECT_EQ(bool(value), python_boolean.GetValue());
215   };
216 
217   // Test PythonBoolean constructed from long integer values.
218   test_from_long(0); // Test 'false' value.
219   test_from_long(1); // Test 'true' value.
220   test_from_long(~0); // Any value != 0 is 'true'.
221 }
222 
223 TEST_F(PythonDataObjectsTest, TestPythonBytes) {
224   static const char *test_bytes = "PythonDataObjectsTest::TestPythonBytes";
225   PyObject *py_bytes = PyBytes_FromString(test_bytes);
226   EXPECT_TRUE(PythonBytes::Check(py_bytes));
227   PythonBytes python_bytes(PyRefType::Owned, py_bytes);
228 
229 #if PY_MAJOR_VERSION < 3
230   EXPECT_TRUE(PythonString::Check(py_bytes));
231   EXPECT_EQ(PyObjectType::String, python_bytes.GetObjectType());
232 #else
233   EXPECT_FALSE(PythonString::Check(py_bytes));
234   EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
235 #endif
236 
237   llvm::ArrayRef<uint8_t> bytes = python_bytes.GetBytes();
238   EXPECT_EQ(bytes.size(), strlen(test_bytes));
239   EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
240 }
241 
242 TEST_F(PythonDataObjectsTest, TestPythonByteArray) {
243   static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
244   llvm::StringRef orig_bytes(test_bytes);
245   PyObject *py_bytes =
246       PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
247   EXPECT_TRUE(PythonByteArray::Check(py_bytes));
248   PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
249   EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());
250 
251   llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
252   EXPECT_EQ(after_bytes.size(), orig_bytes.size());
253   EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
254 }
255 
256 TEST_F(PythonDataObjectsTest, TestPythonString) {
257   // Test that strings behave correctly when wrapped by a PythonString.
258 
259   static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
260   static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";
261 
262 #if PY_MAJOR_VERSION < 3
263   // Verify that `PythonString` works correctly when given a PyString object.
264   // Note that PyString doesn't exist in Python 3.x, so this is only for 2.x
265   PyObject *py_string = PyString_FromString(test_string);
266   EXPECT_TRUE(PythonString::Check(py_string));
267   PythonString python_string(PyRefType::Owned, py_string);
268 
269   EXPECT_EQ(PyObjectType::String, python_string.GetObjectType());
270   EXPECT_STREQ(test_string, python_string.GetString().data());
271 #else
272   // Verify that `PythonString` works correctly when given a PyUnicode object.
273   PyObject *py_unicode = PyUnicode_FromString(test_string);
274   EXPECT_TRUE(PythonString::Check(py_unicode));
275   PythonString python_unicode(PyRefType::Owned, py_unicode);
276   EXPECT_EQ(PyObjectType::String, python_unicode.GetObjectType());
277   EXPECT_STREQ(test_string, python_unicode.GetString().data());
278 #endif
279 
280   // Test that creating a `PythonString` object works correctly with the
281   // string constructor
282   PythonString constructed_string(test_string2);
283   EXPECT_EQ(test_string2, constructed_string.GetString());
284 }
285 
286 TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
287   const char *GetString = "PythonDataObjectsTest::TestPythonStringToStr";
288 
289   PythonString str(GetString);
290   EXPECT_EQ(GetString, str.GetString());
291 
292   PythonString str_str = str.Str();
293   EXPECT_EQ(GetString, str_str.GetString());
294 }
295 
296 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}
297 
298 TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredInteger) {
299   PythonInteger integer(7);
300   auto int_sp = integer.CreateStructuredInteger();
301   EXPECT_EQ(7U, int_sp->GetValue());
302 }
303 
304 TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) {
305   static const char *test_string =
306       "PythonDataObjectsTest::TestPythonStringToStructuredString";
307   PythonString constructed_string(test_string);
308   auto string_sp = constructed_string.CreateStructuredString();
309   EXPECT_EQ(test_string, string_sp->GetStringValue());
310 }
311 
312 TEST_F(PythonDataObjectsTest, TestPythonListValueEquality) {
313   // Test that a list which is built through the native
314   // Python API behaves correctly when wrapped by a PythonList.
315   static const unsigned list_size = 2;
316   static const long long_value0 = 5;
317   static const char *const string_value1 = "String Index 1";
318 
319   PyObject *py_list = PyList_New(2);
320   EXPECT_TRUE(PythonList::Check(py_list));
321   PythonList list(PyRefType::Owned, py_list);
322 
323   PythonObject list_items[list_size];
324   list_items[0] = PythonInteger(long_value0);
325   list_items[1] = PythonString(string_value1);
326 
327   for (unsigned i = 0; i < list_size; ++i)
328     list.SetItemAtIndex(i, list_items[i]);
329 
330   EXPECT_EQ(list_size, list.GetSize());
331   EXPECT_EQ(PyObjectType::List, list.GetObjectType());
332 
333   // Verify that the values match
334   PythonObject chk_value1 = list.GetItemAtIndex(0);
335   PythonObject chk_value2 = list.GetItemAtIndex(1);
336   EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
337   EXPECT_TRUE(PythonString::Check(chk_value2.get()));
338 
339   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
340   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
341 
342   EXPECT_EQ(long_value0, chk_int.GetInteger());
343   EXPECT_EQ(string_value1, chk_str.GetString());
344 }
345 
346 TEST_F(PythonDataObjectsTest, TestPythonListManipulation) {
347   // Test that manipulation of a PythonList behaves correctly when
348   // wrapped by a PythonDictionary.
349 
350   static const long long_value0 = 5;
351   static const char *const string_value1 = "String Index 1";
352 
353   PythonList list(PyInitialValue::Empty);
354   PythonInteger integer(long_value0);
355   PythonString string(string_value1);
356 
357   list.AppendItem(integer);
358   list.AppendItem(string);
359   EXPECT_EQ(2U, list.GetSize());
360 
361   // Verify that the values match
362   PythonObject chk_value1 = list.GetItemAtIndex(0);
363   PythonObject chk_value2 = list.GetItemAtIndex(1);
364   EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
365   EXPECT_TRUE(PythonString::Check(chk_value2.get()));
366 
367   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
368   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
369 
370   EXPECT_EQ(long_value0, chk_int.GetInteger());
371   EXPECT_EQ(string_value1, chk_str.GetString());
372 }
373 
374 TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
375   static const long long_value0 = 5;
376   static const char *const string_value1 = "String Index 1";
377 
378   PythonList list(PyInitialValue::Empty);
379   list.AppendItem(PythonInteger(long_value0));
380   list.AppendItem(PythonString(string_value1));
381 
382   auto array_sp = list.CreateStructuredArray();
383   EXPECT_EQ(lldb::eStructuredDataTypeInteger,
384             array_sp->GetItemAtIndex(0)->GetType());
385   EXPECT_EQ(lldb::eStructuredDataTypeString,
386             array_sp->GetItemAtIndex(1)->GetType());
387 
388   auto int_sp = array_sp->GetItemAtIndex(0)->GetAsInteger();
389   auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();
390 
391   EXPECT_EQ(long_value0, long(int_sp->GetValue()));
392   EXPECT_EQ(string_value1, string_sp->GetValue());
393 }
394 
395 TEST_F(PythonDataObjectsTest, TestPythonTupleSize) {
396   PythonTuple tuple(PyInitialValue::Empty);
397   EXPECT_EQ(0U, tuple.GetSize());
398 
399   tuple = PythonTuple(3);
400   EXPECT_EQ(3U, tuple.GetSize());
401 }
402 
403 TEST_F(PythonDataObjectsTest, TestPythonTupleValues) {
404   PythonTuple tuple(3);
405 
406   PythonInteger int_value(1);
407   PythonString string_value("Test");
408   PythonObject none_value(PyRefType::Borrowed, Py_None);
409 
410   tuple.SetItemAtIndex(0, int_value);
411   tuple.SetItemAtIndex(1, string_value);
412   tuple.SetItemAtIndex(2, none_value);
413 
414   EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
415   EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
416   EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
417 }
418 
419 TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList) {
420   PythonInteger int_value(1);
421   PythonString string_value("Test");
422   PythonObject none_value(PyRefType::Borrowed, Py_None);
423   PythonTuple tuple{int_value, string_value, none_value};
424   EXPECT_EQ(3U, tuple.GetSize());
425 
426   EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
427   EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
428   EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
429 }
430 
431 TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) {
432   PythonInteger int_value(1);
433   PythonString string_value("Test");
434   PythonObject none_value(PyRefType::Borrowed, Py_None);
435 
436   PythonTuple tuple{int_value.get(), string_value.get(), none_value.get()};
437   EXPECT_EQ(3U, tuple.GetSize());
438 
439   EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
440   EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
441   EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
442 }
443 
444 TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) {
445   PythonInteger int_value(1);
446   PythonString string_value("Test");
447 
448   PythonTuple tuple{int_value.get(), string_value.get()};
449 
450   auto array_sp = tuple.CreateStructuredArray();
451   EXPECT_EQ(tuple.GetSize(), array_sp->GetSize());
452   EXPECT_EQ(lldb::eStructuredDataTypeInteger,
453             array_sp->GetItemAtIndex(0)->GetType());
454   EXPECT_EQ(lldb::eStructuredDataTypeString,
455             array_sp->GetItemAtIndex(1)->GetType());
456 }
457 
458 TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) {
459   // Test that a dictionary which is built through the native
460   // Python API behaves correctly when wrapped by a PythonDictionary.
461   static const unsigned dict_entries = 2;
462   const char *key_0 = "Key 0";
463   int key_1 = 1;
464   const int value_0 = 0;
465   const char *value_1 = "Value 1";
466 
467   PythonObject py_keys[dict_entries];
468   PythonObject py_values[dict_entries];
469 
470   py_keys[0] = PythonString(key_0);
471   py_keys[1] = PythonInteger(key_1);
472   py_values[0] = PythonInteger(value_0);
473   py_values[1] = PythonString(value_1);
474 
475   PyObject *py_dict = PyDict_New();
476   EXPECT_TRUE(PythonDictionary::Check(py_dict));
477   PythonDictionary dict(PyRefType::Owned, py_dict);
478 
479   for (unsigned i = 0; i < dict_entries; ++i)
480     PyDict_SetItem(py_dict, py_keys[i].get(), py_values[i].get());
481   EXPECT_EQ(dict.GetSize(), dict_entries);
482   EXPECT_EQ(PyObjectType::Dictionary, dict.GetObjectType());
483 
484   // Verify that the values match
485   PythonObject chk_value1 = dict.GetItemForKey(py_keys[0]);
486   PythonObject chk_value2 = dict.GetItemForKey(py_keys[1]);
487   EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
488   EXPECT_TRUE(PythonString::Check(chk_value2.get()));
489 
490   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
491   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
492 
493   EXPECT_EQ(value_0, chk_int.GetInteger());
494   EXPECT_EQ(value_1, chk_str.GetString());
495 }
496 
497 TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation) {
498   // Test that manipulation of a dictionary behaves correctly when wrapped
499   // by a PythonDictionary.
500   static const unsigned dict_entries = 2;
501 
502   const char *const key_0 = "Key 0";
503   const char *const key_1 = "Key 1";
504   const long value_0 = 1;
505   const char *const value_1 = "Value 1";
506 
507   PythonString keys[dict_entries];
508   PythonObject values[dict_entries];
509 
510   keys[0] = PythonString(key_0);
511   keys[1] = PythonString(key_1);
512   values[0] = PythonInteger(value_0);
513   values[1] = PythonString(value_1);
514 
515   PythonDictionary dict(PyInitialValue::Empty);
516   for (int i = 0; i < 2; ++i)
517     dict.SetItemForKey(keys[i], values[i]);
518 
519   EXPECT_EQ(dict_entries, dict.GetSize());
520 
521   // Verify that the keys and values match
522   PythonObject chk_value1 = dict.GetItemForKey(keys[0]);
523   PythonObject chk_value2 = dict.GetItemForKey(keys[1]);
524   EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
525   EXPECT_TRUE(PythonString::Check(chk_value2.get()));
526 
527   PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
528   PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
529 
530   EXPECT_EQ(value_0, chk_int.GetInteger());
531   EXPECT_EQ(value_1, chk_str.GetString());
532 }
533 
534 TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) {
535   static const char *const string_key0 = "String Key 0";
536   static const char *const string_key1 = "String Key 1";
537 
538   static const char *const string_value0 = "String Value 0";
539   static const long int_value1 = 7;
540 
541   PythonDictionary dict(PyInitialValue::Empty);
542   dict.SetItemForKey(PythonString(string_key0), PythonString(string_value0));
543   dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1));
544 
545   auto dict_sp = dict.CreateStructuredDictionary();
546   EXPECT_EQ(2U, dict_sp->GetSize());
547 
548   EXPECT_TRUE(dict_sp->HasKey(string_key0));
549   EXPECT_TRUE(dict_sp->HasKey(string_key1));
550 
551   auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
552   auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsInteger();
553 
554   EXPECT_EQ(string_value0, string_sp->GetValue());
555   EXPECT_EQ(int_value1, long(int_sp->GetValue()));
556 }
557 
558 TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) {
559   PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info");
560   PythonObject none(PyRefType::Borrowed, Py_None);
561 
562   EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get()));
563   EXPECT_FALSE(PythonCallable::Check(none.get()));
564 }
565 
566 TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) {
567   auto list = m_builtins_module.ResolveName("list").AsType<PythonCallable>();
568   PythonInteger one(1);
569   PythonString two("two");
570   PythonTuple three = {one, two};
571 
572   PythonTuple tuple_to_convert = {one, two, three};
573   PythonObject result = list({tuple_to_convert});
574 
575   EXPECT_TRUE(PythonList::Check(result.get()));
576   auto list_result = result.AsType<PythonList>();
577   EXPECT_EQ(3U, list_result.GetSize());
578   EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get());
579   EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get());
580   EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get());
581 }
582 
583 TEST_F(PythonDataObjectsTest, TestPythonFile) {
584   auto file = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL),
585                                           File::eOpenOptionRead);
586   ASSERT_THAT_EXPECTED(file, llvm::Succeeded());
587   auto py_file = PythonFile::FromFile(*file.get(), "r");
588   ASSERT_THAT_EXPECTED(py_file, llvm::Succeeded());
589   EXPECT_TRUE(PythonFile::Check(py_file.get().get()));
590 }
591 
592 TEST_F(PythonDataObjectsTest, TestObjectAttributes) {
593   PythonInteger py_int(42);
594   EXPECT_TRUE(py_int.HasAttribute("numerator"));
595   EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist"));
596 
597   PythonInteger numerator_attr =
598       py_int.GetAttributeValue("numerator").AsType<PythonInteger>();
599   EXPECT_TRUE(numerator_attr.IsAllocated());
600   EXPECT_EQ(42, numerator_attr.GetInteger());
601 }
602 
603 TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
604   // Make up a custom dictionary with "sys" pointing to the `sys` module.
605   const char *key_name = "addr";
606   const uint64_t value = 0xf000000000000000ull;
607   PythonDictionary python_dict(PyInitialValue::Empty);
608   PythonInteger python_ull_value(PyRefType::Owned,
609                                  PyLong_FromUnsignedLongLong(value));
610   python_dict.SetItemForKey(PythonString(key_name), python_ull_value);
611   StructuredData::ObjectSP structured_data_sp =
612       python_dict.CreateStructuredObject();
613   EXPECT_TRUE((bool)structured_data_sp);
614   if (structured_data_sp) {
615     StructuredData::Dictionary *structured_dict_ptr =
616         structured_data_sp->GetAsDictionary();
617     EXPECT_TRUE(structured_dict_ptr != nullptr);
618     if (structured_dict_ptr) {
619       StructuredData::ObjectSP structured_addr_value_sp =
620           structured_dict_ptr->GetValueForKey(key_name);
621       EXPECT_TRUE((bool)structured_addr_value_sp);
622       const uint64_t extracted_value =
623           structured_addr_value_sp->GetIntegerValue(123);
624       EXPECT_TRUE(extracted_value == value);
625     }
626   }
627 }
628 
629 TEST_F(PythonDataObjectsTest, TestCallable) {
630 
631   PythonDictionary globals(PyInitialValue::Empty);
632   auto builtins = PythonModule::BuiltinsModule();
633   llvm::Error error = globals.SetItem("__builtins__", builtins);
634   ASSERT_FALSE(error);
635 
636   {
637     PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
638                                globals.get());
639     ASSERT_FALSE(o == NULL);
640     auto lambda = Take<PythonCallable>(o);
641     auto arginfo = lambda.GetArgInfo();
642     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
643     EXPECT_EQ(arginfo.get().count, 1);
644     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
645     EXPECT_EQ(arginfo.get().has_varargs, false);
646   }
647 
648   {
649     PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
650                                globals.get());
651     ASSERT_FALSE(o == NULL);
652     auto lambda = Take<PythonCallable>(o);
653     auto arginfo = lambda.GetArgInfo();
654     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
655     EXPECT_EQ(arginfo.get().count, 2);
656     EXPECT_EQ(arginfo.get().max_positional_args, 2u);
657     EXPECT_EQ(arginfo.get().has_varargs, false);
658   }
659 
660   {
661     PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
662                                globals.get(), globals.get());
663     ASSERT_FALSE(o == NULL);
664     auto lambda = Take<PythonCallable>(o);
665     auto arginfo = lambda.GetArgInfo();
666     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
667     EXPECT_EQ(arginfo.get().count, 2);
668     EXPECT_EQ(arginfo.get().max_positional_args, 2u);
669     EXPECT_EQ(arginfo.get().has_varargs, false);
670   }
671 
672   {
673     PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(),
674                                globals.get());
675     ASSERT_FALSE(o == NULL);
676     auto lambda = Take<PythonCallable>(o);
677     auto arginfo = lambda.GetArgInfo();
678     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
679     EXPECT_EQ(arginfo.get().count, 2);
680     EXPECT_EQ(arginfo.get().max_positional_args,
681               PythonCallable::ArgInfo::UNBOUNDED);
682     EXPECT_EQ(arginfo.get().has_varargs, true);
683   }
684 
685   {
686     PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
687                                globals.get(), globals.get());
688     ASSERT_FALSE(o == NULL);
689     auto lambda = Take<PythonCallable>(o);
690     auto arginfo = lambda.GetArgInfo();
691     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
692     EXPECT_EQ(arginfo.get().count, 2);
693     EXPECT_EQ(arginfo.get().max_positional_args,
694               PythonCallable::ArgInfo::UNBOUNDED);
695     EXPECT_EQ(arginfo.get().has_varargs, true);
696   }
697 
698   {
699     const char *script = R"(
700 class Foo:
701   def bar(self, x):
702      return x
703   @classmethod
704   def classbar(cls, x):
705      return x
706   @staticmethod
707   def staticbar(x):
708      return x
709   def __call__(self, x):
710      return x
711 obj = Foo()
712 bar_bound   = Foo().bar
713 bar_class   = Foo().classbar
714 bar_static  = Foo().staticbar
715 bar_unbound = Foo.bar
716 )";
717     PyObject *o =
718         PyRun_String(script, Py_file_input, globals.get(), globals.get());
719     ASSERT_FALSE(o == NULL);
720     Take<PythonObject>(o);
721 
722     auto bar_bound = As<PythonCallable>(globals.GetItem("bar_bound"));
723     ASSERT_THAT_EXPECTED(bar_bound, llvm::Succeeded());
724     auto arginfo = bar_bound.get().GetArgInfo();
725     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
726     EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
727     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
728     EXPECT_EQ(arginfo.get().has_varargs, false);
729 
730     auto bar_unbound = As<PythonCallable>(globals.GetItem("bar_unbound"));
731     ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
732     arginfo = bar_unbound.get().GetArgInfo();
733     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
734     EXPECT_EQ(arginfo.get().count, 2);
735     EXPECT_EQ(arginfo.get().max_positional_args, 2u);
736     EXPECT_EQ(arginfo.get().has_varargs, false);
737 
738     auto bar_class = As<PythonCallable>(globals.GetItem("bar_class"));
739     ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
740     arginfo = bar_class.get().GetArgInfo();
741     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
742     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
743     EXPECT_EQ(arginfo.get().has_varargs, false);
744 
745     auto bar_static = As<PythonCallable>(globals.GetItem("bar_static"));
746     ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
747     arginfo = bar_static.get().GetArgInfo();
748     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
749     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
750     EXPECT_EQ(arginfo.get().has_varargs, false);
751 
752     auto obj = As<PythonCallable>(globals.GetItem("obj"));
753     ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
754     arginfo = obj.get().GetArgInfo();
755     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
756     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
757     EXPECT_EQ(arginfo.get().has_varargs, false);
758   }
759 
760 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
761 
762   // the old implementation of GetArgInfo just doesn't work on builtins.
763 
764   {
765     auto builtins = PythonModule::BuiltinsModule();
766     auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
767     ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());
768     auto arginfo = hex.get().GetArgInfo();
769     ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
770     EXPECT_EQ(arginfo.get().count, 1);
771     EXPECT_EQ(arginfo.get().max_positional_args, 1u);
772     EXPECT_EQ(arginfo.get().has_varargs, false);
773   }
774 
775 #endif
776 }
777 
778 TEST_F(PythonDataObjectsTest, TestScript) {
779 
780   static const char script[] = R"(
781 def factorial(n):
782   if n > 1:
783     return n * factorial(n-1)
784   else:
785     return 1;
786 main = factorial
787 )";
788 
789   PythonScript factorial(script);
790 
791   EXPECT_THAT_EXPECTED(As<long long>(factorial(5ll)), llvm::HasValue(120));
792 }
793 
794 TEST_F(PythonDataObjectsTest, TestExceptions) {
795 
796   static const char script[] = R"(
797 def foo():
798   return bar()
799 def bar():
800   return baz()
801 def baz():
802   return 1 / 0
803 main = foo
804 )";
805 
806   PythonScript foo(script);
807 
808   EXPECT_THAT_EXPECTED(foo(),
809                        llvm::Failed<PythonException>(testing::Property(
810                            &PythonException::ReadBacktrace,
811                            testing::ContainsRegex("line 3, in foo..*"
812                                                   "line 5, in bar.*"
813                                                   "line 7, in baz.*"
814                                                   "ZeroDivisionError"))));
815 
816   static const char script2[] = R"(
817 class MyError(Exception):
818   def __str__(self):
819     return self.my_message
820 
821 def main():
822   raise MyError("lol")
823 
824 )";
825 
826   PythonScript lol(script2);
827 
828   EXPECT_THAT_EXPECTED(lol(),
829                        llvm::Failed<PythonException>(testing::Property(
830                            &PythonException::ReadBacktrace,
831                            testing::ContainsRegex("unprintable MyError"))));
832 }
833 
834 TEST_F(PythonDataObjectsTest, TestRun) {
835 
836   PythonDictionary globals(PyInitialValue::Empty);
837 
838   auto x = As<long long>(runStringOneLine("40 + 2", globals, globals));
839   ASSERT_THAT_EXPECTED(x, llvm::Succeeded());
840   EXPECT_EQ(x.get(), 42l);
841 
842   Expected<PythonObject> r = runStringOneLine("n = 42", globals, globals);
843   ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
844   auto y = As<long long>(globals.GetItem("n"));
845   ASSERT_THAT_EXPECTED(y, llvm::Succeeded());
846   EXPECT_EQ(y.get(), 42l);
847 
848   const char script[] = R"(
849 def foobar():
850   return "foo" + "bar" + "baz"
851 g = foobar()
852 )";
853 
854   r = runStringMultiLine(script, globals, globals);
855   ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
856   auto g = As<std::string>(globals.GetItem("g"));
857   ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz"));
858 }