From 0aef6422a349e498410c4a06b9decc04addd8c25 Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Thu, 31 Aug 2017 14:38:23 +0200 Subject: [PATCH] Simplify function signature annotation and parsing `type_descr` is now applied only to the final signature so that it only marks the argument types, but not nested types (e.g. for tuples) or return types. --- include/pybind11/cast.h | 14 +++++------ include/pybind11/detail/init.h | 2 +- include/pybind11/eigen.h | 5 ++-- include/pybind11/functional.h | 2 +- include/pybind11/pybind11.h | 44 ++++++++++++++++------------------ 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 8c9493a6..16a399ea 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -778,7 +778,7 @@ template struct is_copy_constructible class type_caster_base : public type_caster_generic { using itype = intrinsic_t; public: - static constexpr auto name = type_descr(_()); + static constexpr auto name = _(); type_caster_base() : type_caster_base(typeid(type)) { } explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { } @@ -900,7 +900,7 @@ public: protected: \ type value; \ public: \ - static constexpr auto name = type_descr(py_name); \ + static constexpr auto name = py_name; \ template >::value, int> = 0> \ static handle cast(T_ *src, return_value_policy policy, handle parent) { \ if (!src) return none().release(); \ @@ -1049,7 +1049,7 @@ public: template using cast_op_type = void*&; operator void *&() { return value; } - static constexpr auto name = type_descr(_("capsule")); + static constexpr auto name = _("capsule"); private: void *value = nullptr; }; @@ -1289,7 +1289,7 @@ public: return value[0]; } - static constexpr auto name = type_descr(_(PYBIND11_STRING_NAME)); + static constexpr auto name = _(PYBIND11_STRING_NAME); template using cast_op_type = remove_reference_t>; }; @@ -1314,9 +1314,7 @@ public: return cast_impl(std::forward(src), policy, parent, indices{}); } - static constexpr auto name = type_descr( - _("Tuple[") + detail::concat(make_caster::name...) + _("]") - ); + static constexpr auto name = _("Tuple[") + concat(make_caster::name...) + _("]"); template using cast_op_type = type; @@ -1826,7 +1824,7 @@ public: static constexpr bool has_kwargs = kwargs_pos < 0; static constexpr bool has_args = args_pos < 0; - static constexpr auto arg_names = detail::concat(make_caster::name...); + static constexpr auto arg_names = concat(type_descr(make_caster::name)...); bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index ded32114..3238256c 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -24,7 +24,7 @@ public: template using cast_op_type = value_and_holder &; operator value_and_holder &() { return *value; } - static constexpr auto name = type_descr(_()); + static constexpr auto name = _(); private: value_and_holder *value = nullptr; diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index 9d9a23ea..8190246b 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -185,7 +185,7 @@ template struct EigenProps { static constexpr bool show_c_contiguous = show_order && requires_row_major; static constexpr bool show_f_contiguous = !show_c_contiguous && show_order && requires_col_major; - static constexpr auto descriptor = type_descr( + static constexpr auto descriptor = _("numpy.ndarray[") + npy_format_descriptor::name + _("[") + _(_<(size_t) rows>(), _("m")) + _(", ") + _(_<(size_t) cols>(), _("n")) + @@ -199,8 +199,7 @@ template struct EigenProps { _(", flags.writeable", "") + _(", flags.c_contiguous", "") + _(", flags.f_contiguous", "") + - _("]") - ); + _("]"); }; // Casts an Eigen type to numpy array. If given a base, the numpy array references the src data, diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index 8c88c353..9cdf21f7 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -75,7 +75,7 @@ public: return cpp_function(std::forward(f_), policy).release(); } - PYBIND11_TYPE_CASTER(type, _("Callable[[") + argument_loader::arg_names + _("], ") + PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") + make_caster::name + _("]")); }; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 90e12c56..59af0229 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -217,34 +217,30 @@ protected: /* Generate a proper function signature */ std::string signature; - size_t type_depth = 0, char_index = 0, type_index = 0, arg_index = 0; - while (true) { - char c = text[char_index++]; - if (c == '\0') - break; + size_t type_index = 0, arg_index = 0; + for (auto *pc = text; *pc != '\0'; ++pc) { + const auto c = *pc; if (c == '{') { - // Write arg name for everything except *args, **kwargs and return type. - if (type_depth == 0 && text[char_index] != '*' && arg_index < args) { - if (!rec->args.empty() && rec->args[arg_index].name) { - signature += rec->args[arg_index].name; - } else if (arg_index == 0 && rec->is_method) { - signature += "self"; - } else { - signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); - } - signature += ": "; + // Write arg name for everything except *args and **kwargs. + if (*(pc + 1) == '*') + continue; + + if (arg_index < rec->args.size() && rec->args[arg_index].name) { + signature += rec->args[arg_index].name; + } else if (arg_index == 0 && rec->is_method) { + signature += "self"; + } else { + signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); } - ++type_depth; + signature += ": "; } else if (c == '}') { - --type_depth; - if (type_depth == 0) { - if (arg_index < rec->args.size() && rec->args[arg_index].descr) { - signature += "="; - signature += rec->args[arg_index].descr; - } - arg_index++; + // Write default value if available. + if (arg_index < rec->args.size() && rec->args[arg_index].descr) { + signature += "="; + signature += rec->args[arg_index].descr; } + arg_index++; } else if (c == '%') { const std::type_info *t = types[type_index++]; if (!t) @@ -272,7 +268,7 @@ protected: signature += c; } } - if (type_depth != 0 || types[type_index] != nullptr) + if (arg_index != args || types[type_index] != nullptr) pybind11_fail("Internal error while parsing type signature (2)"); #if PY_MAJOR_VERSION < 3