diff --git a/example/example-arg-keywords-and-defaults.cpp b/example/example-arg-keywords-and-defaults.cpp index 4e620de5..9c58605f 100644 --- a/example/example-arg-keywords-and-defaults.cpp +++ b/example/example-arg-keywords-and-defaults.cpp @@ -40,8 +40,13 @@ void args_kwargs_function(py::args args, py::kwargs kwargs) { } } +struct KWClass { + void foo(int, float) {} +}; + void init_ex_arg_keywords_and_defaults(py::module &m) { - m.def("kw_func", &kw_func, py::arg("x"), py::arg("y")); + m.def("kw_func0", &kw_func); + m.def("kw_func1", &kw_func, py::arg("x"), py::arg("y")); m.def("kw_func2", &kw_func, py::arg("x") = 100, py::arg("y") = 200); m.def("kw_func3", [](const char *) { }, py::arg("data") = std::string("Hello world!")); @@ -59,4 +64,8 @@ void init_ex_arg_keywords_and_defaults(py::module &m) { using namespace py::literals; m.def("kw_func_udl", &kw_func, "x"_a, "y"_a=300); m.def("kw_func_udl_z", &kw_func, "x"_a, "y"_a=0); + + py::class_(m, "KWClass") + .def("foo0", &KWClass::foo) + .def("foo1", &KWClass::foo, "x"_a, "y"_a); } diff --git a/example/example-arg-keywords-and-defaults.py b/example/example-arg-keywords-and-defaults.py index 09ba13e6..2536782f 100755 --- a/example/example-arg-keywords-and-defaults.py +++ b/example/example-arg-keywords-and-defaults.py @@ -5,19 +5,26 @@ import pydoc sys.path.append('.') -from example import kw_func, kw_func2, kw_func3, kw_func4, call_kw_func +from example import kw_func0, kw_func1, kw_func2, kw_func3, kw_func4, call_kw_func from example import args_function, args_kwargs_function, kw_func_udl, kw_func_udl_z +from example import KWClass -print(pydoc.render_doc(kw_func, "Help on %s")) +print(pydoc.render_doc(kw_func0, "Help on %s")) +print(pydoc.render_doc(kw_func1, "Help on %s")) print(pydoc.render_doc(kw_func2, "Help on %s")) print(pydoc.render_doc(kw_func3, "Help on %s")) print(pydoc.render_doc(kw_func4, "Help on %s")) print(pydoc.render_doc(kw_func_udl, "Help on %s")) print(pydoc.render_doc(kw_func_udl_z, "Help on %s")) +print(pydoc.render_doc(args_function, "Help on %s")) +print(pydoc.render_doc(args_kwargs_function, "Help on %s")) -kw_func(5, 10) -kw_func(5, y=10) -kw_func(y=10, x=5) +print(KWClass.foo0.__doc__) +print(KWClass.foo1.__doc__) + +kw_func1(5, 10) +kw_func1(5, y=10) +kw_func1(y=10, x=5) kw_func2() diff --git a/example/example-arg-keywords-and-defaults.ref b/example/example-arg-keywords-and-defaults.ref index a693b6ce..68895743 100644 --- a/example/example-arg-keywords-and-defaults.ref +++ b/example/example-arg-keywords-and-defaults.ref @@ -1,32 +1,52 @@ -Help on built-in function kw_func in module example +Help on built-in function kw_func0 in module example -kkww__ffuunncc(...) - kw_func(x : int, y : int) -> NoneType +kkww__ffuunncc00(...) + kw_func0(arg0: int, arg1: int) -> NoneType + +Help on built-in function kw_func1 in module example + +kkww__ffuunncc11(...) + kw_func1(x: int, y: int) -> NoneType Help on built-in function kw_func2 in module example kkww__ffuunncc22(...) - kw_func2(x : int = 100L, y : int = 200L) -> NoneType + kw_func2(x: int=100L, y: int=200L) -> NoneType Help on built-in function kw_func3 in module example kkww__ffuunncc33(...) - kw_func3(data : unicode = u'Hello world!') -> NoneType + kw_func3(data: unicode=u'Hello world!') -> NoneType Help on built-in function kw_func4 in module example kkww__ffuunncc44(...) - kw_func4(myList : list = [13L, 17L]) -> NoneType + kw_func4(myList: list=[13L, 17L]) -> NoneType Help on built-in function kw_func_udl in module example kkww__ffuunncc__uuddll(...) - kw_func_udl(x : int, y : int = 300L) -> NoneType + kw_func_udl(x: int, y: int=300L) -> NoneType Help on built-in function kw_func_udl_z in module example kkww__ffuunncc__uuddll__zz(...) - kw_func_udl_z(x : int, y : int = 0L) -> NoneType + kw_func_udl_z(x: int, y: int=0L) -> NoneType + +Help on built-in function args_function in module example + +aarrggss__ffuunnccttiioonn(...) + args_function(*args) -> NoneType + +Help on built-in function args_kwargs_function in module example + +aarrggss__kkwwaarrggss__ffuunnccttiioonn(...) + args_kwargs_function(*args, **kwargs) -> NoneType + + +foo0(self: KWClass, arg0: int, arg1: float) -> NoneType +foo1(self: KWClass, x: int, y: float) -> NoneType + kw_func(x=5, y=10) kw_func(x=5, y=10) @@ -38,7 +58,7 @@ kw_func(x=100, y=10) kw_func(x=5, y=10) kw_func(x=5, y=10) Caught expected exception: Incompatible function arguments. The following argument types are supported: - 1. (x : int = 100L, y : int = 200L) -> NoneType + 1. (x: int=100L, y: int=200L) -> NoneType Invoked with: kw_func4: 13 17 kw_func4: 1 2 3 diff --git a/example/example-callbacks.ref b/example/example-callbacks.ref index c2e8eef5..d6ab75eb 100644 --- a/example/example-callbacks.ref +++ b/example/example-callbacks.ref @@ -6,7 +6,7 @@ Molly is a dog Molly is a dog Woof! The following error is expected: Incompatible function arguments. The following argument types are supported: - 1. (example.Dog) -> NoneType + 1. (arg0: example.Dog) -> NoneType Invoked with: Callback function 1 called! False diff --git a/example/issues.ref b/example/issues.ref index 0386d2c6..90d8ce17 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -6,10 +6,10 @@ Yay.. [3, 5, 7, 9, 11, 13, 15] 0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9, Failed as expected: Incompatible function arguments. The following argument types are supported: - 1. (example.issues.ElementA) -> NoneType + 1. (arg0: example.issues.ElementA) -> NoneType Invoked with: None Failed as expected: Incompatible function arguments. The following argument types are supported: - 1. (int) -> int + 1. (arg0: int) -> int Invoked with: 5.2 12.0 C++ version @@ -21,6 +21,6 @@ In python f() StrIssue.__str__ called StrIssue[3] Failed as expected: Incompatible constructor arguments. The following argument types are supported: - 1. example.issues.StrIssue(int) + 1. example.issues.StrIssue(arg0: int) 2. example.issues.StrIssue() Invoked with: no, such, constructor diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index bfb0f07a..26124ae9 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -157,7 +157,7 @@ protected: /// Register a function call with Python (generic non-templated code goes here) void initialize_generic(detail::function_record *rec, const char *text, - const std::type_info *const *types, int args) { + const std::type_info *const *types, size_t args) { /* Create copies of all referenced C-style strings */ rec->name = strdup(rec->name ? rec->name : ""); @@ -182,16 +182,23 @@ protected: break; if (c == '{') { - if (type_depth == 1 && arg_index < rec->args.size()) { - signature += rec->args[arg_index].name; - signature += " : "; + // Write arg name for everything except *args, **kwargs and return type. + if (type_depth == 1 && text[char_index] != '*' && arg_index < args) { + if (!rec->args.empty()) { + signature += rec->args[arg_index].name; + } else if (arg_index == 0 && rec->class_) { + signature += "self"; + } else { + signature += "arg" + std::to_string(arg_index - (rec->class_ ? 1 : 0)); + } + signature += ": "; } ++type_depth; } else if (c == '}') { --type_depth; - if (type_depth == 1 && arg_index < rec->args.size()) { - if (rec->args[arg_index].descr) { - signature += " = "; + if (type_depth == 1) { + if (arg_index < rec->args.size() && rec->args[arg_index].descr) { + signature += "="; signature += rec->args[arg_index].descr; } arg_index++; @@ -453,9 +460,9 @@ protected: bool wrote_sig = false; if (overloads->is_constructor) { - // For a constructor, rewrite `(Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` + // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` std::string sig = it2->signature; - size_t start = sig.find('(') + 1; + size_t start = sig.find('(') + 7; // skip "(self: " if (start < sig.size()) { // End at the , for the next argument size_t end = sig.find(", "), next = end + 2;