Skip to content

Commit 3ccb15d

Browse files
authored
[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
1 parent ad060df commit 3ccb15d

File tree

1 file changed

+61
-66
lines changed

1 file changed

+61
-66
lines changed

clang/bindings/python/clang/cindex.py

Lines changed: 61 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
cast as Tcast,
9292
Generic,
9393
Iterator,
94+
Literal,
9495
Optional,
9596
Sequence,
9697
Type as TType,
@@ -1982,7 +1983,7 @@ def type(self) -> Type:
19821983
Retrieve the Type (if any) of the entity pointed at by the cursor.
19831984
"""
19841985
if not hasattr(self, "_type"):
1985-
self._type = Type.from_result(conf.lib.clang_getCursorType(self), (self,))
1986+
self._type = Type.from_result(conf.lib.clang_getCursorType(self), self)
19861987

19871988
return self._type
19881989

@@ -2009,7 +2010,7 @@ def result_type(self) -> Type:
20092010
"""Retrieve the Type of the result for this Cursor."""
20102011
if not hasattr(self, "_result_type"):
20112012
self._result_type = Type.from_result(
2012-
conf.lib.clang_getCursorResultType(self), (self,)
2013+
conf.lib.clang_getCursorResultType(self), self
20132014
)
20142015

20152016
return self._result_type
@@ -2040,7 +2041,7 @@ def underlying_typedef_type(self) -> Type:
20402041
if not hasattr(self, "_underlying_type"):
20412042
assert self.kind.is_declaration()
20422043
self._underlying_type = Type.from_result(
2043-
conf.lib.clang_getTypedefDeclUnderlyingType(self), (self,)
2044+
conf.lib.clang_getTypedefDeclUnderlyingType(self), self
20442045
)
20452046

20462047
return self._underlying_type
@@ -2056,7 +2057,7 @@ def enum_type(self) -> Type:
20562057
if not hasattr(self, "_enum_type"):
20572058
assert self.kind == CursorKind.ENUM_DECL
20582059
self._enum_type = Type.from_result(
2059-
conf.lib.clang_getEnumDeclIntegerType(self), (self,)
2060+
conf.lib.clang_getEnumDeclIntegerType(self), self
20602061
)
20612062

20622063
return self._enum_type
@@ -2197,7 +2198,7 @@ def get_template_argument_kind(self, num: int) -> TemplateArgumentKind:
21972198
def get_template_argument_type(self, num: int) -> Type:
21982199
"""Returns the CXType for the indicated template argument."""
21992200
return Type.from_result(
2200-
conf.lib.clang_Cursor_getTemplateArgumentType(self, num), (self, num)
2201+
conf.lib.clang_Cursor_getTemplateArgumentType(self, num), self
22012202
)
22022203

22032204
@cursor_null_guard
@@ -2597,8 +2598,10 @@ class Type(Structure):
25972598

25982599
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
25992600

2601+
_tu: TranslationUnit
2602+
26002603
@property
2601-
def kind(self):
2604+
def kind(self) -> TypeKind:
26022605
"""Return the kind of this type."""
26032606
return TypeKind.from_id(self._kind_id)
26042607

@@ -2635,7 +2638,7 @@ def __getitem__(self, key: int) -> Type:
26352638
)
26362639

26372640
result = Type.from_result(
2638-
conf.lib.clang_getArgType(self.parent, key), (self.parent, key)
2641+
conf.lib.clang_getArgType(self.parent, key), self.parent
26392642
)
26402643
if result.kind == TypeKind.INVALID:
26412644
raise IndexError("Argument could not be retrieved.")
@@ -2646,63 +2649,56 @@ def __getitem__(self, key: int) -> Type:
26462649
return ArgumentsIterator(self)
26472650

26482651
@property
2649-
def element_type(self):
2652+
def element_type(self) -> Type:
26502653
"""Retrieve the Type of elements within this Type.
26512654
26522655
If accessed on a type that is not an array, complex, or vector type, an
26532656
exception will be raised.
26542657
"""
2655-
result = Type.from_result(conf.lib.clang_getElementType(self), (self,))
2658+
result = Type.from_result(conf.lib.clang_getElementType(self), self)
26562659
if result.kind == TypeKind.INVALID:
26572660
raise Exception("Element type not available on this type.")
26582661

26592662
return result
26602663

26612664
@property
2662-
def element_count(self):
2665+
def element_count(self) -> int:
26632666
"""Retrieve the number of elements in this type.
26642667
26652668
Returns an int.
26662669
26672670
If the Type is not an array or vector, this raises.
26682671
"""
2669-
result = conf.lib.clang_getNumElements(self)
2672+
result: int = conf.lib.clang_getNumElements(self)
26702673
if result < 0:
26712674
raise Exception("Type does not have elements.")
26722675

26732676
return result
26742677

26752678
@property
2676-
def translation_unit(self):
2679+
def translation_unit(self) -> TranslationUnit:
26772680
"""The TranslationUnit to which this Type is associated."""
26782681
# If this triggers an AttributeError, the instance was not properly
26792682
# instantiated.
26802683
return self._tu
26812684

26822685
@staticmethod
2683-
def from_result(res, args):
2686+
def from_result(res: Type, arg: Cursor | Type) -> Type:
26842687
assert isinstance(res, Type)
2685-
2686-
tu = None
2687-
for arg in args:
2688-
if hasattr(arg, "translation_unit"):
2689-
tu = arg.translation_unit
2690-
break
2691-
2692-
assert tu is not None
2693-
res._tu = tu
2688+
assert arg.translation_unit is not None
2689+
res._tu = arg.translation_unit
26942690

26952691
return res
26962692

2697-
def get_num_template_arguments(self):
2693+
def get_num_template_arguments(self) -> int:
26982694
return conf.lib.clang_Type_getNumTemplateArguments(self) # type: ignore [no-any-return]
26992695

2700-
def get_template_argument_type(self, num):
2696+
def get_template_argument_type(self, num: int) -> Type:
27012697
return Type.from_result(
2702-
conf.lib.clang_Type_getTemplateArgumentAsType(self, num), (self, num)
2698+
conf.lib.clang_Type_getTemplateArgumentAsType(self, num), self
27032699
)
27042700

2705-
def get_canonical(self):
2701+
def get_canonical(self) -> Type:
27062702
"""
27072703
Return the canonical type for a Type.
27082704
@@ -2712,9 +2708,11 @@ def get_canonical(self):
27122708
example, if 'T' is a typedef for 'int', the canonical type for
27132709
'T' would be 'int'.
27142710
"""
2715-
return Type.from_result(conf.lib.clang_getCanonicalType(self), (self,))
2711+
return Type.from_result(conf.lib.clang_getCanonicalType(self), self)
27162712

2717-
def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
2713+
def get_fully_qualified_name(
2714+
self, policy: PrintingPolicy, with_global_ns_prefix: bool = False
2715+
) -> str:
27182716
"""
27192717
Get the fully qualified name for a type.
27202718
@@ -2727,118 +2725,118 @@ def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
27272725
conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix)
27282726
)
27292727

2730-
def is_const_qualified(self):
2728+
def is_const_qualified(self) -> bool:
27312729
"""Determine whether a Type has the "const" qualifier set.
27322730
27332731
This does not look through typedefs that may have added "const"
27342732
at a different level.
27352733
"""
27362734
return conf.lib.clang_isConstQualifiedType(self) # type: ignore [no-any-return]
27372735

2738-
def is_volatile_qualified(self):
2736+
def is_volatile_qualified(self) -> bool:
27392737
"""Determine whether a Type has the "volatile" qualifier set.
27402738
27412739
This does not look through typedefs that may have added "volatile"
27422740
at a different level.
27432741
"""
27442742
return conf.lib.clang_isVolatileQualifiedType(self) # type: ignore [no-any-return]
27452743

2746-
def is_restrict_qualified(self):
2744+
def is_restrict_qualified(self) -> bool:
27472745
"""Determine whether a Type has the "restrict" qualifier set.
27482746
27492747
This does not look through typedefs that may have added "restrict" at
27502748
a different level.
27512749
"""
27522750
return conf.lib.clang_isRestrictQualifiedType(self) # type: ignore [no-any-return]
27532751

2754-
def is_function_variadic(self):
2752+
def is_function_variadic(self) -> bool:
27552753
"""Determine whether this function Type is a variadic function type."""
27562754
assert self.kind == TypeKind.FUNCTIONPROTO
27572755

27582756
return conf.lib.clang_isFunctionTypeVariadic(self) # type: ignore [no-any-return]
27592757

2760-
def get_address_space(self):
2758+
def get_address_space(self) -> int:
27612759
return conf.lib.clang_getAddressSpace(self) # type: ignore [no-any-return]
27622760

2763-
def get_typedef_name(self):
2761+
def get_typedef_name(self) -> str:
27642762
return _CXString.from_result(conf.lib.clang_getTypedefName(self))
27652763

2766-
def is_pod(self):
2764+
def is_pod(self) -> bool:
27672765
"""Determine whether this Type represents plain old data (POD)."""
27682766
return conf.lib.clang_isPODType(self) # type: ignore [no-any-return]
27692767

2770-
def get_pointee(self):
2768+
def get_pointee(self) -> Type:
27712769
"""
27722770
For pointer types, returns the type of the pointee.
27732771
"""
2774-
return Type.from_result(conf.lib.clang_getPointeeType(self), (self,))
2772+
return Type.from_result(conf.lib.clang_getPointeeType(self), self)
27752773

2776-
def get_declaration(self):
2774+
def get_declaration(self) -> Cursor:
27772775
"""
27782776
Return the cursor for the declaration of the given type.
27792777
"""
27802778
return Cursor.from_non_null_cursor_result(
27812779
conf.lib.clang_getTypeDeclaration(self), self
27822780
)
27832781

2784-
def get_result(self):
2782+
def get_result(self) -> Type:
27852783
"""
27862784
Retrieve the result type associated with a function type.
27872785
"""
2788-
return Type.from_result(conf.lib.clang_getResultType(self), (self,))
2786+
return Type.from_result(conf.lib.clang_getResultType(self), self)
27892787

2790-
def get_array_element_type(self):
2788+
def get_array_element_type(self) -> Type:
27912789
"""
27922790
Retrieve the type of the elements of the array type.
27932791
"""
2794-
return Type.from_result(conf.lib.clang_getArrayElementType(self), (self,))
2792+
return Type.from_result(conf.lib.clang_getArrayElementType(self), self)
27952793

2796-
def get_array_size(self):
2794+
def get_array_size(self) -> int:
27972795
"""
27982796
Retrieve the size of the constant array.
27992797
"""
28002798
return conf.lib.clang_getArraySize(self) # type: ignore [no-any-return]
28012799

2802-
def get_class_type(self):
2800+
def get_class_type(self) -> Type:
28032801
"""
28042802
Retrieve the class type of the member pointer type.
28052803
"""
2806-
return Type.from_result(conf.lib.clang_Type_getClassType(self), (self,))
2804+
return Type.from_result(conf.lib.clang_Type_getClassType(self), self)
28072805

2808-
def get_named_type(self):
2806+
def get_named_type(self) -> Type:
28092807
"""
28102808
Retrieve the type named by the qualified-id.
28112809
"""
2812-
return Type.from_result(conf.lib.clang_Type_getNamedType(self), (self,))
2810+
return Type.from_result(conf.lib.clang_Type_getNamedType(self), self)
28132811

2814-
def get_align(self):
2812+
def get_align(self) -> int:
28152813
"""
28162814
Retrieve the alignment of the record.
28172815
"""
28182816
return conf.lib.clang_Type_getAlignOf(self) # type: ignore [no-any-return]
28192817

2820-
def get_size(self):
2818+
def get_size(self) -> int:
28212819
"""
28222820
Retrieve the size of the record.
28232821
"""
28242822
return conf.lib.clang_Type_getSizeOf(self) # type: ignore [no-any-return]
28252823

2826-
def get_offset(self, fieldname):
2824+
def get_offset(self, fieldname: str) -> int:
28272825
"""
28282826
Retrieve the offset of a field in the record.
28292827
"""
28302828
return conf.lib.clang_Type_getOffsetOf(self, fieldname) # type: ignore [no-any-return]
28312829

2832-
def get_ref_qualifier(self):
2830+
def get_ref_qualifier(self) -> RefQualifierKind:
28332831
"""
28342832
Retrieve the ref-qualifier of the type.
28352833
"""
28362834
return RefQualifierKind.from_id(conf.lib.clang_Type_getCXXRefQualifier(self))
28372835

2838-
def get_fields(self):
2836+
def get_fields(self) -> Iterator[Cursor]:
28392837
"""Return an iterator for accessing the fields of this type."""
28402838

2841-
def visitor(field, children):
2839+
def visitor(field: Cursor, _: Any) -> Literal[1]:
28422840
assert not field.is_null()
28432841

28442842
# Create reference to TU so it isn't GC'd before Cursor.
@@ -2850,10 +2848,10 @@ def visitor(field, children):
28502848
conf.lib.clang_Type_visitFields(self, fields_visit_callback(visitor), fields)
28512849
return iter(fields)
28522850

2853-
def get_bases(self):
2851+
def get_bases(self) -> Iterator[Cursor]:
28542852
"""Return an iterator for accessing the base classes of this type."""
28552853

2856-
def visitor(base, children):
2854+
def visitor(base: Cursor, _: Any) -> Literal[1]:
28572855
assert not base.is_null()
28582856

28592857
# Create reference to TU so it isn't GC'd before Cursor.
@@ -2865,10 +2863,10 @@ def visitor(base, children):
28652863
conf.lib.clang_visitCXXBaseClasses(self, fields_visit_callback(visitor), bases)
28662864
return iter(bases)
28672865

2868-
def get_methods(self):
2866+
def get_methods(self) -> Iterator[Cursor]:
28692867
"""Return an iterator for accessing the methods of this type."""
28702868

2871-
def visitor(method, children):
2869+
def visitor(method: Cursor, _: Any) -> Literal[1]:
28722870
assert not method.is_null()
28732871

28742872
# Create reference to TU so it isn't GC'd before Cursor.
@@ -2880,7 +2878,7 @@ def visitor(method, children):
28802878
conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), methods)
28812879
return iter(methods)
28822880

2883-
def get_exception_specification_kind(self):
2881+
def get_exception_specification_kind(self) -> ExceptionSpecificationKind:
28842882
"""
28852883
Return the kind of the exception specification; a value from
28862884
the ExceptionSpecificationKind enumeration.
@@ -2890,21 +2888,18 @@ def get_exception_specification_kind(self):
28902888
)
28912889

28922890
@property
2893-
def spelling(self):
2891+
def spelling(self) -> str:
28942892
"""Retrieve the spelling of this Type."""
28952893
return _CXString.from_result(conf.lib.clang_getTypeSpelling(self))
28962894

2897-
def pretty_printed(self, policy):
2895+
def pretty_printed(self, policy: PrintingPolicy) -> str:
28982896
"""Pretty-prints this Type with the given PrintingPolicy"""
28992897
return _CXString.from_result(conf.lib.clang_getTypePrettyPrinted(self, policy))
29002898

2901-
def __eq__(self, other):
2902-
if not isinstance(other, Type):
2903-
return False
2904-
2905-
return conf.lib.clang_equalTypes(self, other) # type: ignore [no-any-return]
2899+
def __eq__(self, other: object) -> bool:
2900+
return isinstance(other, Type) and conf.lib.clang_equalTypes(self, other)
29062901

2907-
def __ne__(self, other):
2902+
def __ne__(self, other: object) -> bool:
29082903
return not self.__eq__(other)
29092904

29102905

0 commit comments

Comments
 (0)