/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Examples/test-suite/python_annotations_typing.i
348 строк
9 KB
Nerixyz
[Python] Support multi-argument argout typing
05 авг 2026, 01:41
05 авг 2026, 01:41
5b13fbf
Код
Авторство
О чём код?
%module python_annotations_typing %include <std_string.i> %include <std_wstring.i> %include <std_complex.i> // Tests the typing annotations %feature("python:annotations", "typing"); // The default library 'pytyping' typemaps annotate wrapped C/C++ types as typing.Any. // Opt this test module in to proxy-name annotations by defining the SWIGTYPE 'pytyping' // typemaps explicitly, which exercises the $pytypename and $&pytypename special variables. %typemap(pytyping) SWIGTYPE "$&pytypename"; %typemap(pytyping) SWIGTYPE [] "typing.Optional[$pytypename]"; %typemap(pytyping) SWIGTYPE * "typing.Optional[$pytypename]"; %typemap(pytyping) SWIGTYPE & "$pytypename"; %typemap(pytyping) SWIGTYPE && "$pytypename"; %typemap(pytyping) enum SWIGTYPE "int"; // Exercise $*pytypename, which removes one pointer level: for a MyStruct ** argument it // yields the MyStruct proxy name. %typemap(pytyping) MyStruct ** "typing.Optional[$*pytypename]"; %feature("python:annotations", "0") no_annotations; %typemap(pytyping) OptionalInt "typing.Optional[int]"; %typemap(pytyping, out = "$typemap(pytyping, short)") MyType "typing.Union[int, float]"; %typemap(in) OptionalInt { $1 = $input == Py_None ? OptionalInt() : OptionalInt(PyLong_AsLong($input)); } %typemap(out) OptionalInt { $result = $1.has_value ? PyLong_FromLong($1.value) : Py_None; } // Test that a changed type for MyEnum will be picked up correctly. %typemap(pytyping) MyEnum "bool"; %rename(MyNamespaced2) MyNamespace::Inner::MyNamespaced1; // Test a typemap using $pytypename for an enum - it should expand to "int" as Python wraps enums as ints. %typemap(pytyping) PytypenameEnum "typing.Optional[$pytypename]"; %inline %{ namespace Space { template<class T> struct Template { void mymethod(int, Template* tt) {} }; } template<typename T> Space::Template<T> makeT(int x) { return Space::Template<T>(); } int *global_ints(int &ri, Space::Template<short> t) { return &ri; } int *global_overloaded(int &ri) { return &ri; } int *global_overloaded() { return NULL; } int *no_annotations(int &ri, const char *c) { return NULL; } %} %template(TemplateShort) Space::Template<short>; %template(MakeShort) makeT<short>; %inline %{ #ifdef SWIGPYTHON_BUILTIN int is_python_builtin() { return 1; } #else int is_python_builtin() { return 0; } #endif #if defined SWIGPYTHON_FASTPROXY int is_python_fastproxy() { return 1; } #else int is_python_fastproxy() { return 0; } #endif %} %typemap(in) (int argc, char **argv) { /* Check if is a list */ if (PyList_Check($input)) { int i; $1 = (int)PyList_Size($input); $2 = (char **)malloc(($1+1)*sizeof(char *)); for (i = 0; i < $1; i++) { PyObject *o = PyList_GetItem($input, i); if (PyBytes_Check(o)) { $2[i] = PyBytes_AsString(PyList_GetItem($input, i)); } else { PyErr_SetString(PyExc_TypeError, "list must contain strings"); SWIG_fail; } } $2[i] = 0; } else { PyErr_SetString(PyExc_TypeError, "not a list"); SWIG_fail; } } %typemap(freearg) (int argc, char **argv) { free((char *) $2); } %typemap(pytyping) (int argc, char **argv) "typing.List[str]" %typemap(in, numinputs=0) short *OutAppend (short temp) { $1 = &temp; } %typemap(argout) (short *OutAppend) { $result = SWIG_AppendOutput($result, PyLong_FromLong(*$1)); } %typemap(pytyping) short *OutAppend "int" %apply short *OutAppend { short *OutAppend2 }; %typemap(in, numinputs=0) (short **short_list)(short*temp) { $1 = &temp; } %typemap(in, numinputs=0) (size_t *short_list_len)(size_t temp) { $1 = &temp; } %typemap(freearg) (short **short_list) { free(*$1); } %typemap(argout) (short **short_list, size_t *short_list_len) { PyObject *list = PyList_New(*$2); for (size_t i = 0; i < *$2; i++) PyList_SetItem(list, i, PyLong_FromLong((*$1)[i])); $result = SWIG_AppendOutput($result, list); } %typemap(pytyping) (short **short_list, size_t *short_list_len) "typing.List[int]" %inline %{ #include <cstddef> void take_argv(int argc, char **argv) {} void take_argv_surround(double before, int argc, char **argv, short after) {} void argcheck_bool( bool a_bool, const bool &a_bool_cref ) {} void argcheck_char( char a_char, wchar_t a_wchar, const char &a_char_cref ) {} void argcheck_int( signed char a_schar, unsigned char a_uchar, short a_short, unsigned short a_ushort, int a_int, unsigned int a_uint, long a_long, unsigned long a_ulong, long long a_llong, unsigned long long a_ullong, size_t a_size, std::size_t a_stdsize, ptrdiff_t a_ptrdiff, std::ptrdiff_t a_stdptrdiff, const short &a_short_cref, const int &a_int_cref, const size_t &a_size_cref, const std::size_t &a_stdsize_cref, const ptrdiff_t &a_ptrdiff_cref, const std::ptrdiff_t &a_stdptrdiff_cref ) {} void argcheck_float( float a_float, double a_double, const double &a_double_cref ) {} /* long double has no in/out typemaps of its own, so it is wrapped as a pointer to an opaque type and a Python float is not accepted. Both forms must stay typing.Any. */ void argcheck_long_double( long double a_ldouble, const long double &a_ldouble_cref ) {} void argcheck_complex( std::complex<float> a_cfloat, std::complex<double> a_cdouble, const std::complex<double> &a_cdouble_cref ) {} void argcheck_str( const char* a_cstr, const wchar_t *a_wcstr, std::string a_stdstr, std::wstring a_stdwstr, const std::string &a_stdstr_cref ) {} void argcheck_fnptr(int(*f)(char, bool)) {} void argcheck_array(float arr[3]) {} struct OptionalInt { OptionalInt() : has_value(false) {} OptionalInt(int i) : has_value(true), value(i) {} bool has_value; int value; }; OptionalInt optional_square(OptionalInt i) { if (i.has_value) return OptionalInt(i.value * i.value); return OptionalInt(); } struct MyType {}; MyType docs_do_something_out_type(MyType t) { return MyType(); } struct MyStruct { void do_something(MyStruct& ref, MyStruct* ptr, const MyStruct& cref) {} }; typedef int MyTypedef; typedef MyStruct MyStructTypedef; void use_typedefs(int i, MyTypedef mt, const MyStructTypedef &cref_mst) {} void use_memberfn_ptr(void (MyStruct::* ptr)(MyStruct&, MyStruct*, const MyStruct&)) {} void use_member_ptr(int OptionalInt::*ptr) {} void use_deref(MyStruct **pp) {} enum MyEnum { MyEnumMember1, MyEnumMember2, MyEnumMember3, }; typedef MyEnum MyEnumTypedef; enum MyOtherEnum { MyOtherEnumMember1, MyOtherEnumMember2, }; typedef MyOtherEnum MyOtherEnumTypedef; void use_enums(MyEnum me, MyEnumTypedef met, MyOtherEnum moe, MyOtherEnumTypedef moet) {} enum PytypenameEnum { PytypenameEnumMember1, }; void use_pytypename_enum(PytypenameEnum e) {} namespace MyNamespace { struct MyNamespaced1 { int foo; }; namespace Inner { struct MyInner { int bar; }; struct MyNamespaced1 { int baz; }; } } void use_namespaced(MyNamespace::MyNamespaced1 ns1, const MyNamespace::Inner::MyInner &inner1, MyNamespace::Inner::MyNamespaced1 *inner_ns1) {} void *wrap_ptr(size_t val) { return (void *)val; } size_t unwrap_ptr(void *ptr) { return (size_t)ptr; } short &make_short_ref() { static short v = 1; return v; } const short &make_short_cref() { static short v = 1; return v; } MyStruct &make_struct_ref() { static MyStruct v; return v; } const MyStruct &make_struct_cref() { static MyStruct v; return v; } struct HasClassMembers { MyStruct member_value; MyStruct *member_pointer; }; // Forward-declared only: no proxy class, so $pytypename falls back to an opaque // SWIGTYPE_ type wrapper class. struct ForwardOnly; void use_forward_only(ForwardOnly *fp) { (void)fp; } void argoutVoidSingleAppend(bool arg, short *OutAppend) { *OutAppend = 42; } bool argoutBoolSingleAppend(bool arg, short *OutAppend) { *OutAppend = 42; return arg; } void argoutVoidAppendTwice(bool arg, short *OutAppend, short *OutAppend2) { *OutAppend = 42; *OutAppend2 = 43; } bool argoutBoolAppendTwice(bool arg, short *OutAppend, short *OutAppend2) { *OutAppend = 42; *OutAppend2 = 43; return arg; } void argoutMultiarg(short **short_list, size_t *short_list_len) { *short_list = NULL; *short_list_len = 0; } bool argoutBoolMultiarg(bool arg, short **short_list, size_t *short_list_len) { *short_list = NULL; *short_list_len = 0; return arg; } void argoutMultiargAfterFirst(int first, short **short_list, size_t *short_list_len) { (void)first; *short_list = NULL; *short_list_len = 0; } bool argoutBoolMultiargAfterFirst(int first, short **short_list, size_t *short_list_len) { *short_list = NULL; *short_list_len = 0; return first != 0; } void argoutMultiargBetweenFirstLast(int first, short **short_list, size_t *short_list_len, double last) { (void)first; (void)last; *short_list = NULL; *short_list_len = 0; } bool argoutBoolMultiargBetweenFirstLast(int first, short **short_list, size_t *short_list_len, double last) { *short_list = NULL; *short_list_len = 0; return first != 0 && last != 0.0; } %} // A class-typed %constant is annotated at module level. %constant MyStruct *CONST_STRUCT = 0;