Skip to content

[libclang/python] Add Cursor.from_translation_unit #140496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented May 19, 2025

This should complete the list of things Cursor can be made from.

@Endilll Endilll requested a review from DeinAlptraum May 19, 2025 06:22
@Endilll Endilll added the clang:as-a-library libclang and C++ API label May 19, 2025
@llvmbot llvmbot added the clang Clang issues not falling into any other category label May 19, 2025
@llvmbot
Copy link
Member

llvmbot commented May 19, 2025

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

Changes

This should complete the list of things Cursor can be made from.


Full diff: https://github.com/llvm/llvm-project/pull/140496.diff

3 Files Affected:

  • (modified) clang/bindings/python/clang/cindex.py (+4)
  • (modified) clang/bindings/python/tests/cindex/test_cursor.py (+6)
  • (modified) clang/docs/ReleaseNotes.rst (+1)
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index f65bcad780a70..615b70d5afb0f 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1595,6 +1595,10 @@ class Cursor(Structure):
     def from_location(tu: TranslationUnit, location: SourceLocation) -> Cursor | None:
         return Cursor.from_result(conf.lib.clang_getCursor(tu, location), tu)
 
+    @staticmethod
+    def from_translation_unit(tu: TranslationUnit) -> Cursor | None:
+        return Cursor.from_result(conf.lib.clang_getTranslationUnitCursor(tu), tu)
+
     # This function is not null-guarded because it is used in cursor_null_guard itself
     def __eq__(self, other: object) -> bool:
         if not isinstance(other, Cursor):
diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py
index eb0d1d50601a6..aeb387f7a6f62 100644
--- a/clang/bindings/python/tests/cindex/test_cursor.py
+++ b/clang/bindings/python/tests/cindex/test_cursor.py
@@ -1064,3 +1064,9 @@ def test_null_cursor(self):
             nc.is_definition()
         with self.assertRaises(Exception):
             nc.spelling
+
+    def test_cursor_from_tu(self):
+        tu = get_tu("int a = 0;")
+        cursor = Cursor.from_translation_unit(tu)
+        reference_cursor = tu.cursor
+        self.assertEqual(cursor, reference_cursor)        
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4a3c1bee82831..8676c5a5e2cd5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -959,6 +959,7 @@ Sanitizers
 Python Binding Changes
 ----------------------
 - Made ``Cursor`` hashable.
+- Added ``Cursor.from_translation_unit``, mirroring ``TranslationUnit.cursor``.
 - Added ``Cursor.has_attrs``, a binding for ``clang_Cursor_hasAttrs``, to check
   whether a cursor has any attributes.
 - Added ``Cursor.specialized_template``, a binding for

Copy link

⚠️ Python code formatter, darker found issues in your code. ⚠️

You can test this locally with the following command:
darker --check --diff -r HEAD~1...HEAD clang/bindings/python/clang/cindex.py clang/bindings/python/tests/cindex/test_cursor.py
View the diff from darker here.
--- tests/cindex/test_cursor.py	2025-05-19 06:20:55.000000 +0000
+++ tests/cindex/test_cursor.py	2025-05-19 06:25:20.022200 +0000
@@ -1067,6 +1067,6 @@
 
     def test_cursor_from_tu(self):
         tu = get_tu("int a = 0;")
         cursor = Cursor.from_translation_unit(tu)
         reference_cursor = tu.cursor
-        self.assertEqual(cursor, reference_cursor)        
+        self.assertEqual(cursor, reference_cursor)

Copy link
Contributor

@DeinAlptraum DeinAlptraum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but are you sure there is a need for this API? This just seems like a slighly less convenient version of TranslationUnit.cursor.

This should complete the list of things Cursor can be made from.

There is also a cursor property on Tokens

@Endilll
Copy link
Contributor Author

Endilll commented May 19, 2025

Hmm, so the reason we have Cursor.from_source_location is that SourceLocation doesn't hold a reference to TU. Yeah, I guess we don't need this.

@Endilll Endilll closed this May 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:as-a-library libclang and C++ API clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants