/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Examples/test-suite/python/python_annotations_typing_runme.py
307 строк
12 KB
William S Fulton
[Python] Check annotations in .pyi stubs with -builtin and -fastproxy
05 авг 2026, 01:41
05 авг 2026, 01:41
7a137da
Код
Авторство
О чём код?
from swig_test_utils import swig_annotations_in_stub, swig_assert, swig_check, swig_get_annotations from python_annotations_typing import * # Annotations are only added to the runtime objects for the default proxy classes, # but with -pyi they are always available in the generated .pyi stub file annotations_supported = swig_annotations_in_stub() or not(is_python_builtin() or is_python_fastproxy()) def get_annotations(obj): return swig_get_annotations(obj, "python_annotations_typing", is_python_fastproxy()) if annotations_supported: anno = get_annotations(global_ints) if anno != { "ri": "SWIGTYPE_p_int", "t": "TemplateShort", "return": "typing.Optional[SWIGTYPE_p_int]", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(global_overloaded) if anno != {"return": "typing.Optional[SWIGTYPE_p_int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) ts = MakeShort(10) anno = get_annotations(MakeShort) if anno != {"x": "int", "return": "TemplateShort"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(ts.mymethod) if anno != { "arg2": "int", "tt": "typing.Optional[TemplateShort]", "return": "None", }: raise RuntimeError("annotations mismatch: {}".format(anno)) # No annotations anno = get_annotations(no_annotations) if anno != {}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(take_argv) if anno != {"argc": "typing.List[str]", "return": "None"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(take_argv_surround) if anno != { "before": "float", "argc": "typing.List[str]", "after": "int", "return": "None", }: raise RuntimeError("annotations mismatch: {}".format(anno)) def make_argcheck(exp, args): d = {arg: exp for arg in args} d["return"] = "None" return d anno = get_annotations(argcheck_bool) if anno != make_argcheck("bool", ["a_bool", "a_bool_cref"]): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_char) if anno != make_argcheck("str", ["a_char", "a_wchar", "a_char_cref"]): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_int) if anno != make_argcheck( "int", [ "a_schar", "a_uchar", "a_short", "a_ushort", "a_int", "a_uint", "a_long", "a_ulong", "a_llong", "a_ullong", "a_size", "a_stdsize", "a_ptrdiff", "a_stdptrdiff", "a_short_cref", "a_int_cref", "a_size_cref", "a_stdsize_cref", "a_ptrdiff_cref", "a_stdptrdiff_cref", ], ): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_float) if anno != make_argcheck("float", ["a_float", "a_double", "a_double_cref"]): raise RuntimeError("annotations mismatch: {}".format(anno)) # long double has no in/out typemaps of its own, so it is wrapped as a pointer anno = get_annotations(argcheck_long_double) if anno != make_argcheck( "SWIGTYPE_p_long_double", ["a_ldouble", "a_ldouble_cref"] ): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_complex) if anno != make_argcheck( "complex", ["a_cfloat", "a_cdouble", "a_cdouble_cref"] ): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_str) if anno != { "a_cstr": "typing.Optional[str]", "a_wcstr": "typing.Optional[str]", "a_stdstr": "str", "a_stdwstr": "str", "a_stdstr_cref": "str", "return": "None", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_fnptr) if anno != make_argcheck("typing.Optional[SWIGTYPE_p_f_char_bool__int]", ["f"]): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(argcheck_array) if anno != make_argcheck("typing.Optional[SWIGTYPE_p_float]", ["arr"]): raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(optional_square) if anno != {"return": "typing.Optional[int]", "i": "typing.Optional[int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(optional_square(None) is None) swig_assert(optional_square(3) == 9) anno = get_annotations(docs_do_something_out_type) if anno != {"return": "int", "t": "typing.Union[int, float]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) my_struct = MyStruct() anno = get_annotations(my_struct.do_something) if anno != { "return": "None", "ref": "MyStruct", "ptr": "typing.Optional[MyStruct]", "cref": "MyStruct", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(use_typedefs) if anno != { "return": "None", "i": "int", "mt": "int", "cref_mst": "MyStruct", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(use_memberfn_ptr) if anno != { "return": "None", "ptr": "typing.Optional[SWIGTYPE_m_MyStruct__f_r_MyStruct_p_MyStruct_r_q_const__MyStruct__void]", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(use_member_ptr) if anno != { "return": "None", "ptr": "typing.Optional[SWIGTYPE_m_OptionalInt__int]", }: raise RuntimeError("annotations mismatch: {}".format(anno)) # $*pytypename removes one pointer level: MyStruct ** -> MyStruct proxy name. anno = get_annotations(use_deref) if anno != {"return": "None", "pp": "typing.Optional[MyStruct]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(use_enums) if anno != { "return": "None", "me": "bool", "met": "bool", "moe": "int", "moet": "int", }: raise RuntimeError("annotations mismatch: {}".format(anno)) # A pytyping typemap using $pytypename should expand to int. anno = get_annotations(use_pytypename_enum) if anno != {"return": "None", "e": "typing.Optional[int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(use_namespaced) if anno != { "return": "None", "ns1": "MyNamespaced1", "inner1": "MyInner", "inner_ns1": "typing.Optional[MyNamespaced2]", }: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(wrap_ptr) if anno != {"return": "typing.Optional[SWIGTYPE_p_void]", "val": "int"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(unwrap_ptr) if anno != {"ptr": "typing.Optional[SWIGTYPE_p_void]", "return": "int"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(make_short_ref) if anno != {"return": "SWIGTYPE_p_short"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(make_short_cref) if anno != {"return": "int"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(make_struct_ref) if anno != {"return": "MyStruct"}: raise RuntimeError("annotations mismatch: {}".format(anno)) anno = get_annotations(make_struct_cref) if anno != {"return": "MyStruct"}: raise RuntimeError("annotations mismatch: {}".format(anno)) # Class-typed member variables are wrapped as annotated properties. anno = get_annotations(HasClassMembers) if anno != {"member_value": "MyStruct", "member_pointer": "typing.Optional[MyStruct]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) # A forward-declared-only class has no proxy, so $pytypename falls back # to an opaque type wrapper class. anno = get_annotations(use_forward_only) if anno != {"return": "None", "fp": "typing.Optional[SWIGTYPE_p_ForwardOnly]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) import python_annotations_typing # A class-typed %constant is annotated at module level. if get_annotations(python_annotations_typing).get("CONST_STRUCT") != "typing.Optional[MyStruct]": raise RuntimeError("annotations mismatch: {}".format(get_annotations(python_annotations_typing))) # The type wrapper classes referenced by the annotations above (the # SWIGTYPE_* opaque types) are declared only for static type checkers # under 'if typing.TYPE_CHECKING' and must not exist at runtime. for name in [ "SWIGTYPE_p_void", "SWIGTYPE_p_int", "SWIGTYPE_p_short", "SWIGTYPE_p_float", "SWIGTYPE_p_f_char_bool__int", "SWIGTYPE_p_ForwardOnly", ]: swig_assert(not hasattr(python_annotations_typing, name)) anno = get_annotations(argoutVoidSingleAppend) if anno != {"arg": "bool", "return": "int"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(isinstance(argoutVoidSingleAppend(True), int)) anno = get_annotations(argoutBoolSingleAppend) if anno != {"arg": "bool", "return": "typing.List[typing.Union[bool, int]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(isinstance(argoutBoolSingleAppend(True), list)) anno = get_annotations(argoutVoidAppendTwice) if anno != {"arg": "bool", "return": "typing.List[typing.Union[int, int]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(isinstance(argoutVoidAppendTwice(True), list)) anno = get_annotations(argoutBoolAppendTwice) if anno != {"arg": "bool", "return": "typing.List[typing.Union[bool, int, int]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(isinstance(argoutBoolAppendTwice(True), list)) anno = get_annotations(argoutMultiarg) if anno != {"return": "typing.List[int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_assert(isinstance(argoutMultiarg(), list)) anno = get_annotations(argoutBoolMultiarg) if anno != {"arg": "bool", "return": "typing.List[typing.Union[bool, typing.List[int]]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_check(argoutBoolMultiarg(True), [True, []]) anno = get_annotations(argoutMultiargAfterFirst) if anno != {"first": "int", "return": "typing.List[int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_check(argoutMultiargAfterFirst(1), []) anno = get_annotations(argoutBoolMultiargAfterFirst) if anno != {"first": "int", "return": "typing.List[typing.Union[bool, typing.List[int]]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_check(argoutBoolMultiargAfterFirst(2), [True, []]) anno = get_annotations(argoutMultiargBetweenFirstLast) if anno != {"first": "int", "last": "float", "return": "typing.List[int]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_check(argoutMultiargBetweenFirstLast(3, 4.0), []) anno = get_annotations(argoutBoolMultiargBetweenFirstLast) if anno != {"first": "int", "last": "float", "return": "typing.List[typing.Union[bool, typing.List[int]]]"}: raise RuntimeError("annotations mismatch: {}".format(anno)) swig_check(argoutBoolMultiargBetweenFirstLast(5, 6.0), [True, []])