_pybind_default_value_rx = re.compile('[^,)]+')
def parse_pybind_type(state: State, referrer_path: List[str], signature: str) -> str:
- input_type = _pybind_type_rx.match(signature).group(0)
- signature = signature[len(input_type):]
- type = map_name_prefix(state, input_type)
- type_link = make_name_link(state, referrer_path, type)
+ # If this doesn't match, it's because we're in Callable[[arg, ...], retval]
+ match = _pybind_type_rx.match(signature)
+ if match:
+ input_type = match.group(0)
+ signature = signature[len(input_type):]
+ type = map_name_prefix(state, input_type)
+ type_link = make_name_link(state, referrer_path, type)
+ else:
+ assert signature[0] == '['
+ type = ''
+ type_link = ''
+
+ # This is a generic type (or the list in Callable)
if signature and signature[0] == '[':
type += '['
type_link += '['
+#include <functional>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> /* needed for std::vector! */
+#include <pybind11/functional.h> /* for std::function */
namespace py = pybind11;
std::string overloaded(int) { return {}; }
bool overloaded(float) { return {}; }
+// Doesn't work with just a plain function pointer, MEH
+void takesAFunction(std::function<int(float, std::vector<float>&)>) {}
+
struct MyClass {
static MyClass staticFunction(int, float) { return {}; }
.def("overloaded", static_cast<std::string(*)(int)>(&overloaded), "Overloaded for ints")
.def("overloaded", static_cast<bool(*)(float)>(&overloaded), "Overloaded for floats")
.def("duck", &duck, "A function taking args/kwargs directly")
+ .def("takes_a_function", &takesAFunction, "A function taking a Callable")
.def("tenOverloads", &tenOverloads<float, float>, "Ten overloads of a function")
.def("tenOverloads", &tenOverloads<int, float>, "Ten overloads of a function")
argument: float) -> int</span>
</dt>
<dd>Scale an integer, kwargs</dd>
+ <dt>
+ <span class="m-doc-wrap-bumper">def <a href="#takes_a_function-b0069" class="m-doc-self" id="takes_a_function-b0069">takes_a_function</a>(</span><span class="m-doc-wrap">arg0: Callable[[float, List[float]], int]<span class="m-text m-dim">, /</span>)</span>
+ </dt>
+ <dd>A function taking a Callable</dd>
<dt>
<span class="m-doc-wrap-bumper">def <a href="#taking_a_list_returning_a_tuple-54d79" class="m-doc-self" id="taking_a_list_returning_a_tuple-54d79">taking_a_list_returning_a_tuple</a>(</span><span class="m-doc-wrap">arg0: List[float]<span class="m-text m-dim">, /</span>) -> Tuple[int, int, int]</span>
</dt>
('another', 'float', 'float', None),
], 'Union[str, Any]'))
+ def test_callable(self):
+ self.assertEqual(parse_pybind_signature(State({}), [],
+ 'foo(a: Callable[[int, Tuple[int, int]], float], another: float)'),
+ ('foo', '', [
+ ('a', 'Callable[[int, Tuple[int, int]], float]', 'Callable[[int, Tuple[int, int]], float]', None),
+ ('another', 'float', 'float', None),
+ ], None))
+
def test_kwargs(self):
self.assertEqual(parse_pybind_signature(State({}), [],
'foo(*args, **kwargs)'),