[clang] [libclang/python] Deprecate CodeCompletionResults.results (PR #177764)

Jannick Kremer via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 31 07:59:28 PST 2026


https://github.com/DeinAlptraum updated https://github.com/llvm/llvm-project/pull/177764

>From b57527dbe70fcb4248914001c699da4acbdd685e Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Sat, 24 Jan 2026 22:36:47 +0900
Subject: [PATCH 1/7] Deprecate CodeCompletionResults.results

---
 clang/bindings/python/clang/cindex.py          | 18 ++++++++++++++++++
 .../tests/cindex/test_code_completion.py       |  2 +-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 428ac694720fa..a0b7c475a5fc5 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3283,8 +3283,26 @@ def from_param(self) -> _Pointer[CCRStructure]:
     def __del__(self) -> None:
         conf.lib.clang_disposeCodeCompleteResults(self)
 
+    def __len__(self) -> int:
+        return self.ptr.contents.numResults
+
+    def __getitem__(self, key: int) -> CodeCompletionResult:
+        if len(self) <= key:
+            raise IndexError
+
+        return self.ptr.contents.results[key]
+
     @property
     def results(self) -> CCRStructure:
+        warnings.warn(
+            "Access to 'CodeCompletionResult's through "
+            "'CodeCompletionResults.results' will be removed in a future release."
+            "Existing uses of 'CodeCompletionResults.results' should be changed "
+            "to directly use 'CodeCompletionResults': it nows supports '__len__' "
+            "and '__getitem__', so it can be used the same as "
+            "'CodeCompletionResults.results'.",
+            DeprecationWarning,
+        )
         return self.ptr.contents
 
     @property
diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py
index c376b0e5cce40..c0a6a7069344b 100644
--- a/clang/bindings/python/tests/cindex/test_code_completion.py
+++ b/clang/bindings/python/tests/cindex/test_code_completion.py
@@ -14,7 +14,7 @@ def check_completion_results(self, cr, expected):
         self.assertIsNotNone(cr)
         self.assertEqual(len(cr.diagnostics), 0)
 
-        completions = [str(c) for c in cr.results]
+        completions = [str(c) for c in cr]
 
         for c in expected:
             self.assertIn(c, completions)

>From 8e1bbf8ab43f700d64a95bdf6299bfea1053bdab Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Thu, 29 Jan 2026 22:31:13 +0900
Subject: [PATCH 2/7] Add test for old variant

---
 .../tests/cindex/test_code_completion.py      | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py
index c0a6a7069344b..5194239489891 100644
--- a/clang/bindings/python/tests/cindex/test_code_completion.py
+++ b/clang/bindings/python/tests/cindex/test_code_completion.py
@@ -1,7 +1,9 @@
 from clang.cindex import (
     AvailabilityKind,
+    CompletionChunk,
     CompletionChunkKind,
     CompletionString,
+    SPELLING_CACHE,
     TranslationUnit,
 )
 
@@ -19,6 +21,11 @@ def check_completion_results(self, cr, expected):
         for c in expected:
             self.assertIn(c, completions)
 
+        completions_deprecated = [str(c) for c in cr.results]
+
+        for c in expected:
+            self.assertIn(c, completions_deprecated)
+
     def test_code_complete(self):
         files = [
             (
@@ -214,3 +221,23 @@ def test_completion_chunk_kind_compatibility(self):
         for value, old_str in value_to_old_str.items():
             new_kind = CompletionChunkKind.from_id(value)
             self.assertEqual(old_str, str(new_kind))
+
+    def test_spelling_cache_missing_attribute(self):
+        # Test that accessing missing attributes on SpellingCacheAlias raises
+        # during the transitionary period
+        with self.assertRaises(AttributeError, msg=SPELLING_CACHE.deprecation_message):
+            SPELLING_CACHE.keys()
+
+    def test_spelling_cache_alias(self):
+        kind_keys = list(CompletionChunk.SPELLING_CACHE)
+        self.assertEqual(len(kind_keys), 13)
+        for kind_key in kind_keys:
+            self.assertEqual(
+                SPELLING_CACHE[kind_key.value], CompletionChunk.SPELLING_CACHE[kind_key]
+            )
+
+    def test_spelling_cache_missing_attribute(self):
+        # Test that accessing missing attributes on SpellingCacheAlias raises
+        # during the transitionary period
+        with self.assertRaises(AttributeError, msg=SPELLING_CACHE.deprecation_message):
+            SPELLING_CACHE.keys()

>From e587e3f147561d80cca42d8d984ffa5a0af780eb Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Thu, 29 Jan 2026 22:36:22 +0900
Subject: [PATCH 3/7] Remove unrelated tests

---
 .../tests/cindex/test_code_completion.py      | 20 -------------------
 1 file changed, 20 deletions(-)

diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py
index 5194239489891..a8f4555936d75 100644
--- a/clang/bindings/python/tests/cindex/test_code_completion.py
+++ b/clang/bindings/python/tests/cindex/test_code_completion.py
@@ -221,23 +221,3 @@ def test_completion_chunk_kind_compatibility(self):
         for value, old_str in value_to_old_str.items():
             new_kind = CompletionChunkKind.from_id(value)
             self.assertEqual(old_str, str(new_kind))
-
-    def test_spelling_cache_missing_attribute(self):
-        # Test that accessing missing attributes on SpellingCacheAlias raises
-        # during the transitionary period
-        with self.assertRaises(AttributeError, msg=SPELLING_CACHE.deprecation_message):
-            SPELLING_CACHE.keys()
-
-    def test_spelling_cache_alias(self):
-        kind_keys = list(CompletionChunk.SPELLING_CACHE)
-        self.assertEqual(len(kind_keys), 13)
-        for kind_key in kind_keys:
-            self.assertEqual(
-                SPELLING_CACHE[kind_key.value], CompletionChunk.SPELLING_CACHE[kind_key]
-            )
-
-    def test_spelling_cache_missing_attribute(self):
-        # Test that accessing missing attributes on SpellingCacheAlias raises
-        # during the transitionary period
-        with self.assertRaises(AttributeError, msg=SPELLING_CACHE.deprecation_message):
-            SPELLING_CACHE.keys()

>From de1f55a1432af77d574e1c5190696407ada87cb9 Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Thu, 29 Jan 2026 22:41:36 +0900
Subject: [PATCH 4/7] Fix deprecation warning formatting

---
 clang/bindings/python/clang/cindex.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 38e0e9d9c2426..e94f70de65d6a 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3358,7 +3358,7 @@ def __getitem__(self, key: int) -> CodeCompletionResult:
     def results(self) -> CCRStructure:
         warnings.warn(
             "Access to 'CodeCompletionResult's through "
-            "'CodeCompletionResults.results' will be removed in a future release."
+            "'CodeCompletionResults.results' will be removed in a future release. "
             "Existing uses of 'CodeCompletionResults.results' should be changed "
             "to directly use 'CodeCompletionResults': it nows supports '__len__' "
             "and '__getitem__', so it can be used the same as "

>From caf56b2c7bac49bc30de3d5a5e332a8e12f5790e Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Thu, 29 Jan 2026 22:44:37 +0900
Subject: [PATCH 5/7] Add release note

---
 clang/docs/ReleaseNotes.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 423ee9f66a6e3..3099db80feb13 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -363,6 +363,11 @@ Python Binding Changes
 
   Affected methods: ``isKindOptional``, ``isKindTypedText``, ``isKindPlaceHolder``,
   ``isKindInformative`` and ``isKindResultType``.
+- Add a deprecation warning to ``CodeCompletionResults.results``.
+  This property will be removed in a future release. Existing uses of
+  ``CodeCompletionResults.results`` should be changed to directly use
+  ``CodeCompletionResults``: it nows supports ``__len__`` and ``__getitem__``,
+  so it can be used the same as ``CodeCompletionResults.results``.
 
 OpenMP Support
 --------------

>From 9d0862027bd2dc8b8da633d0aca4a18e8b592878 Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Sat, 31 Jan 2026 11:05:15 +0900
Subject: [PATCH 6/7] Add deprecation warning catching for direct access to
 CCRs

---
 .../bindings/python/tests/cindex/test_code_completion.py  | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py
index 80d1fa6e7a5f2..d969bb2fa0e6c 100644
--- a/clang/bindings/python/tests/cindex/test_code_completion.py
+++ b/clang/bindings/python/tests/cindex/test_code_completion.py
@@ -17,14 +17,18 @@ def check_completion_results(self, cr, expected):
         self.assertIsNotNone(cr)
         self.assertEqual(len(cr.diagnostics), 0)
 
-        completions = [str(c) for c in cr]
+        with warnings.catch_warnings(record=True) as log:
+            completions = [str(c) for c in cr]
+            self.assertEqual(len(log), 2)
+            for warning in log:
+                self.assertIsInstance(warning.message, DeprecationWarning)
 
         for c in expected:
             self.assertIn(c, completions)
 
         with warnings.catch_warnings(record=True) as log:
             completions_deprecated = [str(c) for c in cr.results]
-            self.assertEqual(len(log), 2)
+            self.assertEqual(len(log), 3)
             for warning in log:
                 self.assertIsInstance(warning.message, DeprecationWarning)
 

>From 436c279d6047889cabc28a2734ffc72ac0dbfa95 Mon Sep 17 00:00:00 2001
From: Jannick Kremer <jannick.kremer at mailbox.org>
Date: Sun, 1 Feb 2026 00:59:03 +0900
Subject: [PATCH 7/7] Adapt deprecation message and release note

---
 clang/bindings/python/clang/cindex.py | 4 ++--
 clang/docs/ReleaseNotes.rst           | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index e94f70de65d6a..ec077d4154187 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3357,8 +3357,8 @@ def __getitem__(self, key: int) -> CodeCompletionResult:
     @property
     def results(self) -> CCRStructure:
         warnings.warn(
-            "Access to 'CodeCompletionResult's through "
-            "'CodeCompletionResults.results' will be removed in a future release. "
+            "'CodeCompletionResults.results' will become an implementation detail "
+            "with changed behavior in a future release and should not be used directly. "
             "Existing uses of 'CodeCompletionResults.results' should be changed "
             "to directly use 'CodeCompletionResults': it nows supports '__len__' "
             "and '__getitem__', so it can be used the same as "
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 55ad3b92fa537..7badcd04909d0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -362,7 +362,8 @@ Python Binding Changes
   Affected methods: ``isKindOptional``, ``isKindTypedText``, ``isKindPlaceHolder``,
   ``isKindInformative`` and ``isKindResultType``.
 - Add a deprecation warning to ``CodeCompletionResults.results``.
-  This property will be removed in a future release. Existing uses of
+  This property will become an implementation detail with changed behavior in a 
+  future release and should not be used directly.. Existing uses of 
   ``CodeCompletionResults.results`` should be changed to directly use
   ``CodeCompletionResults``: it nows supports ``__len__`` and ``__getitem__``,
   so it can be used the same as ``CodeCompletionResults.results``.



More information about the cfe-commits mailing list