diff --git a/CHANGELOG.md b/CHANGELOG.md index bf53e25..6c0f27c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,5 @@ autowrap 0.22.11 + +- Fixes some issues with typing support on python side +- Added a real C++ bool converter. C++ bools in a pxd will now be real booleans + on python side. Not "just" ints and will also be typed like that. \ No newline at end of file diff --git a/autowrap/CodeGenerator.py b/autowrap/CodeGenerator.py index 0259ebf..b0c6552 100644 --- a/autowrap/CodeGenerator.py +++ b/autowrap/CodeGenerator.py @@ -383,7 +383,8 @@ def create_for( pxd_code += c.render() pxd_code += " \n" - pyi_code = "from typing import overload, Any, List, Dict, Tuple, Set, Sequence, Union \n\n" + pyi_code = "from __future__ import annotations\n" + pyi_code += "from typing import overload, Any, List, Dict, Tuple, Set, Sequence, Union\n\n" pyi_code += "from enum import Enum as _PyEnum\n\n" pyi_code += "\n".join(ci.render() for ci in self.top_level_typestub_code) pyi_code += "\n\n" @@ -910,8 +911,6 @@ def _create_overloaded_method_decl( docstrings = Code() signatures = [] for method in methods: - ## TODO refactor this part as something like getTypingSignature or getTypingSignatureParts - ## or maybe save them for the after-the-next for-loop that generates them again args = augment_arg_names(method) py_typing_signature_parts = [] for arg_num, (t, n) in enumerate(args): @@ -931,9 +930,6 @@ def _create_overloaded_method_decl( # Add autodoc docstring signatures first: https://github.com/sphinx-doc/sphinx/pull/7748 sig = f"{py_name}(self, {args_typestub_str}) {return_type}" signatures.append(sig) - #docstrings.add(sig) - - #docstrings.add("") for method, sig in zip(methods, signatures): docstrings.add(".. rubric:: Overload:") diff --git a/autowrap/ConversionProvider.py b/autowrap/ConversionProvider.py index 54cf806..a5ed5a3 100644 --- a/autowrap/ConversionProvider.py +++ b/autowrap/ConversionProvider.py @@ -215,6 +215,7 @@ class IntegerConverter(TypeConverterBase): """ wraps long and int. "long" base_type is converted to "int" by the cython parser! + TODO Long does not exist in Python2 anymore. Can we remove stuff? """ def get_base_types(self) -> List[str]: @@ -235,7 +236,7 @@ def matches(self, cpp_type: CppType) -> bool: return not cpp_type.is_ptr def matching_python_type(self, cpp_type: CppType) -> str: - return "" + return "" # TODO can't we use int? Especially in py3 only. def matching_python_type_full(self, cpp_type: CppType) -> str: return "int" @@ -417,11 +418,12 @@ def matching_python_type(self, cpp_type: CppType) -> str: return "" def matching_python_type_full(self, cpp_type: CppType) -> str: - if self.enum.cpp_decl.annotations.get("wrap-attach"): - if not self.enum.scoped: - return "__" + self.enum.name - else: - return "_Py" + self.enum.name + if not self.enum.scoped: + # TODO add some other hint that this must be an + # int from the class "__" + self.enum.name + return "int" + elif self.enum.cpp_decl.annotations.get("wrap-attach"): + return "_Py" + self.enum.name else: return self.enum.name @@ -2024,6 +2026,15 @@ def output_conversion( class StdStringConverter(TypeConverterBase): + """ + This converter deals with functions that expect/return a C++ std::string. + It expects and returns bytes on the python side. + Note that this provider will NOT be picked up if it is located inside + a container (e.g. std::vector aka libcpp_vector). However, it can and + should be used to indicate the correct typing for the automatic + conversion by Cython, which is set to bytes in autowrap. + """ + def get_base_types(self) -> List[str]: return ["libcpp_string"] @@ -2053,20 +2064,35 @@ def output_conversion( return "%s = %s" % (output_py_var, input_cpp_var) +# TODO I think we have to be more clear about the use case of this ConvProv +# Currently it can be used if you don't know if the incoming +# py type is bytes or unicode. We currently have no provider that allows +# for specifically unicode only. class StdStringUnicodeConverter(StdStringConverter): + """ + This converter deals with functions that expect a C++ std::string. + Note that this provider will NOT be picked up if it is located inside + a container (e.g. std::vector aka libcpp_vector). Please use the usual + StdStringConverter to at least get the typing right. + It can only be used in function parameters (i.e. input). + It can handle both bytes and unicode strings and converts to bytes internally. + """ + def get_base_types(self) -> List[str]: return ["libcpp_utf8_string"] def matching_python_type(self, cpp_type: CppType) -> str: - return "" + return "" # TODO can we use "basestring"? def matching_python_type_full(self, cpp_type: CppType) -> str: - return "Union[bytes, unicode]" + return "Union[bytes, str]" def input_conversion( self, cpp_type: CppType, argument_var: str, arg_num: int ) -> Tuple[Code, str, str]: code = Code() + # although python3 does not have "unicode" as a built-in type anymore, + # Cython understands it and uses the Py_IsUnicodeCheck code.add( """ |if isinstance($argument_var, unicode): @@ -2079,13 +2105,26 @@ def input_conversion( return code, call_as, cleanup def type_check_expression(self, cpp_type: CppType, argument_var: str) -> str: - return "isinstance(%s, (bytes, unicode))" % argument_var + return "isinstance(%s, (bytes, str))" % argument_var class StdStringUnicodeOutputConverter(StdStringUnicodeConverter): + """ + This converter deals with functions that return a C++ std::string. + Note that this provider will NOT be picked up if it is located inside + a container (e.g. std::vector aka libcpp_vector). Please use the usual + StdStringConverter to at least get the typing right. + It should only be used in function returns (i.e. output). + It returns unicode strings to python and therefore expects the C++ + function to return something that is decodable from utf8 (including ascii) + """ + def get_base_types(self) -> List[str]: return ["libcpp_utf8_output_string"] + def matching_python_type_full(self, cpp_type: CppType) -> str: + return "str" # python3 + def output_conversion( self, cpp_type: CppType, input_cpp_var: str, output_py_var: str ) -> Optional[str]: