[Lldb-commits] [lldb] [lldb] Add Pythonic API to SBStructuredData extension (PR #155061)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Sat Aug 23 11:12:14 PDT 2025
https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/155061
>From 8c8a17a0ac56d31ec9cf8319a5aa33060852ef27 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Fri, 22 Aug 2025 19:34:57 -0700
Subject: [PATCH 1/4] [lldb] Add Pythonic API to SBStructuredData extension
* Implements `__getitem__` for array and dictionary subscripting
* Updates `__iter__` to support dictionary instances
* Adds converstion to `str`, `int`, and `float`
* Adds `bool` conversion
Additionally did some cleanup in TestStructuredDataAPI.py.
---
.../interface/SBStructuredDataExtensions.i | 119 ++++++++++++++++-
.../sbstructureddata/TestStructuredDataAPI.py | 121 ++++++++++++++----
2 files changed, 210 insertions(+), 30 deletions(-)
diff --git a/lldb/bindings/interface/SBStructuredDataExtensions.i b/lldb/bindings/interface/SBStructuredDataExtensions.i
index ca3d0966f9fc1..900dc192df2bb 100644
--- a/lldb/bindings/interface/SBStructuredDataExtensions.i
+++ b/lldb/bindings/interface/SBStructuredDataExtensions.i
@@ -3,16 +3,127 @@ STRING_EXTENSION_OUTSIDE(SBStructuredData)
%extend lldb::SBStructuredData {
#ifdef SWIGPYTHON
%pythoncode%{
- def __int__(self):
- return self.GetSignedInteger()
-
def __len__(self):
'''Return the number of element in a lldb.SBStructuredData object.'''
return self.GetSize()
def __iter__(self):
'''Iterate over all the elements in a lldb.SBStructuredData object.'''
- return lldb_iter(self, 'GetSize', 'GetItemAtIndex')
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeArray:
+ return lldb_iter(self, 'GetSize', 'GetItemAtIndex')
+ elif data_type == eStructuredDataTypeDictionary:
+ keys = SBStringList()
+ self.GetKeys(keys)
+ return iter(keys)
+ raise TypeError(f"cannot iterate {self.type_name(data_type)} type")
+
+ def __getitem__(self, key):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeArray:
+ if not isinstance(key, int):
+ raise TypeError("subscript index must be an integer")
+ count = len(self)
+ if -count <= key < count:
+ key %= count
+ return self.GetItemAtIndex(key)
+ raise IndexError("index out of range")
+ elif data_type == eStructuredDataTypeDictionary:
+ if not isinstance(key, str):
+ raise TypeError("subscript key must be a string")
+ return self.GetValueForKey(key)
+ else:
+ raise TypeError(f"cannot subscript {self.type_name(data_type)} type")
+
+ def __bool__(self):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeBoolean:
+ return self.GetBooleanValue()
+ elif data_type == eStructuredDataTypeInteger:
+ return bool(int(self))
+ elif data_type == eStructuredDataTypeSignedInteger:
+ return bool(int(self))
+ elif data_type == eStructuredDataTypeFloat:
+ return bool(float(self))
+ elif data_type == eStructuredDataTypeString:
+ return bool(str(self))
+ elif data_type == eStructuredDataTypeArray:
+ return bool(len(self))
+ elif data_type == eStructuredDataTypeDictionary:
+ return bool(len(self))
+ elif data_type == eStructuredDataTypeNull:
+ return False
+ elif data_type == eStructuredDataTypeInvalid:
+ return False
+ else:
+ raise TypeError(f"cannot convert {self.type_name(data_type)} to bool")
+
+ def __str__(self):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeString:
+ size = len(self) or 1023
+ return self.GetStringValue(size + 1)
+ elif data_type == eStructuredDataTypeInteger:
+ return str(int(self))
+ elif data_type == eStructuredDataTypeSignedInteger:
+ return str(int(self))
+ elif data_type == eStructuredDataTypeFloat:
+ return str(float(self))
+ else:
+ raise TypeError(f"cannot convert {self.type_name(data_type)} to string")
+
+ def __int__(self):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeInteger:
+ return self.GetUnsignedIntegerValue()
+ elif data_type == eStructuredDataTypeSignedInteger:
+ return self.GetSignedIntegerValue()
+ elif data_type == eStructuredDataTypeFloat:
+ return int(float(self))
+ elif data_type == eStructuredDataTypeString:
+ return int(str(self))
+ elif data_type == eStructuredDataTypeBoolean:
+ return int(bool(self))
+ else:
+ raise TypeError(f"cannot convert {self.type_name(data_type)} to int")
+
+ def __float__(self):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeFloat:
+ return self.GetFloatValue()
+ elif data_type == eStructuredDataTypeInteger:
+ return float(int(self))
+ elif data_type == eStructuredDataTypeSignedInteger:
+ return float(int(self))
+ elif data_type == eStructuredDataTypeString:
+ return float(str(self))
+ else:
+ raise TypeError(f"cannot convert {self.type_name(data_type)} to float")
+
+ @staticmethod
+ def type_name(t):
+ if t == eStructuredDataTypeNull:
+ return "null"
+ elif t == eStructuredDataTypeBoolean:
+ return "boolean"
+ elif t == eStructuredDataTypeInteger:
+ return "integer"
+ elif t == eStructuredDataTypeSignedInteger:
+ return "integer"
+ elif t == eStructuredDataTypeFloat:
+ return "float"
+ elif t == eStructuredDataTypeString:
+ return "string"
+ elif t == eStructuredDataTypeArray:
+ return "array"
+ elif t == eStructuredDataTypeDictionary:
+ return "dictionary"
+ elif t == eStructuredDataTypeGeneric:
+ return "generic"
+ elif t == eStructuredDataTypeInvalid:
+ return "invalid"
+ else:
+ raise TypeError(f"unknown structured data type: {t}")
%}
#endif
}
diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
index 99f88d3da794a..6594c3604d26a 100644
--- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
+++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
@@ -51,7 +51,6 @@ def structured_data_api_test(self):
if not "key_float" in s.GetData():
self.fail("FAILED: could not find key_float in description output")
- dict_struct = lldb.SBStructuredData()
dict_struct = example.GetValueForKey("key_dict")
# Tests for dictionary data type
@@ -113,21 +112,26 @@ class MyRandomClass:
self.assertSuccess(example.SetFromJSON("1"))
self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger)
self.assertEqual(example.GetIntegerValue(), 1)
+ self.assertEqual(int(example), 1)
self.assertSuccess(example.SetFromJSON("4.19"))
self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat)
self.assertEqual(example.GetFloatValue(), 4.19)
+ self.assertEqual(float(example), 4.19)
self.assertSuccess(example.SetFromJSON('"Bonjour, 123!"'))
self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString)
self.assertEqual(example.GetStringValue(42), "Bonjour, 123!")
+ self.assertEqual(str(example), "Bonjour, 123!")
self.assertSuccess(example.SetFromJSON("true"))
self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean)
self.assertTrue(example.GetBooleanValue())
+ self.assertTrue(example)
self.assertSuccess(example.SetFromJSON("null"))
self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull)
+ self.assertFalse(example)
example = lldb.SBStructuredData()
example.SetUnsignedIntegerValue(1)
@@ -187,38 +191,35 @@ class MyRandomClass:
self.assertEqual(sb_data, example_arr)
def invalid_struct_test(self, example):
- invalid_struct = lldb.SBStructuredData()
invalid_struct = example.GetValueForKey("invalid_key")
if invalid_struct.IsValid():
self.fail("An invalid object should have been returned")
# Check Type API
- if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid:
+ if invalid_struct.GetType() != lldb.eStructuredDataTypeInvalid:
self.fail("Wrong type returned: " + str(invalid_struct.GetType()))
def dictionary_struct_test(self, example):
# Check API returning a valid SBStructuredData of 'dictionary' type
- dict_struct = lldb.SBStructuredData()
dict_struct = example.GetValueForKey("key_dict")
if not dict_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary:
+ if dict_struct.GetType() != lldb.eStructuredDataTypeDictionary:
self.fail("Wrong type returned: " + str(dict_struct.GetType()))
# Check Size API for 'dictionary' type
- if not dict_struct.GetSize() == 6:
+ if dict_struct.GetSize() != 6:
self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize()))
def string_struct_test(self, dict_struct):
- string_struct = lldb.SBStructuredData()
string_struct = dict_struct.GetValueForKey("key_string")
if not string_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not string_struct.GetType() == lldb.eStructuredDataTypeString:
+ if string_struct.GetType() != lldb.eStructuredDataTypeString:
self.fail("Wrong type returned: " + str(string_struct.GetType()))
# Check API returning 'string' value
@@ -238,18 +239,17 @@ def uint_struct_test(self, dict_struct):
# Check a valid SBStructuredData containing an unsigned integer.
# We intentionally make this larger than what an int64_t can hold but
# still small enough to fit a uint64_t
- uint_struct = lldb.SBStructuredData()
uint_struct = dict_struct.GetValueForKey("key_uint")
if not uint_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger:
+ if uint_struct.GetType() != lldb.eStructuredDataTypeInteger:
self.fail("Wrong type returned: " + str(uint_struct.GetType()))
# Check API returning unsigned integer value
output = uint_struct.GetUnsignedIntegerValue()
- if not output == 0xFFFFFFFF00000000:
+ if output != 0xFFFFFFFF00000000:
self.fail("wrong output: " + str(output))
# Calling wrong API on a SBStructuredData
@@ -262,18 +262,17 @@ def sint_struct_test(self, dict_struct):
# Check a valid SBStructuredData containing an signed integer.
# We intentionally make this smaller than what an uint64_t can hold but
# still small enough to fit a int64_t
- sint_struct = lldb.SBStructuredData()
sint_struct = dict_struct.GetValueForKey("key_sint")
if not sint_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger:
+ if sint_struct.GetType() != lldb.eStructuredDataTypeSignedInteger:
self.fail("Wrong type returned: " + str(sint_struct.GetType()))
# Check API returning signed integer value
output = sint_struct.GetSignedIntegerValue()
- if not output == -42:
+ if output != -42:
self.fail("wrong output: " + str(output))
# Calling wrong API on a SBStructuredData
@@ -283,28 +282,26 @@ def sint_struct_test(self, dict_struct):
self.fail("Valid string " + output + " returned for an integer object")
def double_struct_test(self, dict_struct):
- floating_point_struct = lldb.SBStructuredData()
floating_point_struct = dict_struct.GetValueForKey("key_float")
if not floating_point_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat:
+ if floating_point_struct.GetType() != lldb.eStructuredDataTypeFloat:
self.fail("Wrong type returned: " + str(floating_point_struct.GetType()))
# Check API returning 'double' value
output = floating_point_struct.GetFloatValue()
- if not output == 2.99:
+ if output != 2.99:
self.fail("wrong output: " + str(output))
def bool_struct_test(self, dict_struct):
- bool_struct = lldb.SBStructuredData()
bool_struct = dict_struct.GetValueForKey("key_bool")
if not bool_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean:
+ if bool_struct.GetType() != lldb.eStructuredDataTypeBoolean:
self.fail("Wrong type returned: " + str(bool_struct.GetType()))
# Check API returning 'bool' value
@@ -314,17 +311,16 @@ def bool_struct_test(self, dict_struct):
def array_struct_test(self, dict_struct):
# Check API returning a valid SBStructuredData of 'array' type
- array_struct = lldb.SBStructuredData()
array_struct = dict_struct.GetValueForKey("key_array")
if not array_struct.IsValid():
self.fail("A valid object should have been returned")
# Check Type API
- if not array_struct.GetType() == lldb.eStructuredDataTypeArray:
+ if array_struct.GetType() != lldb.eStructuredDataTypeArray:
self.fail("Wrong type returned: " + str(array_struct.GetType()))
# Check Size API for 'array' type
- if not array_struct.GetSize() == 2:
+ if array_struct.GetSize() != 2:
self.fail("Wrong no of elements returned: " + str(array_struct.GetSize()))
# Check API returning a valid SBStructuredData for different 'array'
@@ -332,17 +328,90 @@ def array_struct_test(self, dict_struct):
string_struct = array_struct.GetItemAtIndex(0)
if not string_struct.IsValid():
self.fail("A valid object should have been returned")
- if not string_struct.GetType() == lldb.eStructuredDataTypeString:
+ if string_struct.GetType() != lldb.eStructuredDataTypeString:
self.fail("Wrong type returned: " + str(string_struct.GetType()))
output = string_struct.GetStringValue(5)
- if not output == "23":
+ if output != "23":
self.fail("wrong output: " + str(output))
string_struct = array_struct.GetItemAtIndex(1)
if not string_struct.IsValid():
self.fail("A valid object should have been returned")
- if not string_struct.GetType() == lldb.eStructuredDataTypeString:
+ if string_struct.GetType() != lldb.eStructuredDataTypeString:
self.fail("Wrong type returned: " + str(string_struct.GetType()))
output = string_struct.GetStringValue(5)
- if not output == "arr":
+ if output != "arr":
self.fail("wrong output: " + str(output))
+
+ def test_round_trip_scalars(self):
+ for original in (0, 11, -1, 0.0, 4.5, -0.25, "", "dirk", True, False):
+ constructor = type(original)
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ round_tripped = constructor(data)
+ self.assertEqual(round_tripped, original)
+
+ def test_round_trip_string(self):
+ # No 0.0, it inherently does not round trip.
+ for original in (0, 11, -1, 4.5, -0.25, "", "dirk"):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(str(data), str(original))
+
+ def test_round_trip_int(self):
+ for original in (0, 11, -1, 0.0, 4.5, -0.25, "0", "11", "-1", True, False):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(int(data), int(original))
+
+ def test_round_trip_float(self):
+ for original in (0, 11, -1, 0.0, 4.5, -0.25, "0.0", "4.5", "-0.25"):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(float(data), float(original))
+
+ def test_round_trip_bool(self):
+ for original in (0, 11, -1, 0.0, 4.5, -0.25, "0.0", "4.5", "-0.25"):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(bool(data), bool(original))
+
+ for original in ([], {}, [1], {1: 1}):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(bool(data), bool(original))
+
+ def test_assert_false(self):
+ self.assertFalse(lldb.SBStructuredData())
+ for original in ("0", "0.0", '""', "[]", "{}"):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(original)
+ self.assertFalse(data)
+
+ def test_iterate_array(self):
+ array = [0, 1, 2]
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(array))
+ for value in data:
+ self.assertEqual(int(value), array.pop(0))
+
+ def test_iterate_dictionary(self):
+ dictionary = {"0": 0, "1": 1, "2": 2}
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(dictionary))
+ for key in data:
+ self.assertEqual(int(key), dictionary[key])
+
+ def test_getitem_array(self):
+ array = [1, 2, 3]
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(array))
+ for i in range(len(array)):
+ self.assertEqual(int(data[i]), array[i])
+
+ def test_getitem_dictionary(self):
+ dictionary = {"one": 1, "two": 2, "three": 3}
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(dictionary))
+ for key in dictionary:
+ self.assertEqual(int(data[key]), dictionary[key])
>From c7994222101add29c6d4fd9b291599a3ebb4b8d2 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 23 Aug 2025 09:34:49 -0700
Subject: [PATCH 2/4] unwrap dynamically when using getitem/iter
---
.../interface/SBStructuredDataExtensions.i | 32 ++++++++++++++++---
.../sbstructureddata/TestStructuredDataAPI.py | 12 +++++--
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/lldb/bindings/interface/SBStructuredDataExtensions.i b/lldb/bindings/interface/SBStructuredDataExtensions.i
index 900dc192df2bb..2a6e5790c965d 100644
--- a/lldb/bindings/interface/SBStructuredDataExtensions.i
+++ b/lldb/bindings/interface/SBStructuredDataExtensions.i
@@ -11,12 +11,15 @@ STRING_EXTENSION_OUTSIDE(SBStructuredData)
'''Iterate over all the elements in a lldb.SBStructuredData object.'''
data_type = self.GetType()
if data_type == eStructuredDataTypeArray:
- return lldb_iter(self, 'GetSize', 'GetItemAtIndex')
+ for i in range(self.GetSize()):
+ yield self.GetItemAtIndex(i).dynamic
+ return
elif data_type == eStructuredDataTypeDictionary:
keys = SBStringList()
self.GetKeys(keys)
return iter(keys)
- raise TypeError(f"cannot iterate {self.type_name(data_type)} type")
+ else:
+ raise TypeError(f"cannot iterate {self.type_name(data_type)} type")
def __getitem__(self, key):
data_type = self.GetType()
@@ -26,12 +29,12 @@ STRING_EXTENSION_OUTSIDE(SBStructuredData)
count = len(self)
if -count <= key < count:
key %= count
- return self.GetItemAtIndex(key)
+ return self.GetItemAtIndex(key).dynamic
raise IndexError("index out of range")
elif data_type == eStructuredDataTypeDictionary:
if not isinstance(key, str):
raise TypeError("subscript key must be a string")
- return self.GetValueForKey(key)
+ return self.GetValueForKey(key).dynamic
else:
raise TypeError(f"cannot subscript {self.type_name(data_type)} type")
@@ -100,6 +103,27 @@ STRING_EXTENSION_OUTSIDE(SBStructuredData)
else:
raise TypeError(f"cannot convert {self.type_name(data_type)} to float")
+ @property
+ def dynamic(self):
+ data_type = self.GetType()
+ if data_type == eStructuredDataTypeNull:
+ return None
+ elif data_type == eStructuredDataTypeBoolean:
+ return self.GetBooleanValue()
+ elif data_type == eStructuredDataTypeInteger:
+ return self.GetUnsignedIntegerValue()
+ elif data_type == eStructuredDataTypeSignedInteger:
+ return self.GetSignedIntegerValue()
+ elif data_type == eStructuredDataTypeFloat:
+ return self.GetFloatValue()
+ elif data_type == eStructuredDataTypeString:
+ size = len(self) or 1023
+ return self.GetStringValue(size + 1)
+ elif data_type == eStructuredDataTypeGeneric:
+ return self.GetGenericValue()
+ else:
+ return self
+
@staticmethod
def type_name(t):
if t == eStructuredDataTypeNull:
diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
index 6594c3604d26a..f3add778ef554 100644
--- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
+++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
@@ -351,6 +351,12 @@ def test_round_trip_scalars(self):
round_tripped = constructor(data)
self.assertEqual(round_tripped, original)
+ def test_dynamic(self):
+ for original in (0, 11, -1, 0.0, 4.5, -0.25, "", "dirk", True, False):
+ data = lldb.SBStructuredData()
+ data.SetFromJSON(json.dumps(original))
+ self.assertEqual(data.dynamic, original)
+
def test_round_trip_string(self):
# No 0.0, it inherently does not round trip.
for original in (0, 11, -1, 4.5, -0.25, "", "dirk"):
@@ -393,7 +399,7 @@ def test_iterate_array(self):
data = lldb.SBStructuredData()
data.SetFromJSON(json.dumps(array))
for value in data:
- self.assertEqual(int(value), array.pop(0))
+ self.assertEqual(value, array.pop(0))
def test_iterate_dictionary(self):
dictionary = {"0": 0, "1": 1, "2": 2}
@@ -407,11 +413,11 @@ def test_getitem_array(self):
data = lldb.SBStructuredData()
data.SetFromJSON(json.dumps(array))
for i in range(len(array)):
- self.assertEqual(int(data[i]), array[i])
+ self.assertEqual(data[i], array[i])
def test_getitem_dictionary(self):
dictionary = {"one": 1, "two": 2, "three": 3}
data = lldb.SBStructuredData()
data.SetFromJSON(json.dumps(dictionary))
for key in dictionary:
- self.assertEqual(int(data[key]), dictionary[key])
+ self.assertEqual(data[key], dictionary[key])
>From a68276bf196c591dc718d89bc618b5c203952e59 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 23 Aug 2025 10:37:00 -0700
Subject: [PATCH 3/4] tweak test_iterate_dictionary
---
.../API/python_api/sbstructureddata/TestStructuredDataAPI.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
index f3add778ef554..d3ec4dcc4f6ca 100644
--- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
+++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py
@@ -403,10 +403,12 @@ def test_iterate_array(self):
def test_iterate_dictionary(self):
dictionary = {"0": 0, "1": 1, "2": 2}
+ keys = set(dictionary.keys())
data = lldb.SBStructuredData()
data.SetFromJSON(json.dumps(dictionary))
for key in data:
- self.assertEqual(int(key), dictionary[key])
+ self.assertIn(key, keys)
+ keys.remove(key)
def test_getitem_array(self):
array = [1, 2, 3]
>From d75c5ffa8413f228ee6b5d9b2503a48f3ddc4d3f Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 23 Aug 2025 11:11:54 -0700
Subject: [PATCH 4/4] simplify str/bool/int/float
---
.../interface/SBStructuredDataExtensions.i | 76 ++++++++-----------
1 file changed, 31 insertions(+), 45 deletions(-)
diff --git a/lldb/bindings/interface/SBStructuredDataExtensions.i b/lldb/bindings/interface/SBStructuredDataExtensions.i
index 2a6e5790c965d..cf3b240df2456 100644
--- a/lldb/bindings/interface/SBStructuredDataExtensions.i
+++ b/lldb/bindings/interface/SBStructuredDataExtensions.i
@@ -40,66 +40,52 @@ STRING_EXTENSION_OUTSIDE(SBStructuredData)
def __bool__(self):
data_type = self.GetType()
- if data_type == eStructuredDataTypeBoolean:
- return self.GetBooleanValue()
- elif data_type == eStructuredDataTypeInteger:
- return bool(int(self))
- elif data_type == eStructuredDataTypeSignedInteger:
- return bool(int(self))
- elif data_type == eStructuredDataTypeFloat:
- return bool(float(self))
- elif data_type == eStructuredDataTypeString:
- return bool(str(self))
- elif data_type == eStructuredDataTypeArray:
- return bool(len(self))
- elif data_type == eStructuredDataTypeDictionary:
- return bool(len(self))
- elif data_type == eStructuredDataTypeNull:
- return False
- elif data_type == eStructuredDataTypeInvalid:
+ if data_type == eStructuredDataTypeInvalid:
return False
+ elif data_type in (
+ eStructuredDataTypeArray,
+ eStructuredDataTypeDictionary,
+ ):
+ return self.GetSize() != 0
+ elif data_type != eStructuredDataTypeGeneric:
+ return bool(self.dynamic)
else:
- raise TypeError(f"cannot convert {self.type_name(data_type)} to bool")
+ raise TypeError("cannot convert generic to bool")
def __str__(self):
data_type = self.GetType()
- if data_type == eStructuredDataTypeString:
- size = len(self) or 1023
- return self.GetStringValue(size + 1)
- elif data_type == eStructuredDataTypeInteger:
- return str(int(self))
- elif data_type == eStructuredDataTypeSignedInteger:
- return str(int(self))
- elif data_type == eStructuredDataTypeFloat:
- return str(float(self))
+ if data_type in (
+ eStructuredDataTypeString,
+ eStructuredDataTypeInteger,
+ eStructuredDataTypeSignedInteger,
+ eStructuredDataTypeFloat,
+ ):
+ return str(self.dynamic)
else:
raise TypeError(f"cannot convert {self.type_name(data_type)} to string")
def __int__(self):
data_type = self.GetType()
- if data_type == eStructuredDataTypeInteger:
- return self.GetUnsignedIntegerValue()
- elif data_type == eStructuredDataTypeSignedInteger:
- return self.GetSignedIntegerValue()
- elif data_type == eStructuredDataTypeFloat:
- return int(float(self))
- elif data_type == eStructuredDataTypeString:
- return int(str(self))
- elif data_type == eStructuredDataTypeBoolean:
- return int(bool(self))
+ if data_type in (
+ eStructuredDataTypeInteger,
+ eStructuredDataTypeSignedInteger,
+ eStructuredDataTypeFloat,
+ eStructuredDataTypeString,
+ eStructuredDataTypeBoolean,
+ ):
+ return int(self.dynamic)
else:
raise TypeError(f"cannot convert {self.type_name(data_type)} to int")
def __float__(self):
data_type = self.GetType()
- if data_type == eStructuredDataTypeFloat:
- return self.GetFloatValue()
- elif data_type == eStructuredDataTypeInteger:
- return float(int(self))
- elif data_type == eStructuredDataTypeSignedInteger:
- return float(int(self))
- elif data_type == eStructuredDataTypeString:
- return float(str(self))
+ if data_type in (
+ eStructuredDataTypeFloat,
+ eStructuredDataTypeInteger,
+ eStructuredDataTypeSignedInteger,
+ eStructuredDataTypeString,
+ ):
+ return float(self.dynamic)
else:
raise TypeError(f"cannot convert {self.type_name(data_type)} to float")
More information about the lldb-commits
mailing list