Author: Jannick Kremer
Date: 2025-05-18T08:43:38+01:00
New Revision: 3ccb15d6caf57f2a866d496ada2fb52d14b179d2

URL: 
https://github.com/llvm/llvm-project/commit/3ccb15d6caf57f2a866d496ada2fb52d14b179d2
DIFF: 
https://github.com/llvm/llvm-project/commit/3ccb15d6caf57f2a866d496ada2fb52d14b179d2.diff

LOG: [libclang/python] Add typing annotations for the Type class (#140378)

This fully annotates the Type class, resolving 75 strict typing errors
as the next step towards #76664

Added: 
    

Modified: 
    clang/bindings/python/clang/cindex.py

Removed: 
    


################################################################################
diff  --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index a49441e815004..f65bcad780a70 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -91,6 +91,7 @@
     cast as Tcast,
     Generic,
     Iterator,
+    Literal,
     Optional,
     Sequence,
     Type as TType,
@@ -1982,7 +1983,7 @@ def type(self) -> Type:
         Retrieve the Type (if any) of the entity pointed at by the cursor.
         """
         if not hasattr(self, "_type"):
-            self._type = Type.from_result(conf.lib.clang_getCursorType(self), 
(self,))
+            self._type = Type.from_result(conf.lib.clang_getCursorType(self), 
self)
 
         return self._type
 
@@ -2009,7 +2010,7 @@ def result_type(self) -> Type:
         """Retrieve the Type of the result for this Cursor."""
         if not hasattr(self, "_result_type"):
             self._result_type = Type.from_result(
-                conf.lib.clang_getCursorResultType(self), (self,)
+                conf.lib.clang_getCursorResultType(self), self
             )
 
         return self._result_type
@@ -2040,7 +2041,7 @@ def underlying_typedef_type(self) -> Type:
         if not hasattr(self, "_underlying_type"):
             assert self.kind.is_declaration()
             self._underlying_type = Type.from_result(
-                conf.lib.clang_getTypedefDeclUnderlyingType(self), (self,)
+                conf.lib.clang_getTypedefDeclUnderlyingType(self), self
             )
 
         return self._underlying_type
@@ -2056,7 +2057,7 @@ def enum_type(self) -> Type:
         if not hasattr(self, "_enum_type"):
             assert self.kind == CursorKind.ENUM_DECL
             self._enum_type = Type.from_result(
-                conf.lib.clang_getEnumDeclIntegerType(self), (self,)
+                conf.lib.clang_getEnumDeclIntegerType(self), self
             )
 
         return self._enum_type
@@ -2197,7 +2198,7 @@ def get_template_argument_kind(self, num: int) -> 
TemplateArgumentKind:
     def get_template_argument_type(self, num: int) -> Type:
         """Returns the CXType for the indicated template argument."""
         return Type.from_result(
-            conf.lib.clang_Cursor_getTemplateArgumentType(self, num), (self, 
num)
+            conf.lib.clang_Cursor_getTemplateArgumentType(self, num), self
         )
 
     @cursor_null_guard
@@ -2597,8 +2598,10 @@ class Type(Structure):
 
     _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
 
+    _tu: TranslationUnit
+
     @property
-    def kind(self):
+    def kind(self) -> TypeKind:
         """Return the kind of this type."""
         return TypeKind.from_id(self._kind_id)
 
@@ -2635,7 +2638,7 @@ def __getitem__(self, key: int) -> Type:
                     )
 
                 result = Type.from_result(
-                    conf.lib.clang_getArgType(self.parent, key), (self.parent, 
key)
+                    conf.lib.clang_getArgType(self.parent, key), self.parent
                 )
                 if result.kind == TypeKind.INVALID:
                     raise IndexError("Argument could not be retrieved.")
@@ -2646,63 +2649,56 @@ def __getitem__(self, key: int) -> Type:
         return ArgumentsIterator(self)
 
     @property
-    def element_type(self):
+    def element_type(self) -> Type:
         """Retrieve the Type of elements within this Type.
 
         If accessed on a type that is not an array, complex, or vector type, an
         exception will be raised.
         """
-        result = Type.from_result(conf.lib.clang_getElementType(self), (self,))
+        result = Type.from_result(conf.lib.clang_getElementType(self), self)
         if result.kind == TypeKind.INVALID:
             raise Exception("Element type not available on this type.")
 
         return result
 
     @property
-    def element_count(self):
+    def element_count(self) -> int:
         """Retrieve the number of elements in this type.
 
         Returns an int.
 
         If the Type is not an array or vector, this raises.
         """
-        result = conf.lib.clang_getNumElements(self)
+        result: int = conf.lib.clang_getNumElements(self)
         if result < 0:
             raise Exception("Type does not have elements.")
 
         return result
 
     @property
-    def translation_unit(self):
+    def translation_unit(self) -> TranslationUnit:
         """The TranslationUnit to which this Type is associated."""
         # If this triggers an AttributeError, the instance was not properly
         # instantiated.
         return self._tu
 
     @staticmethod
-    def from_result(res, args):
+    def from_result(res: Type, arg: Cursor | Type) -> Type:
         assert isinstance(res, Type)
-
-        tu = None
-        for arg in args:
-            if hasattr(arg, "translation_unit"):
-                tu = arg.translation_unit
-                break
-
-        assert tu is not None
-        res._tu = tu
+        assert arg.translation_unit is not None
+        res._tu = arg.translation_unit
 
         return res
 
-    def get_num_template_arguments(self):
+    def get_num_template_arguments(self) -> int:
         return conf.lib.clang_Type_getNumTemplateArguments(self)  # type: 
ignore [no-any-return]
 
-    def get_template_argument_type(self, num):
+    def get_template_argument_type(self, num: int) -> Type:
         return Type.from_result(
-            conf.lib.clang_Type_getTemplateArgumentAsType(self, num), (self, 
num)
+            conf.lib.clang_Type_getTemplateArgumentAsType(self, num), self
         )
 
-    def get_canonical(self):
+    def get_canonical(self) -> Type:
         """
         Return the canonical type for a Type.
 
@@ -2712,9 +2708,11 @@ def get_canonical(self):
         example, if 'T' is a typedef for 'int', the canonical type for
         'T' would be 'int'.
         """
-        return Type.from_result(conf.lib.clang_getCanonicalType(self), (self,))
+        return Type.from_result(conf.lib.clang_getCanonicalType(self), self)
 
-    def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
+    def get_fully_qualified_name(
+        self, policy: PrintingPolicy, with_global_ns_prefix: bool = False
+    ) -> str:
         """
         Get the fully qualified name for a type.
 
@@ -2727,7 +2725,7 @@ def get_fully_qualified_name(self, policy, 
with_global_ns_prefix=False):
             conf.lib.clang_getFullyQualifiedName(self, policy, 
with_global_ns_prefix)
         )
 
-    def is_const_qualified(self):
+    def is_const_qualified(self) -> bool:
         """Determine whether a Type has the "const" qualifier set.
 
         This does not look through typedefs that may have added "const"
@@ -2735,7 +2733,7 @@ def is_const_qualified(self):
         """
         return conf.lib.clang_isConstQualifiedType(self)  # type: ignore 
[no-any-return]
 
-    def is_volatile_qualified(self):
+    def is_volatile_qualified(self) -> bool:
         """Determine whether a Type has the "volatile" qualifier set.
 
         This does not look through typedefs that may have added "volatile"
@@ -2743,7 +2741,7 @@ def is_volatile_qualified(self):
         """
         return conf.lib.clang_isVolatileQualifiedType(self)  # type: ignore 
[no-any-return]
 
-    def is_restrict_qualified(self):
+    def is_restrict_qualified(self) -> bool:
         """Determine whether a Type has the "restrict" qualifier set.
 
         This does not look through typedefs that may have added "restrict" at
@@ -2751,29 +2749,29 @@ def is_restrict_qualified(self):
         """
         return conf.lib.clang_isRestrictQualifiedType(self)  # type: ignore 
[no-any-return]
 
-    def is_function_variadic(self):
+    def is_function_variadic(self) -> bool:
         """Determine whether this function Type is a variadic function type."""
         assert self.kind == TypeKind.FUNCTIONPROTO
 
         return conf.lib.clang_isFunctionTypeVariadic(self)  # type: ignore 
[no-any-return]
 
-    def get_address_space(self):
+    def get_address_space(self) -> int:
         return conf.lib.clang_getAddressSpace(self)  # type: ignore 
[no-any-return]
 
-    def get_typedef_name(self):
+    def get_typedef_name(self) -> str:
         return _CXString.from_result(conf.lib.clang_getTypedefName(self))
 
-    def is_pod(self):
+    def is_pod(self) -> bool:
         """Determine whether this Type represents plain old data (POD)."""
         return conf.lib.clang_isPODType(self)  # type: ignore [no-any-return]
 
-    def get_pointee(self):
+    def get_pointee(self) -> Type:
         """
         For pointer types, returns the type of the pointee.
         """
-        return Type.from_result(conf.lib.clang_getPointeeType(self), (self,))
+        return Type.from_result(conf.lib.clang_getPointeeType(self), self)
 
-    def get_declaration(self):
+    def get_declaration(self) -> Cursor:
         """
         Return the cursor for the declaration of the given type.
         """
@@ -2781,64 +2779,64 @@ def get_declaration(self):
             conf.lib.clang_getTypeDeclaration(self), self
         )
 
-    def get_result(self):
+    def get_result(self) -> Type:
         """
         Retrieve the result type associated with a function type.
         """
-        return Type.from_result(conf.lib.clang_getResultType(self), (self,))
+        return Type.from_result(conf.lib.clang_getResultType(self), self)
 
-    def get_array_element_type(self):
+    def get_array_element_type(self) -> Type:
         """
         Retrieve the type of the elements of the array type.
         """
-        return Type.from_result(conf.lib.clang_getArrayElementType(self), 
(self,))
+        return Type.from_result(conf.lib.clang_getArrayElementType(self), self)
 
-    def get_array_size(self):
+    def get_array_size(self) -> int:
         """
         Retrieve the size of the constant array.
         """
         return conf.lib.clang_getArraySize(self)  # type: ignore 
[no-any-return]
 
-    def get_class_type(self):
+    def get_class_type(self) -> Type:
         """
         Retrieve the class type of the member pointer type.
         """
-        return Type.from_result(conf.lib.clang_Type_getClassType(self), 
(self,))
+        return Type.from_result(conf.lib.clang_Type_getClassType(self), self)
 
-    def get_named_type(self):
+    def get_named_type(self) -> Type:
         """
         Retrieve the type named by the qualified-id.
         """
-        return Type.from_result(conf.lib.clang_Type_getNamedType(self), 
(self,))
+        return Type.from_result(conf.lib.clang_Type_getNamedType(self), self)
 
-    def get_align(self):
+    def get_align(self) -> int:
         """
         Retrieve the alignment of the record.
         """
         return conf.lib.clang_Type_getAlignOf(self)  # type: ignore 
[no-any-return]
 
-    def get_size(self):
+    def get_size(self) -> int:
         """
         Retrieve the size of the record.
         """
         return conf.lib.clang_Type_getSizeOf(self)  # type: ignore 
[no-any-return]
 
-    def get_offset(self, fieldname):
+    def get_offset(self, fieldname: str) -> int:
         """
         Retrieve the offset of a field in the record.
         """
         return conf.lib.clang_Type_getOffsetOf(self, fieldname)  # type: 
ignore [no-any-return]
 
-    def get_ref_qualifier(self):
+    def get_ref_qualifier(self) -> RefQualifierKind:
         """
         Retrieve the ref-qualifier of the type.
         """
         return 
RefQualifierKind.from_id(conf.lib.clang_Type_getCXXRefQualifier(self))
 
-    def get_fields(self):
+    def get_fields(self) -> Iterator[Cursor]:
         """Return an iterator for accessing the fields of this type."""
 
-        def visitor(field, children):
+        def visitor(field: Cursor, _: Any) -> Literal[1]:
             assert not field.is_null()
 
             # Create reference to TU so it isn't GC'd before Cursor.
@@ -2850,10 +2848,10 @@ def visitor(field, children):
         conf.lib.clang_Type_visitFields(self, fields_visit_callback(visitor), 
fields)
         return iter(fields)
 
-    def get_bases(self):
+    def get_bases(self) -> Iterator[Cursor]:
         """Return an iterator for accessing the base classes of this type."""
 
-        def visitor(base, children):
+        def visitor(base: Cursor, _: Any) -> Literal[1]:
             assert not base.is_null()
 
             # Create reference to TU so it isn't GC'd before Cursor.
@@ -2865,10 +2863,10 @@ def visitor(base, children):
         conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
         return iter(bases)
 
-    def get_methods(self):
+    def get_methods(self) -> Iterator[Cursor]:
         """Return an iterator for accessing the methods of this type."""
 
-        def visitor(method, children):
+        def visitor(method: Cursor, _: Any) -> Literal[1]:
             assert not method.is_null()
 
             # Create reference to TU so it isn't GC'd before Cursor.
@@ -2880,7 +2878,7 @@ def visitor(method, children):
         conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
         return iter(methods)
 
-    def get_exception_specification_kind(self):
+    def get_exception_specification_kind(self) -> ExceptionSpecificationKind:
         """
         Return the kind of the exception specification; a value from
         the ExceptionSpecificationKind enumeration.
@@ -2890,21 +2888,18 @@ def get_exception_specification_kind(self):
         )
 
     @property
-    def spelling(self):
+    def spelling(self) -> str:
         """Retrieve the spelling of this Type."""
         return _CXString.from_result(conf.lib.clang_getTypeSpelling(self))
 
-    def pretty_printed(self, policy):
+    def pretty_printed(self, policy: PrintingPolicy) -> str:
         """Pretty-prints this Type with the given PrintingPolicy"""
         return _CXString.from_result(conf.lib.clang_getTypePrettyPrinted(self, 
policy))
 
-    def __eq__(self, other):
-        if not isinstance(other, Type):
-            return False
-
-        return conf.lib.clang_equalTypes(self, other)  # type: ignore 
[no-any-return]
+    def __eq__(self, other: object) -> bool:
+        return isinstance(other, Type) and conf.lib.clang_equalTypes(self, 
other)
 
-    def __ne__(self, other):
+    def __ne__(self, other: object) -> bool:
         return not self.__eq__(other)
 
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to