Skip to content

Commit 20fc2d5

Browse files
[libclang/python] Add some bindings to the Cursor interface (#132377)
Make Cursor hashable Add `Cursor.has_attr()` Add `Cursor.specialized_template` This covers the Cursor interface changes added by #120590 --------- Co-authored-by: Mathias Stearn <[email protected]>
1 parent 14d2561 commit 20fc2d5

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

clang/bindings/python/clang/cindex.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,9 @@ def __eq__(self, other):
15611561
def __ne__(self, other):
15621562
return not self.__eq__(other)
15631563

1564+
def __hash__(self) -> int:
1565+
return self.hash
1566+
15641567
def is_definition(self):
15651568
"""
15661569
Returns true if the declaration pointed at by the cursor is also a
@@ -2035,6 +2038,13 @@ def lexical_parent(self):
20352038

20362039
return self._lexical_parent
20372040

2041+
@property
2042+
def specialized_template(self) -> Cursor | None:
2043+
"""Return the primary template that this cursor is a specialization of, if any."""
2044+
return Cursor.from_cursor_result(
2045+
conf.lib.clang_getSpecializedCursorTemplate(self), self
2046+
)
2047+
20382048
@property
20392049
def translation_unit(self):
20402050
"""Returns the TranslationUnit to which this Cursor belongs."""
@@ -2178,6 +2188,12 @@ def get_bitfield_width(self):
21782188
"""
21792189
return conf.lib.clang_getFieldDeclBitWidth(self) # type: ignore [no-any-return]
21802190

2191+
def has_attrs(self) -> bool:
2192+
"""
2193+
Determine whether the given cursor has any attributes.
2194+
"""
2195+
return bool(conf.lib.clang_Cursor_hasAttrs(self))
2196+
21812197
@staticmethod
21822198
def from_result(res, arg):
21832199
assert isinstance(res, Cursor)
@@ -3932,6 +3948,7 @@ def set_property(self, property, value):
39323948
("clang_getCursorType", [Cursor], Type),
39333949
("clang_getCursorUSR", [Cursor], _CXString),
39343950
("clang_Cursor_getMangling", [Cursor], _CXString),
3951+
("clang_Cursor_hasAttrs", [Cursor], c_uint),
39353952
# ("clang_getCXTUResourceUsage",
39363953
# [TranslationUnit],
39373954
# CXTUResourceUsage),

clang/bindings/python/tests/cindex/test_cursor.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
AvailabilityKind,
55
BinaryOperator,
66
Config,
7+
Cursor,
78
CursorKind,
89
PrintingPolicy,
910
PrintingPolicyProperty,
@@ -995,3 +996,42 @@ def test_pretty_print(self):
995996
pp.set_property(PrintingPolicyProperty.Bool, False)
996997
self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), False)
997998
self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n")
999+
1000+
def test_hash(self):
1001+
def accumulate_cursors(cursor: Cursor, all_cursors: list):
1002+
all_cursors.append(cursor)
1003+
for child in cursor.get_children():
1004+
all_cursors = accumulate_cursors(child, all_cursors)
1005+
return all_cursors
1006+
1007+
tu = get_tu(children_test)
1008+
all_cursors = accumulate_cursors(tu.cursor, [])
1009+
cursor_hashes = set()
1010+
for cursor in all_cursors:
1011+
self.assertNotIn(hash(cursor), cursor_hashes)
1012+
cursor_hashes.add(hash(cursor))
1013+
1014+
def test_has_attrs(self):
1015+
tu = get_tu(
1016+
"""
1017+
struct A;
1018+
struct A final {};
1019+
1020+
struct B;
1021+
struct B {};
1022+
""",
1023+
lang="cpp",
1024+
)
1025+
A = get_cursor(tu, "A")
1026+
B = get_cursor(tu, "B")
1027+
self.assertTrue(A.get_definition().has_attrs())
1028+
self.assertFalse(B.get_definition().has_attrs())
1029+
1030+
def test_specialized_template(self):
1031+
tu = get_tu(template_arg_test, lang="cpp")
1032+
foos = get_cursors(tu, "foo")
1033+
prime_foo = foos[1].specialized_template
1034+
1035+
self.assertNotEqual(foos[0], foos[1])
1036+
self.assertEqual(foos[0], prime_foo)
1037+
self.assertIsNone(tu.cursor.specialized_template)

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,12 @@ Sanitizers
525525

526526
Python Binding Changes
527527
----------------------
528+
- Made ``Cursor`` hashable.
529+
- Added ``Cursor.has_attrs``, a binding for ``clang_Cursor_hasAttrs``, to check
530+
whether a cursor has any attributes.
531+
- Added ``Cursor.specialized_template``, a binding for
532+
``clang_getSpecializedCursorTemplate``, to retrieve the primary template that
533+
the cursor is a specialization of.
528534
- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
529535
allows visiting the methods of a class.
530536

0 commit comments

Comments
 (0)