1 //===-- PythonDataObjectsTests.cpp ----------------------------------------===//
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
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 "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"
20 #include "PythonTestSuite.h"
24 using namespace lldb_private
;
25 using namespace lldb_private::python
;
28 class PythonDataObjectsTest
: public PythonTestSuite
{
30 void SetUp() override
{
31 PythonTestSuite::SetUp();
33 m_sys_module
= unwrapIgnoringErrors(PythonModule::Import("sys"));
34 m_main_module
= PythonModule::MainModule();
35 m_builtins_module
= PythonModule::BuiltinsModule();
38 void TearDown() override
{
40 m_main_module
.Reset();
41 m_builtins_module
.Reset();
43 PythonTestSuite::TearDown();
47 PythonModule m_sys_module
;
48 PythonModule m_main_module
;
49 PythonModule m_builtins_module
;
52 TEST_F(PythonDataObjectsTest
, TestOwnedReferences
) {
53 // After creating a new object, the refcount should be >= 1
54 PyObject
*obj
= PyLong_FromLong(3);
55 Py_ssize_t original_refcnt
= obj
->ob_refcnt
;
56 EXPECT_LE(1, original_refcnt
);
58 // If we take an owned reference, the refcount should be the same
59 PythonObject
owned_long(PyRefType::Owned
, obj
);
60 EXPECT_EQ(original_refcnt
, owned_long
.get()->ob_refcnt
);
62 // Take another reference and verify that the refcount increases by 1
63 PythonObject
strong_ref(owned_long
);
64 EXPECT_EQ(original_refcnt
+ 1, strong_ref
.get()->ob_refcnt
);
66 // If we reset the first one, the refcount should be the original value.
68 EXPECT_EQ(original_refcnt
, strong_ref
.get()->ob_refcnt
);
71 TEST_F(PythonDataObjectsTest
, TestResetting
) {
72 PythonDictionary
dict(PyInitialValue::Empty
);
74 PyObject
*new_dict
= PyDict_New();
75 dict
= Take
<PythonDictionary
>(new_dict
);
76 EXPECT_EQ(new_dict
, dict
.get());
78 dict
= Take
<PythonDictionary
>(PyDict_New());
79 EXPECT_NE(nullptr, dict
.get());
81 EXPECT_EQ(nullptr, dict
.get());
84 TEST_F(PythonDataObjectsTest
, TestBorrowedReferences
) {
85 PythonInteger
long_value(PyRefType::Owned
, PyLong_FromLong(3));
86 Py_ssize_t original_refcnt
= long_value
.get()->ob_refcnt
;
87 EXPECT_LE(1, original_refcnt
);
89 PythonInteger
borrowed_long(PyRefType::Borrowed
, long_value
.get());
90 EXPECT_EQ(original_refcnt
+ 1, borrowed_long
.get()->ob_refcnt
);
93 TEST_F(PythonDataObjectsTest
, TestGlobalNameResolutionNoDot
) {
94 PythonObject sys_module
= m_main_module
.ResolveName("sys");
95 EXPECT_EQ(m_sys_module
.get(), sys_module
.get());
96 EXPECT_TRUE(sys_module
.IsAllocated());
97 EXPECT_TRUE(PythonModule::Check(sys_module
.get()));
100 TEST_F(PythonDataObjectsTest
, TestModuleNameResolutionNoDot
) {
101 PythonObject sys_path
= m_sys_module
.ResolveName("path");
102 PythonObject sys_version_info
= m_sys_module
.ResolveName("version_info");
103 EXPECT_TRUE(sys_path
.IsAllocated());
104 EXPECT_TRUE(sys_version_info
.IsAllocated());
106 EXPECT_TRUE(PythonList::Check(sys_path
.get()));
109 TEST_F(PythonDataObjectsTest
, TestTypeNameResolutionNoDot
) {
110 PythonObject sys_version_info
= m_sys_module
.ResolveName("version_info");
112 PythonObject
version_info_type(PyRefType::Owned
,
113 PyObject_Type(sys_version_info
.get()));
114 EXPECT_TRUE(version_info_type
.IsAllocated());
115 PythonObject major_version_field
= version_info_type
.ResolveName("major");
116 EXPECT_TRUE(major_version_field
.IsAllocated());
119 TEST_F(PythonDataObjectsTest
, TestInstanceNameResolutionNoDot
) {
120 PythonObject sys_version_info
= m_sys_module
.ResolveName("version_info");
121 PythonObject major_version_field
= sys_version_info
.ResolveName("major");
122 PythonObject minor_version_field
= sys_version_info
.ResolveName("minor");
124 EXPECT_TRUE(major_version_field
.IsAllocated());
125 EXPECT_TRUE(minor_version_field
.IsAllocated());
127 auto major_version_value
= As
<long long>(major_version_field
);
128 auto minor_version_value
= As
<long long>(minor_version_field
);
130 EXPECT_THAT_EXPECTED(major_version_value
, llvm::HasValue(PY_MAJOR_VERSION
));
131 EXPECT_THAT_EXPECTED(minor_version_value
, llvm::HasValue(PY_MINOR_VERSION
));
134 TEST_F(PythonDataObjectsTest
, TestGlobalNameResolutionWithDot
) {
135 PythonObject sys_path
= m_main_module
.ResolveName("sys.path");
136 EXPECT_TRUE(sys_path
.IsAllocated());
137 EXPECT_TRUE(PythonList::Check(sys_path
.get()));
140 As
<long long>(m_main_module
.ResolveName("sys.version_info.major"));
143 As
<long long>(m_main_module
.ResolveName("sys.version_info.minor"));
145 EXPECT_THAT_EXPECTED(version_major
, llvm::HasValue(PY_MAJOR_VERSION
));
146 EXPECT_THAT_EXPECTED(version_minor
, llvm::HasValue(PY_MINOR_VERSION
));
149 TEST_F(PythonDataObjectsTest
, TestDictionaryResolutionWithDot
) {
150 // Make up a custom dictionary with "sys" pointing to the `sys` module.
151 PythonDictionary
dict(PyInitialValue::Empty
);
152 dict
.SetItemForKey(PythonString("sys"), m_sys_module
);
154 // Now use that dictionary to resolve `sys.version_info.major`
155 auto version_major
= As
<long long>(
156 PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict
));
158 auto version_minor
= As
<long long>(
159 PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict
));
161 EXPECT_THAT_EXPECTED(version_major
, llvm::HasValue(PY_MAJOR_VERSION
));
162 EXPECT_THAT_EXPECTED(version_minor
, llvm::HasValue(PY_MINOR_VERSION
));
165 TEST_F(PythonDataObjectsTest
, TestPythonInteger
) {
166 // Test that integers behave correctly when wrapped by a PythonInteger.
168 // Verify that `PythonInteger` works correctly when given a PyLong object.
169 PyObject
*py_long
= PyLong_FromLong(12);
170 EXPECT_TRUE(PythonInteger::Check(py_long
));
171 PythonInteger
python_long(PyRefType::Owned
, py_long
);
172 EXPECT_EQ(PyObjectType::Integer
, python_long
.GetObjectType());
174 // Verify that you can reset the value and that it is reflected properly.
175 python_long
.SetInteger(40);
176 auto e
= As
<long long>(python_long
);
177 EXPECT_THAT_EXPECTED(e
, llvm::HasValue(40));
179 // Test that creating a `PythonInteger` object works correctly with the
181 PythonInteger
constructed_int(7);
182 auto value
= As
<long long>(constructed_int
);
183 EXPECT_THAT_EXPECTED(value
, llvm::HasValue(7));
186 TEST_F(PythonDataObjectsTest
, TestPythonBoolean
) {
187 // Test PythonBoolean constructed from Py_True
188 EXPECT_TRUE(PythonBoolean::Check(Py_True
));
189 PythonBoolean
python_true(PyRefType::Owned
, Py_True
);
190 EXPECT_EQ(PyObjectType::Boolean
, python_true
.GetObjectType());
192 // Test PythonBoolean constructed from Py_False
193 EXPECT_TRUE(PythonBoolean::Check(Py_False
));
194 PythonBoolean
python_false(PyRefType::Owned
, Py_False
);
195 EXPECT_EQ(PyObjectType::Boolean
, python_false
.GetObjectType());
197 auto test_from_long
= [](long value
) {
198 PyObject
*py_bool
= PyBool_FromLong(value
);
199 EXPECT_TRUE(PythonBoolean::Check(py_bool
));
200 PythonBoolean
python_boolean(PyRefType::Owned
, py_bool
);
201 EXPECT_EQ(PyObjectType::Boolean
, python_boolean
.GetObjectType());
202 EXPECT_EQ(bool(value
), python_boolean
.GetValue());
205 // Test PythonBoolean constructed from long integer values.
206 test_from_long(0); // Test 'false' value.
207 test_from_long(1); // Test 'true' value.
208 test_from_long(~0); // Any value != 0 is 'true'.
211 TEST_F(PythonDataObjectsTest
, TestPythonBytes
) {
212 static const char *test_bytes
= "PythonDataObjectsTest::TestPythonBytes";
213 PyObject
*py_bytes
= PyBytes_FromString(test_bytes
);
214 EXPECT_TRUE(PythonBytes::Check(py_bytes
));
215 PythonBytes
python_bytes(PyRefType::Owned
, py_bytes
);
217 EXPECT_FALSE(PythonString::Check(py_bytes
));
218 EXPECT_EQ(PyObjectType::Bytes
, python_bytes
.GetObjectType());
220 llvm::ArrayRef
<uint8_t> bytes
= python_bytes
.GetBytes();
221 EXPECT_EQ(bytes
.size(), strlen(test_bytes
));
222 EXPECT_EQ(0, ::memcmp(bytes
.data(), test_bytes
, bytes
.size()));
225 TEST_F(PythonDataObjectsTest
, TestPythonByteArray
) {
226 static const char *test_bytes
= "PythonDataObjectsTest::TestPythonByteArray";
227 llvm::StringRef
orig_bytes(test_bytes
);
229 PyByteArray_FromStringAndSize(test_bytes
, orig_bytes
.size());
230 EXPECT_TRUE(PythonByteArray::Check(py_bytes
));
231 PythonByteArray
python_bytes(PyRefType::Owned
, py_bytes
);
232 EXPECT_EQ(PyObjectType::ByteArray
, python_bytes
.GetObjectType());
234 llvm::ArrayRef
<uint8_t> after_bytes
= python_bytes
.GetBytes();
235 EXPECT_EQ(after_bytes
.size(), orig_bytes
.size());
236 EXPECT_EQ(0, ::memcmp(orig_bytes
.data(), test_bytes
, orig_bytes
.size()));
239 TEST_F(PythonDataObjectsTest
, TestPythonString
) {
240 // Test that strings behave correctly when wrapped by a PythonString.
242 static const char *test_string
= "PythonDataObjectsTest::TestPythonString1";
243 static const char *test_string2
= "PythonDataObjectsTest::TestPythonString2";
245 // Verify that `PythonString` works correctly when given a PyUnicode object.
246 PyObject
*py_unicode
= PyUnicode_FromString(test_string
);
247 EXPECT_TRUE(PythonString::Check(py_unicode
));
248 PythonString
python_unicode(PyRefType::Owned
, py_unicode
);
249 EXPECT_EQ(PyObjectType::String
, python_unicode
.GetObjectType());
250 EXPECT_STREQ(test_string
, python_unicode
.GetString().data());
252 // Test that creating a `PythonString` object works correctly with the
253 // string constructor
254 PythonString
constructed_string(test_string2
);
255 EXPECT_EQ(test_string2
, constructed_string
.GetString());
258 TEST_F(PythonDataObjectsTest
, TestPythonStringToStr
) {
259 const char *GetString
= "PythonDataObjectsTest::TestPythonStringToStr";
261 PythonString
str(GetString
);
262 EXPECT_EQ(GetString
, str
.GetString());
264 PythonString str_str
= str
.Str();
265 EXPECT_EQ(GetString
, str_str
.GetString());
268 TEST_F(PythonDataObjectsTest
, TestPythonIntegerToStr
) {}
270 TEST_F(PythonDataObjectsTest
, TestPythonIntegerToStructuredUnsignedInteger
) {
271 PythonInteger
integer(7);
272 auto int_sp
= integer
.CreateStructuredInteger();
274 std::holds_alternative
<StructuredData::UnsignedIntegerSP
>(int_sp
));
275 StructuredData::UnsignedIntegerSP uint_sp
=
276 std::get
<StructuredData::UnsignedIntegerSP
>(int_sp
);
277 EXPECT_EQ(7U, uint_sp
->GetValue());
280 TEST_F(PythonDataObjectsTest
, TestPythonIntegerToStructuredSignedInteger
) {
281 PythonInteger
integer(-42);
282 auto int_sp
= integer
.CreateStructuredInteger();
283 EXPECT_TRUE(std::holds_alternative
<StructuredData::SignedIntegerSP
>(int_sp
));
284 StructuredData::SignedIntegerSP sint_sp
=
285 std::get
<StructuredData::SignedIntegerSP
>(int_sp
);
286 EXPECT_EQ(-42, sint_sp
->GetValue());
289 TEST_F(PythonDataObjectsTest
, TestPythonStringToStructuredString
) {
290 static const char *test_string
=
291 "PythonDataObjectsTest::TestPythonStringToStructuredString";
292 PythonString
constructed_string(test_string
);
293 auto string_sp
= constructed_string
.CreateStructuredString();
294 EXPECT_EQ(test_string
, string_sp
->GetStringValue());
297 TEST_F(PythonDataObjectsTest
, TestPythonListValueEquality
) {
298 // Test that a list which is built through the native
299 // Python API behaves correctly when wrapped by a PythonList.
300 static const unsigned list_size
= 2;
301 static const long long_value0
= 5;
302 static const char *const string_value1
= "String Index 1";
304 PyObject
*py_list
= PyList_New(2);
305 EXPECT_TRUE(PythonList::Check(py_list
));
306 PythonList
list(PyRefType::Owned
, py_list
);
308 PythonObject list_items
[list_size
];
309 list_items
[0] = PythonInteger(long_value0
);
310 list_items
[1] = PythonString(string_value1
);
312 for (unsigned i
= 0; i
< list_size
; ++i
)
313 list
.SetItemAtIndex(i
, list_items
[i
]);
315 EXPECT_EQ(list_size
, list
.GetSize());
316 EXPECT_EQ(PyObjectType::List
, list
.GetObjectType());
318 // Verify that the values match
319 PythonObject chk_value1
= list
.GetItemAtIndex(0);
320 PythonObject chk_value2
= list
.GetItemAtIndex(1);
321 EXPECT_TRUE(PythonInteger::Check(chk_value1
.get()));
322 EXPECT_TRUE(PythonString::Check(chk_value2
.get()));
324 PythonInteger
chk_int(PyRefType::Borrowed
, chk_value1
.get());
325 PythonString
chk_str(PyRefType::Borrowed
, chk_value2
.get());
327 auto chkint
= As
<long long>(chk_value1
);
328 ASSERT_THAT_EXPECTED(chkint
, llvm::HasValue(long_value0
));
329 EXPECT_EQ(string_value1
, chk_str
.GetString());
332 TEST_F(PythonDataObjectsTest
, TestPythonListManipulation
) {
333 // Test that manipulation of a PythonList behaves correctly when
334 // wrapped by a PythonDictionary.
336 static const long long_value0
= 5;
337 static const char *const string_value1
= "String Index 1";
339 PythonList
list(PyInitialValue::Empty
);
340 PythonInteger
integer(long_value0
);
341 PythonString
string(string_value1
);
343 list
.AppendItem(integer
);
344 list
.AppendItem(string
);
345 EXPECT_EQ(2U, list
.GetSize());
347 // Verify that the values match
348 PythonObject chk_value1
= list
.GetItemAtIndex(0);
349 PythonObject chk_value2
= list
.GetItemAtIndex(1);
350 EXPECT_TRUE(PythonInteger::Check(chk_value1
.get()));
351 EXPECT_TRUE(PythonString::Check(chk_value2
.get()));
353 PythonInteger
chk_int(PyRefType::Borrowed
, chk_value1
.get());
354 PythonString
chk_str(PyRefType::Borrowed
, chk_value2
.get());
356 auto e
= As
<long long>(chk_int
);
357 EXPECT_THAT_EXPECTED(e
, llvm::HasValue(long_value0
));
358 EXPECT_EQ(string_value1
, chk_str
.GetString());
361 TEST_F(PythonDataObjectsTest
, TestPythonListToStructuredList
) {
362 static const long long_value0
= 5;
363 static const char *const string_value1
= "String Index 1";
365 PythonList
list(PyInitialValue::Empty
);
366 list
.AppendItem(PythonInteger(long_value0
));
367 list
.AppendItem(PythonString(string_value1
));
369 auto array_sp
= list
.CreateStructuredArray();
370 EXPECT_EQ(lldb::eStructuredDataTypeInteger
,
371 array_sp
->GetItemAtIndex(0)->GetType());
372 EXPECT_EQ(lldb::eStructuredDataTypeString
,
373 array_sp
->GetItemAtIndex(1)->GetType());
375 auto int_sp
= array_sp
->GetItemAtIndex(0)->GetAsUnsignedInteger();
376 auto string_sp
= array_sp
->GetItemAtIndex(1)->GetAsString();
378 EXPECT_EQ(long_value0
, long(int_sp
->GetValue()));
379 EXPECT_EQ(string_value1
, string_sp
->GetValue());
382 TEST_F(PythonDataObjectsTest
, TestPythonTupleSize
) {
383 PythonTuple
tuple(PyInitialValue::Empty
);
384 EXPECT_EQ(0U, tuple
.GetSize());
386 tuple
= PythonTuple(3);
387 EXPECT_EQ(3U, tuple
.GetSize());
390 TEST_F(PythonDataObjectsTest
, TestPythonTupleValues
) {
391 PythonTuple
tuple(3);
393 PythonInteger
int_value(1);
394 PythonString
string_value("Test");
395 PythonObject
none_value(PyRefType::Borrowed
, Py_None
);
397 tuple
.SetItemAtIndex(0, int_value
);
398 tuple
.SetItemAtIndex(1, string_value
);
399 tuple
.SetItemAtIndex(2, none_value
);
401 EXPECT_EQ(tuple
.GetItemAtIndex(0).get(), int_value
.get());
402 EXPECT_EQ(tuple
.GetItemAtIndex(1).get(), string_value
.get());
403 EXPECT_EQ(tuple
.GetItemAtIndex(2).get(), none_value
.get());
406 TEST_F(PythonDataObjectsTest
, TestPythonTupleInitializerList
) {
407 PythonInteger
int_value(1);
408 PythonString
string_value("Test");
409 PythonObject
none_value(PyRefType::Borrowed
, Py_None
);
410 PythonTuple tuple
{int_value
, string_value
, none_value
};
411 EXPECT_EQ(3U, tuple
.GetSize());
413 EXPECT_EQ(tuple
.GetItemAtIndex(0).get(), int_value
.get());
414 EXPECT_EQ(tuple
.GetItemAtIndex(1).get(), string_value
.get());
415 EXPECT_EQ(tuple
.GetItemAtIndex(2).get(), none_value
.get());
418 TEST_F(PythonDataObjectsTest
, TestPythonTupleInitializerList2
) {
419 PythonInteger
int_value(1);
420 PythonString
string_value("Test");
421 PythonObject
none_value(PyRefType::Borrowed
, Py_None
);
423 PythonTuple tuple
{int_value
.get(), string_value
.get(), none_value
.get()};
424 EXPECT_EQ(3U, tuple
.GetSize());
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());
431 TEST_F(PythonDataObjectsTest
, TestPythonTupleToStructuredList
) {
432 PythonInteger
int_value(1);
433 PythonString
string_value("Test");
435 PythonTuple tuple
{int_value
.get(), string_value
.get()};
437 auto array_sp
= tuple
.CreateStructuredArray();
438 EXPECT_EQ(tuple
.GetSize(), array_sp
->GetSize());
439 EXPECT_EQ(lldb::eStructuredDataTypeInteger
,
440 array_sp
->GetItemAtIndex(0)->GetType());
441 EXPECT_EQ(lldb::eStructuredDataTypeString
,
442 array_sp
->GetItemAtIndex(1)->GetType());
445 TEST_F(PythonDataObjectsTest
, TestPythonDictionaryValueEquality
) {
446 // Test that a dictionary which is built through the native
447 // Python API behaves correctly when wrapped by a PythonDictionary.
448 static const unsigned dict_entries
= 2;
449 const char *key_0
= "Key 0";
451 const int value_0
= 0;
452 const char *value_1
= "Value 1";
454 PythonObject py_keys
[dict_entries
];
455 PythonObject py_values
[dict_entries
];
457 py_keys
[0] = PythonString(key_0
);
458 py_keys
[1] = PythonInteger(key_1
);
459 py_values
[0] = PythonInteger(value_0
);
460 py_values
[1] = PythonString(value_1
);
462 PyObject
*py_dict
= PyDict_New();
463 EXPECT_TRUE(PythonDictionary::Check(py_dict
));
464 PythonDictionary
dict(PyRefType::Owned
, py_dict
);
466 for (unsigned i
= 0; i
< dict_entries
; ++i
)
467 PyDict_SetItem(py_dict
, py_keys
[i
].get(), py_values
[i
].get());
468 EXPECT_EQ(dict
.GetSize(), dict_entries
);
469 EXPECT_EQ(PyObjectType::Dictionary
, dict
.GetObjectType());
471 // Verify that the values match
472 PythonObject chk_value1
= dict
.GetItemForKey(py_keys
[0]);
473 PythonObject chk_value2
= dict
.GetItemForKey(py_keys
[1]);
474 EXPECT_TRUE(PythonInteger::Check(chk_value1
.get()));
475 EXPECT_TRUE(PythonString::Check(chk_value2
.get()));
477 PythonString
chk_str(PyRefType::Borrowed
, chk_value2
.get());
478 auto chkint
= As
<long long>(chk_value1
);
480 EXPECT_THAT_EXPECTED(chkint
, llvm::HasValue(value_0
));
481 EXPECT_EQ(value_1
, chk_str
.GetString());
484 TEST_F(PythonDataObjectsTest
, TestPythonDictionaryManipulation
) {
485 // Test that manipulation of a dictionary behaves correctly when wrapped
486 // by a PythonDictionary.
487 static const unsigned dict_entries
= 2;
489 const char *const key_0
= "Key 0";
490 const char *const key_1
= "Key 1";
491 const long value_0
= 1;
492 const char *const value_1
= "Value 1";
494 PythonString keys
[dict_entries
];
495 PythonObject values
[dict_entries
];
497 keys
[0] = PythonString(key_0
);
498 keys
[1] = PythonString(key_1
);
499 values
[0] = PythonInteger(value_0
);
500 values
[1] = PythonString(value_1
);
502 PythonDictionary
dict(PyInitialValue::Empty
);
503 for (int i
= 0; i
< 2; ++i
)
504 dict
.SetItemForKey(keys
[i
], values
[i
]);
506 EXPECT_EQ(dict_entries
, dict
.GetSize());
508 // Verify that the keys and values match
509 PythonObject chk_value1
= dict
.GetItemForKey(keys
[0]);
510 PythonObject chk_value2
= dict
.GetItemForKey(keys
[1]);
511 EXPECT_TRUE(PythonInteger::Check(chk_value1
.get()));
512 EXPECT_TRUE(PythonString::Check(chk_value2
.get()));
514 auto chkint
= As
<long long>(chk_value1
);
515 PythonString
chk_str(PyRefType::Borrowed
, chk_value2
.get());
517 EXPECT_THAT_EXPECTED(chkint
, llvm::HasValue(value_0
));
518 EXPECT_EQ(value_1
, chk_str
.GetString());
521 TEST_F(PythonDataObjectsTest
, TestPythonDictionaryToStructuredDictionary
) {
522 static const char *const string_key0
= "String Key 0";
523 static const char *const string_key1
= "String Key 1";
525 static const char *const string_value0
= "String Value 0";
526 static const long int_value1
= 7;
528 PythonDictionary
dict(PyInitialValue::Empty
);
529 dict
.SetItemForKey(PythonString(string_key0
), PythonString(string_value0
));
530 dict
.SetItemForKey(PythonString(string_key1
), PythonInteger(int_value1
));
532 auto dict_sp
= dict
.CreateStructuredDictionary();
533 EXPECT_EQ(2U, dict_sp
->GetSize());
535 EXPECT_TRUE(dict_sp
->HasKey(string_key0
));
536 EXPECT_TRUE(dict_sp
->HasKey(string_key1
));
538 auto string_sp
= dict_sp
->GetValueForKey(string_key0
)->GetAsString();
539 auto int_sp
= dict_sp
->GetValueForKey(string_key1
)->GetAsUnsignedInteger();
541 EXPECT_EQ(string_value0
, string_sp
->GetValue());
542 EXPECT_EQ(int_value1
, long(int_sp
->GetValue()));
545 TEST_F(PythonDataObjectsTest
, TestPythonCallableCheck
) {
546 PythonObject sys_exc_info
= m_sys_module
.ResolveName("exc_info");
547 PythonObject
none(PyRefType::Borrowed
, Py_None
);
549 EXPECT_TRUE(PythonCallable::Check(sys_exc_info
.get()));
550 EXPECT_FALSE(PythonCallable::Check(none
.get()));
553 TEST_F(PythonDataObjectsTest
, TestPythonCallableInvoke
) {
554 auto list
= m_builtins_module
.ResolveName("list").AsType
<PythonCallable
>();
555 PythonInteger
one(1);
556 PythonString
two("two");
557 PythonTuple three
= {one
, two
};
559 PythonTuple tuple_to_convert
= {one
, two
, three
};
560 PythonObject result
= list({tuple_to_convert
});
562 EXPECT_TRUE(PythonList::Check(result
.get()));
563 auto list_result
= result
.AsType
<PythonList
>();
564 EXPECT_EQ(3U, list_result
.GetSize());
565 EXPECT_EQ(one
.get(), list_result
.GetItemAtIndex(0).get());
566 EXPECT_EQ(two
.get(), list_result
.GetItemAtIndex(1).get());
567 EXPECT_EQ(three
.get(), list_result
.GetItemAtIndex(2).get());
570 TEST_F(PythonDataObjectsTest
, TestPythonFile
) {
571 auto file
= FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL
),
572 File::eOpenOptionReadOnly
);
573 ASSERT_THAT_EXPECTED(file
, llvm::Succeeded());
574 auto py_file
= PythonFile::FromFile(*file
.get(), "r");
575 ASSERT_THAT_EXPECTED(py_file
, llvm::Succeeded());
576 EXPECT_TRUE(PythonFile::Check(py_file
.get().get()));
579 TEST_F(PythonDataObjectsTest
, TestObjectAttributes
) {
580 PythonInteger
py_int(42);
581 EXPECT_TRUE(py_int
.HasAttribute("numerator"));
582 EXPECT_FALSE(py_int
.HasAttribute("this_should_not_exist"));
584 auto numerator_attr
= As
<long long>(py_int
.GetAttributeValue("numerator"));
586 EXPECT_THAT_EXPECTED(numerator_attr
, llvm::HasValue(42));
589 TEST_F(PythonDataObjectsTest
, TestExtractingUInt64ThroughStructuredData
) {
590 // Make up a custom dictionary with "sys" pointing to the `sys` module.
591 const char *key_name
= "addr";
592 const uint64_t value
= 0xf000000000000000ull
;
593 PythonDictionary
python_dict(PyInitialValue::Empty
);
594 PythonInteger
python_ull_value(PyRefType::Owned
,
595 PyLong_FromUnsignedLongLong(value
));
596 python_dict
.SetItemForKey(PythonString(key_name
), python_ull_value
);
597 StructuredData::ObjectSP structured_data_sp
=
598 python_dict
.CreateStructuredObject();
599 EXPECT_TRUE((bool)structured_data_sp
);
600 if (structured_data_sp
) {
601 StructuredData::Dictionary
*structured_dict_ptr
=
602 structured_data_sp
->GetAsDictionary();
603 EXPECT_TRUE(structured_dict_ptr
!= nullptr);
604 if (structured_dict_ptr
) {
605 StructuredData::ObjectSP structured_addr_value_sp
=
606 structured_dict_ptr
->GetValueForKey(key_name
);
607 EXPECT_TRUE((bool)structured_addr_value_sp
);
608 const uint64_t extracted_value
=
609 structured_addr_value_sp
->GetUnsignedIntegerValue(123);
610 EXPECT_TRUE(extracted_value
== value
);
615 TEST_F(PythonDataObjectsTest
, TestCallable
) {
617 PythonDictionary
globals(PyInitialValue::Empty
);
618 auto builtins
= PythonModule::BuiltinsModule();
619 llvm::Error error
= globals
.SetItem("__builtins__", builtins
);
623 PyObject
*o
= PyRun_String("lambda x : x", Py_eval_input
, globals
.get(),
625 ASSERT_FALSE(o
== NULL
);
626 auto lambda
= Take
<PythonCallable
>(o
);
627 auto arginfo
= lambda
.GetArgInfo();
628 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
629 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
633 PyObject
*o
= PyRun_String("lambda x,y=0: x", Py_eval_input
, globals
.get(),
635 ASSERT_FALSE(o
== NULL
);
636 auto lambda
= Take
<PythonCallable
>(o
);
637 auto arginfo
= lambda
.GetArgInfo();
638 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
639 EXPECT_EQ(arginfo
.get().max_positional_args
, 2u);
643 PyObject
*o
= PyRun_String("lambda x,y=0, **kw: x", Py_eval_input
,
644 globals
.get(), globals
.get());
645 ASSERT_FALSE(o
== NULL
);
646 auto lambda
= Take
<PythonCallable
>(o
);
647 auto arginfo
= lambda
.GetArgInfo();
648 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
649 EXPECT_EQ(arginfo
.get().max_positional_args
, 2u);
653 PyObject
*o
= PyRun_String("lambda x,y,*a: x", Py_eval_input
, globals
.get(),
655 ASSERT_FALSE(o
== NULL
);
656 auto lambda
= Take
<PythonCallable
>(o
);
657 auto arginfo
= lambda
.GetArgInfo();
658 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
659 EXPECT_EQ(arginfo
.get().max_positional_args
,
660 PythonCallable::ArgInfo::UNBOUNDED
);
664 PyObject
*o
= PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input
,
665 globals
.get(), globals
.get());
666 ASSERT_FALSE(o
== NULL
);
667 auto lambda
= Take
<PythonCallable
>(o
);
668 auto arginfo
= lambda
.GetArgInfo();
669 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
670 EXPECT_EQ(arginfo
.get().max_positional_args
,
671 PythonCallable::ArgInfo::UNBOUNDED
);
675 const char *script
= R
"(
680 def classbar(cls, x):
685 def __call__(self, x):
688 bar_bound = Foo().bar
689 bar_class = Foo().classbar
690 bar_static = Foo().staticbar
691 bar_unbound = Foo.bar
695 def __init__(self, one, two, three):
698 class NewStyle(object):
699 def __init__(self, one, two, three):
704 PyRun_String(script
, Py_file_input
, globals
.get(), globals
.get());
705 ASSERT_FALSE(o
== NULL
);
706 Take
<PythonObject
>(o
);
708 auto bar_bound
= As
<PythonCallable
>(globals
.GetItem("bar_bound"));
709 ASSERT_THAT_EXPECTED(bar_bound
, llvm::Succeeded());
710 auto arginfo
= bar_bound
.get().GetArgInfo();
711 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
712 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
714 auto bar_unbound
= As
<PythonCallable
>(globals
.GetItem("bar_unbound"));
715 ASSERT_THAT_EXPECTED(bar_unbound
, llvm::Succeeded());
716 arginfo
= bar_unbound
.get().GetArgInfo();
717 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
718 EXPECT_EQ(arginfo
.get().max_positional_args
, 2u);
720 auto bar_class
= As
<PythonCallable
>(globals
.GetItem("bar_class"));
721 ASSERT_THAT_EXPECTED(bar_class
, llvm::Succeeded());
722 arginfo
= bar_class
.get().GetArgInfo();
723 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
724 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
726 auto bar_static
= As
<PythonCallable
>(globals
.GetItem("bar_static"));
727 ASSERT_THAT_EXPECTED(bar_static
, llvm::Succeeded());
728 arginfo
= bar_static
.get().GetArgInfo();
729 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
730 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
732 auto obj
= As
<PythonCallable
>(globals
.GetItem("obj"));
733 ASSERT_THAT_EXPECTED(obj
, llvm::Succeeded());
734 arginfo
= obj
.get().GetArgInfo();
735 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
736 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
738 auto oldstyle
= As
<PythonCallable
>(globals
.GetItem("OldStyle"));
739 ASSERT_THAT_EXPECTED(oldstyle
, llvm::Succeeded());
740 arginfo
= oldstyle
.get().GetArgInfo();
741 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
742 EXPECT_EQ(arginfo
.get().max_positional_args
, 3u);
744 auto newstyle
= As
<PythonCallable
>(globals
.GetItem("NewStyle"));
745 ASSERT_THAT_EXPECTED(newstyle
, llvm::Succeeded());
746 arginfo
= newstyle
.get().GetArgInfo();
747 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
748 EXPECT_EQ(arginfo
.get().max_positional_args
, 3u);
751 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
753 // the old implementation of GetArgInfo just doesn't work on builtins.
756 auto builtins
= PythonModule::BuiltinsModule();
757 auto hex
= As
<PythonCallable
>(builtins
.GetAttribute("hex"));
758 ASSERT_THAT_EXPECTED(hex
, llvm::Succeeded());
759 auto arginfo
= hex
.get().GetArgInfo();
760 ASSERT_THAT_EXPECTED(arginfo
, llvm::Succeeded());
761 EXPECT_EQ(arginfo
.get().max_positional_args
, 1u);
767 TEST_F(PythonDataObjectsTest
, TestScript
) {
769 static const char script
[] = R
"(
772 return n * factorial(n-1)
778 PythonScript
factorial(script
);
780 EXPECT_THAT_EXPECTED(As
<long long>(factorial(5ll)), llvm::HasValue(120));
783 TEST_F(PythonDataObjectsTest
, TestExceptions
) {
785 static const char script
[] = R
"(
795 PythonScript
foo(script
);
797 EXPECT_THAT_EXPECTED(
798 foo(), llvm::Failed
<PythonException
>(testing::Property(
799 &PythonException::ReadBacktrace
,
800 testing::AllOf(testing::ContainsRegex("line 3, in foo"),
801 testing::ContainsRegex("line 5, in bar"),
802 testing::ContainsRegex("line 7, in baz"),
803 testing::ContainsRegex("ZeroDivisionError")))));
805 #if !((defined(_WIN32) || defined(_WIN64)) && (defined(__aarch64__) || defined(_M_ARM64)))
807 static const char script2
[] = R
"(
808 class MyError(Exception):
810 return self.my_message
817 PythonScript
lol(script2
);
819 EXPECT_THAT_EXPECTED(
821 llvm::Failed
<PythonException
>(testing::Property(
822 &PythonException::ReadBacktrace
,
824 testing::ContainsRegex("MyError: <exception str\\(\\) failed>"),
825 testing::ContainsRegex("unprintable MyError")))));
830 TEST_F(PythonDataObjectsTest
, TestRun
) {
832 PythonDictionary
globals(PyInitialValue::Empty
);
834 auto x
= As
<long long>(runStringOneLine("40 + 2", globals
, globals
));
835 ASSERT_THAT_EXPECTED(x
, llvm::Succeeded());
836 EXPECT_EQ(x
.get(), 42l);
838 Expected
<PythonObject
> r
= runStringOneLine("n = 42", globals
, globals
);
839 ASSERT_THAT_EXPECTED(r
, llvm::Succeeded());
840 auto y
= As
<long long>(globals
.GetItem("n"));
841 ASSERT_THAT_EXPECTED(y
, llvm::Succeeded());
842 EXPECT_EQ(y
.get(), 42l);
844 const char script
[] = R
"(
846 return "foo
" + "bar
" + "baz
"
850 r
= runStringMultiLine(script
, globals
, globals
);
851 ASSERT_THAT_EXPECTED(r
, llvm::Succeeded());
852 auto g
= As
<std::string
>(globals
.GetItem("g"));
853 ASSERT_THAT_EXPECTED(g
, llvm::HasValue("foobarbaz"));