Author: Jannick Kremer Date: 2026-01-25T19:58:03+09:00 New Revision: 21fdd49c24362087d6b6d6dfaa4a7cd922b6500c
URL: https://github.com/llvm/llvm-project/commit/21fdd49c24362087d6b6d6dfaa4a7cd922b6500c DIFF: https://github.com/llvm/llvm-project/commit/21fdd49c24362087d6b6d6dfaa4a7cd922b6500c.diff LOG: [libclang/python] Move SPELLING_CACHE into CodeCompletion (#177586) This adresses point 2 from https://github.com/llvm/llvm-project/issues/156680. Also add a dummy object that serves as an alias to `SPELLING_CACHE`, used to replicate the old behavior and throw a `DeprecationWarning`. Added: Modified: clang/bindings/python/clang/cindex.py clang/bindings/python/tests/cindex/test_code_completion.py clang/docs/ReleaseNotes.rst Removed: ################################################################################ diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 428ac694720fa..6d667c36ef9a4 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -3073,36 +3073,59 @@ class _CXUnsavedFile(Structure): _fields_ = [("name", c_char_p), ("contents", c_char_p), ("length", c_ulong)] -# Functions calls through the python interface are rather slow. Fortunately, -# for most symbols, we do not need to perform a function call. Their spelling -# never changes and is consequently provided by this spelling cache. -SPELLING_CACHE = { - # 0: CompletionChunk.Kind("Optional"), - # 1: CompletionChunk.Kind("TypedText"), - # 2: CompletionChunk.Kind("Text"), - # 3: CompletionChunk.Kind("Placeholder"), - # 4: CompletionChunk.Kind("Informative"), - # 5 : CompletionChunk.Kind("CurrentParameter"), - 6: "(", # CompletionChunk.Kind("LeftParen"), - 7: ")", # CompletionChunk.Kind("RightParen"), - 8: "[", # CompletionChunk.Kind("LeftBracket"), - 9: "]", # CompletionChunk.Kind("RightBracket"), - 10: "{", # CompletionChunk.Kind("LeftBrace"), - 11: "}", # CompletionChunk.Kind("RightBrace"), - 12: "<", # CompletionChunk.Kind("LeftAngle"), - 13: ">", # CompletionChunk.Kind("RightAngle"), - 14: ", ", # CompletionChunk.Kind("Comma"), - # 15: CompletionChunk.Kind("ResultType"), - 16: ":", # CompletionChunk.Kind("Colon"), - 17: ";", # CompletionChunk.Kind("SemiColon"), - 18: "=", # CompletionChunk.Kind("Equal"), - 19: " ", # CompletionChunk.Kind("HorizontalSpace"), - # 20: CompletionChunk.Kind("VerticalSpace") -} +class CompletionChunk: + class SpellingCacheAlias: + """ + A temporary utility that acts as an alias to CompletionChunk.SPELLING_CACHE. + This will be removed without deprecation warning in a future release. + Please do not use it directly! + """ + deprecation_message = ( + "'SPELLING_CACHE' has been moved into the scope of 'CompletionChunk' " + "and adapted to use 'CompletionChunkKind's as keys instead of their " + "enum values. Please adapt all uses of 'SPELLING_CACHE' to use " + "'CompletionChunk.SPELLING_CACHE' instead. The old 'SPELLING_CACHE' " + "will be removed in a future release." + ) -class CompletionChunk: - __kind_id: int + def __getattr__(self, _): + raise AttributeError(self.deprecation_message) + + def __getitem__(self, value: int): + warnings.warn(self.deprecation_message, DeprecationWarning) + return CompletionChunk.SPELLING_CACHE[CompletionChunkKind.from_id(value)] + + def __contains__(self, value: int): + warnings.warn(self.deprecation_message, DeprecationWarning) + return CompletionChunkKind.from_id(value) in CompletionChunk.SPELLING_CACHE + + # Functions calls through the python interface are rather slow. Fortunately, + # for most symbols, we do not need to perform a function call. Their spelling + # never changes and is consequently provided by this spelling cache. + SPELLING_CACHE = { + # 0: CompletionChunkKind.OPTIONAL + # 1: CompletionChunkKind.TYPED_TEXT + # 2: CompletionChunkKind.TEXT + # 3: CompletionChunkKind.PLACEHOLDER + # 4: CompletionChunkKind.INFORMATIVE + # 5: CompletionChunkKind.CURRENT_PARAMETER + CompletionChunkKind.LEFT_PAREN: "(", # 6 + CompletionChunkKind.RIGHT_PAREN: ")", # 7 + CompletionChunkKind.LEFT_BRACKET: "[", # 8 + CompletionChunkKind.RIGHT_BRACKET: "]", # 9 + CompletionChunkKind.LEFT_BRACE: "{", # 10 + CompletionChunkKind.RIGHT_BRACE: "}", # 11 + CompletionChunkKind.LEFT_ANGLE: "<", # 12 + CompletionChunkKind.RIGHT_ANGLE: ">", # 13 + CompletionChunkKind.COMMA: ", ", # 14 + # 15: CompletionChunkKind.RESULT_TYPE + CompletionChunkKind.COLON: ":", # 16 + CompletionChunkKind.SEMI_COLON: ";", # 17 + CompletionChunkKind.EQUAL: "=", # 18 + CompletionChunkKind.HORIZONTAL_SPACE: " ", # 19 + # 20: CompletionChunkKind.VERTICAL_SPACE + } def __init__(self, completionString: CObjP, key: int): self.cs = completionString @@ -3113,9 +3136,9 @@ def __repr__(self) -> str: @CachedProperty def spelling(self) -> str: - kind_id = conf.lib.clang_getCompletionChunkKind(self.cs, self.key) - if kind_id in SPELLING_CACHE: - return SPELLING_CACHE[kind_id] + kind = self.kind + if kind in CompletionChunk.SPELLING_CACHE: + return CompletionChunk.SPELLING_CACHE[kind] return _CXString.from_result( conf.lib.clang_getCompletionChunkText(self.cs, self.key) ) @@ -3150,6 +3173,9 @@ def isKindResultType(self) -> bool: return self.kind == CompletionChunkKind.RESULT_TYPE +SPELLING_CACHE = CompletionChunk.SpellingCacheAlias() + + class CompletionString(ClangObject): # AvailabilityKindCompat is an exact copy of AvailabilityKind, except for __str__. # This is a temporary measure to keep the string representation the same diff --git a/clang/bindings/python/tests/cindex/test_code_completion.py b/clang/bindings/python/tests/cindex/test_code_completion.py index c376b0e5cce40..e3a340c061434 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, ) @@ -214,3 +216,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() diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 14384ea3b51c1..df4b21fc26ff1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -72,6 +72,11 @@ Clang Python Bindings Potentially Breaking Changes These representations will be changed in a future release to match other enums. - Remove ``completionChunkKindMap``. In this release, uses of ``completionChunkKindMap`` need to be replaced by ``CompletionChunkKind``. +- Move ``SPELLING_CACHE`` into ``CompletionChunk`` and change it to use + ``CompletionChunkKind`` instances as keys, instead of the enum values. + An alias is kept in the form of a ``SPELLING_CACHE`` variable, but it only supports + ``__getitem__`` and ``__contains__``. It will be removed in a future release. + Please migrate to using ``CompletionChunk.SPELLING_CACHE`` instead. What's New in Clang |release|? ============================== _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
