Skip to content

Conversation

DeinAlptraum
Copy link
Contributor

Since #138103 , the Cursor class throws an error when any of its methods is called on a null cursor. Simultaneously, we adapted all methods to return None instead of a null cursor, so users should not encounter these. We have overlooked one way to end up with null cursors, namely the Token.cursor property, which may return null cursors under some circumstances.

Fixes #163180

@DeinAlptraum DeinAlptraum requested a review from Endilll October 13, 2025 11:52
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:as-a-library libclang and C++ API labels Oct 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 13, 2025

@llvm/pr-subscribers-clang

Author: Jannick Kremer (DeinAlptraum)

Changes

Since #138103 , the Cursor class throws an error when any of its methods is called on a null cursor. Simultaneously, we adapted all methods to return None instead of a null cursor, so users should not encounter these. We have overlooked one way to end up with null cursors, namely the Token.cursor property, which may return null cursors under some circumstances.

Fixes #163180


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

3 Files Affected:

  • (modified) clang/bindings/python/clang/cindex.py (+2)
  • (modified) clang/bindings/python/tests/cindex/test_tokens.py (+8)
  • (modified) clang/docs/ReleaseNotes.rst (+1)
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 80140d2787608..da97bd375608c 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3939,6 +3939,8 @@ def cursor(self):
         cursor._tu = self._tu
 
         conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor))
+        if cursor.is_null():
+            return None
 
         return cursor
 
diff --git a/clang/bindings/python/tests/cindex/test_tokens.py b/clang/bindings/python/tests/cindex/test_tokens.py
index b6c1fc8b83600..d1982164deca8 100644
--- a/clang/bindings/python/tests/cindex/test_tokens.py
+++ b/clang/bindings/python/tests/cindex/test_tokens.py
@@ -53,3 +53,11 @@ def test_token_extent(self):
 
         self.assertEqual(extent.start.offset, 4)
         self.assertEqual(extent.end.offset, 7)
+
+    def test_null_cursor(self):
+        """Ensure that null cursors are converted to None by get_tokens"""
+        tu = get_tu("int i = 5;")
+        tokens = list(tu.get_tokens(extent=tu.cursor.extent))
+        for token in tokens:
+            print(token.spelling, token.kind, token.extent)
+        self.assertEqual(tokens[-1].cursor, None)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 65b086caf3652..b32009309c1cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -136,6 +136,7 @@ Clang Frontend Potentially Breaking Changes
 
 Clang Python Bindings Potentially Breaking Changes
 --------------------------------------------------
+- Return ``None`` instead of null cursors from ``Token.cursor``
 - TypeKind ``ELABORATED`` is not used anymore, per clang AST changes removing
   ElaboratedTypes. The value becomes unused, and all the existing users should
   expect the former underlying type to be reported instead.

@DeinAlptraum DeinAlptraum enabled auto-merge (squash) October 13, 2025 13:33
@DeinAlptraum DeinAlptraum merged commit 38a5282 into llvm:main Oct 13, 2025
12 of 13 checks passed
@DeinAlptraum DeinAlptraum deleted the fix-nullcursors branch October 13, 2025 13:58
@Endilll
Copy link
Contributor

Endilll commented Oct 13, 2025

I talked to Aaron about backporting, and this should be fine to backport.

@DeinAlptraum
Copy link
Contributor Author

Okay, so I get it into the 21.x branch by calling the cherry-pick command in a comment here?

akadutta pushed a commit to akadutta/llvm-project that referenced this pull request Oct 14, 2025
…or (llvm#163183)

Since llvm#138103 , the `Cursor`
class throws an error when any of its methods is called on a null
cursor. Simultaneously, we adapted all methods to return `None` instead
of a null cursor, so users should not encounter these. We have
overlooked one way to end up with null cursors, namely the
`Token.cursor` property, which may return null cursors under some
circumstances.

Fixes llvm#163180
@DeinAlptraum
Copy link
Contributor Author

/cherry-pick 38a5282

@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2025

/cherry-pick 38a5282

Error: Command failed due to missing milestone.

@Endilll
Copy link
Contributor

Endilll commented Oct 17, 2025

/cherry-pick 38a5282

@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2025

Failed to cherry-pick: 38a5282

https://github.com/llvm/llvm-project/actions/runs/18593736643

Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request

DeinAlptraum added a commit to DeinAlptraum/llvm-project that referenced this pull request Oct 17, 2025
…or (llvm#163183)

Since llvm#138103 , the `Cursor`
class throws an error when any of its methods is called on a null
cursor. Simultaneously, we adapted all methods to return `None` instead
of a null cursor, so users should not encounter these. We have
overlooked one way to end up with null cursors, namely the
`Token.cursor` property, which may return null cursors under some
circumstances.

Fixes llvm#163180
@DeinAlptraum
Copy link
Contributor Author

Fixed the release note conflcit manually and opened a PR at #163961

@c-rhodes c-rhodes moved this from Needs Triage to Done in LLVM Release Status Oct 20, 2025
c-rhodes pushed a commit to DeinAlptraum/llvm-project that referenced this pull request Oct 20, 2025
…or (llvm#163183)

Since llvm#138103 , the `Cursor`
class throws an error when any of its methods is called on a null
cursor. Simultaneously, we adapted all methods to return `None` instead
of a null cursor, so users should not encounter these. We have
overlooked one way to end up with null cursors, namely the
`Token.cursor` property, which may return null cursors under some
circumstances.

Fixes llvm#163180
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 release:cherry-pick-failed

Projects

Development

Successfully merging this pull request may close these issues.

libclang Python bindings return null Cursors via Token.cursor property

3 participants