MCPcopy Create free account
hub / github.com/pybind/pybind11 / generate_function_signature

Function generate_function_signature

include/pybind11/pybind11.h:111–237  ·  view source on GitHub ↗

Generate a proper function signature */

Source from the content-addressed store, hash-verified

109
110/* Generate a proper function signature */
111inline std::string generate_function_signature(const char *type_caster_name_field,
112 detail::function_record *func_rec,
113 const std::type_info *const *types,
114 size_t &type_index,
115 size_t &arg_index) {
116 std::string signature;
117 bool is_starred = false;
118 // `is_return_value.top()` is true if we are currently inside the return type of the
119 // signature. Using `@^`/`@$` we can force types to be arg/return types while `@!` pops
120 // back to the previous state.
121 std::stack<bool> is_return_value({false});
122 // The following characters have special meaning in the signature parsing. Literals
123 // containing these are escaped with `!`.
124 std::string special_chars("!@%{}-");
125 for (const auto *pc = type_caster_name_field; *pc != '\0'; ++pc) {
126 const auto c = *pc;
127 if (c == '{') {
128 // Write arg name for everything except *args and **kwargs.
129 // Detect {@*args...} or {@**kwargs...}
130 is_starred = *(pc + 1) == '@' && *(pc + 2) == '*';
131 if (is_starred) {
132 continue;
133 }
134 // Separator for keyword-only arguments, placed before the kw
135 // arguments start (unless we are already putting an *args)
136 if (!func_rec->has_args && arg_index == func_rec->nargs_pos) {
137 signature += "*, ";
138 }
139 if (arg_index < func_rec->args.size() && func_rec->args[arg_index].name) {
140 signature += func_rec->args[arg_index].name;
141 } else if (arg_index == 0 && func_rec->is_method) {
142 signature += "self";
143 } else {
144 signature += "arg" + std::to_string(arg_index - (func_rec->is_method ? 1 : 0));
145 }
146 signature += ": ";
147 } else if (c == '}') {
148 // Write default value if available.
149 if (!is_starred && arg_index < func_rec->args.size()
150 && func_rec->args[arg_index].descr) {
151 signature += " = ";
152 signature += detail::replace_newlines_and_squash(func_rec->args[arg_index].descr);
153 }
154 // Separator for positional-only arguments (placed after the
155 // argument, rather than before like *
156 if (func_rec->nargs_pos_only > 0 && (arg_index + 1) == func_rec->nargs_pos_only) {
157 signature += ", /";
158 }
159 if (!is_starred) {
160 arg_index++;
161 }
162 } else if (c == '%') {
163 const std::type_info *t = types[type_index++];
164 if (!t) {
165 pybind11_fail("Internal error while parsing type signature (1)");
166 }
167 if (auto *tinfo = detail::get_type_info(*t)) {
168 handle th(reinterpret_cast<PyObject *>(tinfo->type));

Callers 2

generate_type_signatureFunction · 0.85
initialize_genericMethod · 0.85

Calls 8

quote_cpp_type_nameFunction · 0.85
clean_type_idFunction · 0.85
attrMethod · 0.80
findMethod · 0.80
sizeMethod · 0.45
nameMethod · 0.45

Tested by

no test coverage detected