[libclang/python] Remove CompletionString.AvailabilityKindCompat (#210682)

This completes the fourth step of
https://github.com/llvm/llvm-project/pull/156680
This change is a follow-up to
https://github.com/llvm/llvm-project/pull/160296, following the release
branching, to ensure a one release-cycle deprecation period.

---------

Co-authored-by: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
This commit is contained in:
Jannick Kremer 2026-07-25 12:38:13 +09:00 committed by GitHub
parent cf95452508
commit c64a5b0c4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 121 deletions

View file

@ -3140,52 +3140,6 @@ class CompletionChunk:
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
# until we change CompletionString.availability to return AvailabilityKind,
# like Cursor.availability does.
# Note that deriving from AvailabilityKind directly is not possible.
class AvailabilityKindCompat(BaseEnumeration):
"""
Describes the availability of an entity.
It is deprecated in favor of AvailabilityKind.
"""
# Ensure AvailabilityKindCompat is comparable with AvailabilityKind
def __eq__(self, other: object) -> bool:
if isinstance(
other, (AvailabilityKind, CompletionString.AvailabilityKindCompat)
):
return self.value == other.value
else:
return NotImplemented
def __str__(self) -> str:
"""
Converts enum value to string in the old camelCase format.
This is a temporary measure that will be changed in the future release
to return string in ALL_CAPS format, like for other enums.
"""
warnings.warn(
"String representation of 'CompletionString.availability' will be "
"changed in a future release from 'camelCase' to 'ALL_CAPS' to "
"match other enums. 'CompletionString.availability' can be "
"compared to 'AvailabilityKind' directly, "
"without conversion to string.",
DeprecationWarning,
)
# Remove underscores
components = self.name.split("_")
# Upper-camel case each split component
components = [component.lower().capitalize() for component in components]
return "".join(components)
AVAILABLE = 0
DEPRECATED = 1
NOT_AVAILABLE = 2
NOT_ACCESSIBLE = 3
def __len__(self) -> int:
return self.num_chunks
@ -3210,9 +3164,9 @@ class CompletionString(ClangObject):
return conf.lib.clang_getCompletionPriority(self.obj) # type: ignore [no-any-return]
@property
def availability(self) -> AvailabilityKindCompat:
def availability(self) -> AvailabilityKind:
res = conf.lib.clang_getCompletionAvailability(self.obj)
return CompletionString.AvailabilityKindCompat.from_id(res)
return AvailabilityKind.from_id(res)
@property
def briefComment(self) -> str:

View file

@ -16,24 +16,10 @@ class TestCodeCompletion(unittest.TestCase):
self.assertIsNotNone(cr)
self.assertEqual(len(cr.diagnostics), 0)
with warnings.catch_warnings(record=True) as log:
completions = [str(c) for c in cr]
self.assertEqual(len(log), 1)
for warning in log:
self.assertIsInstance(warning.message, DeprecationWarning)
completions = [str(c) for c in cr]
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)
for warning in log:
self.assertIsInstance(warning.message, DeprecationWarning)
for c in expected:
self.assertIn(c, completions_deprecated)
def test_code_complete(self):
files = [
(
@ -64,9 +50,9 @@ void f() {
)
expected = [
"{'int', CompletionChunkKind.RESULT_TYPE} | {'test1', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'test2', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
"{'return', CompletionChunkKind.TYPED_TEXT} | {';', CompletionChunkKind.SEMI_COLON} || Priority: 40 || Availability: Available || Brief comment: ",
"{'int', CompletionChunkKind.RESULT_TYPE} | {'test1', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: Aaa.",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'test2', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: Bbb.",
"{'return', CompletionChunkKind.TYPED_TEXT} | {';', CompletionChunkKind.SEMI_COLON} || Priority: 40 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
]
self.check_completion_results(cr, expected)
@ -104,9 +90,9 @@ void f() {
)
expected = [
"{'int', CompletionChunkKind.RESULT_TYPE} | {'test1', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'test2', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
"{'return', CompletionChunkKind.TYPED_TEXT} | {';', CompletionChunkKind.SEMI_COLON} || Priority: 40 || Availability: Available || Brief comment: ",
"{'int', CompletionChunkKind.RESULT_TYPE} | {'test1', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: Aaa.",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'test2', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: Bbb.",
"{'return', CompletionChunkKind.TYPED_TEXT} | {';', CompletionChunkKind.SEMI_COLON} || Priority: 40 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
]
self.check_completion_results(cr, expected)
@ -140,60 +126,18 @@ void f(P x, Q y) {
cr = tu.codeComplete("fake.cpp", 12, 5, unsaved_files=files)
expected = [
"{'const', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: ",
"{'volatile', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: ",
"{'operator', CompletionChunkKind.TYPED_TEXT} || Priority: 40 || Availability: Available || Brief comment: ",
"{'P', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: ",
"{'Q', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: Available || Brief comment: ",
"{'const', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'volatile', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'operator', CompletionChunkKind.TYPED_TEXT} || Priority: 40 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'P', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'Q', CompletionChunkKind.TYPED_TEXT} || Priority: 50 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
]
self.check_completion_results(cr, expected)
cr = tu.codeComplete("fake.cpp", 13, 5, unsaved_files=files)
expected = [
"{'P', CompletionChunkKind.TYPED_TEXT} | {'::', CompletionChunkKind.TEXT} || Priority: 75 || Availability: Available || Brief comment: ",
"{'P &', CompletionChunkKind.RESULT_TYPE} | {'operator=', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {'const P &', CompletionChunkKind.PLACEHOLDER} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 79 || Availability: Available || Brief comment: ",
"{'int', CompletionChunkKind.RESULT_TYPE} | {'member', CompletionChunkKind.TYPED_TEXT} || Priority: 35 || Availability: NotAccessible || Brief comment: ",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'~P', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 79 || Availability: Available || Brief comment: ",
"{'P', CompletionChunkKind.TYPED_TEXT} | {'::', CompletionChunkKind.TEXT} || Priority: 75 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'P &', CompletionChunkKind.RESULT_TYPE} | {'operator=', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {'const P &', CompletionChunkKind.PLACEHOLDER} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 79 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
"{'int', CompletionChunkKind.RESULT_TYPE} | {'member', CompletionChunkKind.TYPED_TEXT} || Priority: 35 || AvailabilityKind.NOT_ACCESSIBLE || Brief comment: ",
"{'void', CompletionChunkKind.RESULT_TYPE} | {'~P', CompletionChunkKind.TYPED_TEXT} | {'(', CompletionChunkKind.LEFT_PAREN} | {')', CompletionChunkKind.RIGHT_PAREN} || Priority: 79 || Availability: AvailabilityKind.AVAILABLE || Brief comment: ",
]
self.check_completion_results(cr, expected)
def test_availability_kind_compat(self):
numKinds = len(CompletionString.AvailabilityKindCompat)
# Compare with regular kind
for compatKind in CompletionString.AvailabilityKindCompat:
commonKind = AvailabilityKind.from_id(compatKind.value)
nextKindId = (compatKind.value + 1) % numKinds
commonKindUnequal = AvailabilityKind.from_id(nextKindId)
self.assertEqual(commonKind, compatKind)
self.assertEqual(compatKind, commonKind)
self.assertNotEqual(commonKindUnequal, compatKind)
self.assertNotEqual(compatKind, commonKindUnequal)
# Compare two compat kinds
for compatKind in CompletionString.AvailabilityKindCompat:
compatKind2 = CompletionString.AvailabilityKindCompat.from_id(
compatKind.value
)
nextKindId = (compatKind.value + 1) % numKinds
compatKind2Unequal = CompletionString.AvailabilityKindCompat.from_id(
nextKindId
)
self.assertEqual(compatKind, compatKind2)
self.assertEqual(compatKind2, compatKind)
self.assertNotEqual(compatKind2Unequal, compatKind)
self.assertNotEqual(compatKind, compatKind2Unequal)
def test_compat_str(self):
kindStringMap = {
0: "Available",
1: "Deprecated",
2: "NotAvailable",
3: "NotAccessible",
}
for id, string in kindStringMap.items():
kind = CompletionString.AvailabilityKindCompat.from_id(id)
with warnings.catch_warnings(record=True) as log:
self.assertEqual(str(kind), string)
self.assertEqual(len(log), 1)
self.assertIsInstance(log[0].message, DeprecationWarning)

View file

@ -27,7 +27,6 @@ class TestEnums(unittest.TestCase):
# Test all enum classes, except for AvailabilityKindCompat since it is
# just a copy of AvailabilityKind and has no corresponding C-class
enums = BaseEnumeration.__subclasses__()
enums.remove(CompletionString.AvailabilityKindCompat)
def test_from_id(self):
"""Check that kinds can be constructed from valid IDs"""

View file

@ -83,6 +83,10 @@ features cannot lower the translation-unit ABI level;
Affected methods: `isKindOptional`, `isKindTypedText`, `isKindPlaceHolder`,
`isKindInformative` and `isKindResultType`.
- `CompletionString.availability` now returns instances of `AvailabilityKind`.
As a result, the `__str__` representation of its return values changed.
Like other libclang enums, it now follows the `CompletionChunkKind.VARIANT_NAME` scheme instead of `VariantName`.
### OpenCL Potentially Breaking Changes
## What's New in Clang {{env.config.release}}?