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