diff --git a/example/eigen.py b/example/eigen.py index 5f7ec5141..18c8a453b 100644 --- a/example/eigen.py +++ b/example/eigen.py @@ -106,3 +106,9 @@ for i in range(4): print("symmetric_lower %s" % ("OK" if (symmetric_lower(asymm) == symm_lower).all() else "FAILED")) print("symmetric_upper %s" % ("OK" if (symmetric_upper(asymm) == symm_upper).all() else "FAILED")) + +print(double_col.__doc__) +print(double_row.__doc__) +print(double_mat_rm.__doc__) +print(sparse_passthrough_r.__doc__) +print(sparse_passthrough_c.__doc__) diff --git a/example/eigen.ref b/example/eigen.ref index 755012f43..626c60485 100644 --- a/example/eigen.ref +++ b/example/eigen.ref @@ -53,3 +53,8 @@ block(1,4,3,2) OK incr_diag OK symmetric_lower OK symmetric_upper OK +double_col(arg0: numpy.ndarray[float32[m, 1]]) -> numpy.ndarray[float32[m, 1]] +double_row(arg0: numpy.ndarray[float32[1, n]]) -> numpy.ndarray[float32[1, n]] +double_mat_rm(arg0: numpy.ndarray[float32[m, n]]) -> numpy.ndarray[float32[m, n]] +sparse_passthrough_r(arg0: scipy.sparse.csr_matrix[float32]) -> scipy.sparse.csr_matrix[float32] +sparse_passthrough_c(arg0: scipy.sparse.csc_matrix[float32]) -> scipy.sparse.csc_matrix[float32] diff --git a/example/example-arg-keywords-and-defaults.cpp b/example/example-arg-keywords-and-defaults.cpp index 4e620de52..9c58605fc 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 09ba13e6c..2536782fc 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 a693b6ceb..d3ca99765 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) -> None + +Help on built-in function kw_func1 in module example + +kkww__ffuunncc11(...) + kw_func1(x: int, y: int) -> None 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) -> None 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!') -> None Help on built-in function kw_func4 in module example kkww__ffuunncc44(...) - kw_func4(myList : list = [13L, 17L]) -> NoneType + kw_func4(myList: List[int]=[13L, 17L]) -> None 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) -> None 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) -> None + +Help on built-in function args_function in module example + +aarrggss__ffuunnccttiioonn(...) + args_function(*args) -> None + +Help on built-in function args_kwargs_function in module example + +aarrggss__kkwwaarrggss__ffuunnccttiioonn(...) + args_kwargs_function(*args, **kwargs) -> None + + +foo0(self: KWClass, arg0: int, arg1: float) -> None +foo1(self: KWClass, x: int, y: float) -> None + kw_func(x=5, y=10) kw_func(x=5, y=10) @@ -38,10 +58,10 @@ 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) -> None Invoked with: -kw_func4: 13 17 -kw_func4: 1 2 3 +kw_func4: 13 17 +kw_func4: 1 2 3 kw_func(x=1234, y=5678) got argument: arg1_value got argument: arg2_value diff --git a/example/example-callbacks.py b/example/example-callbacks.py index 674174a16..1d18c892e 100755 --- a/example/example-callbacks.py +++ b/example/example-callbacks.py @@ -82,3 +82,6 @@ except Exception as e: print("All OK!") else: print("Problem!") + +print(test_callback3.__doc__) +print(test_callback4.__doc__) diff --git a/example/example-callbacks.ref b/example/example-callbacks.ref index c2e8eef5d..7180b585b 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) -> None Invoked with: Callback function 1 called! False @@ -36,3 +36,6 @@ could not convert to a function pointer. All OK! could not convert to a function pointer. All OK! + +test_callback3(arg0: Callable[[int], int]) -> None +test_callback4() -> Callable[[int], int] diff --git a/example/example-numpy-vectorize.py b/example/example-numpy-vectorize.py index e21c1a5f7..322ce2aa0 100755 --- a/example/example-numpy-vectorize.py +++ b/example/example-numpy-vectorize.py @@ -32,3 +32,5 @@ from example import selective_func selective_func(np.array([1], dtype=np.int32)) selective_func(np.array([1.0], dtype=np.float32)) selective_func(np.array([1.0j], dtype=np.complex64)) + +print(vectorized_func.__doc__) diff --git a/example/example-numpy-vectorize.ref b/example/example-numpy-vectorize.ref index 4885fc1ca..d2d5d9b8a 100644 --- a/example/example-numpy-vectorize.ref +++ b/example/example-numpy-vectorize.ref @@ -76,3 +76,4 @@ my_func(x:int=6, y:float=3, z:float=2) Int branch taken. Float branch taken. Complex float branch taken. +vectorized_func(arg0: numpy.ndarray[int], arg1: numpy.ndarray[float], arg2: numpy.ndarray[float]) -> object diff --git a/example/example-opaque-types.ref b/example/example-opaque-types.ref index a6672fde0..f8f169204 100644 --- a/example/example-opaque-types.ref +++ b/example/example-opaque-types.ref @@ -10,7 +10,7 @@ Called ExampleMandA default constructor.. Got void ptr : 0x7f9ba0f3c430 Called ExampleMandA destructor (0) Caught expected exception: Incompatible function arguments. The following argument types are supported: - 1. (capsule) -> NoneType + 1. (arg0: capsule) -> None Invoked with: [1, 2, 3] None Got null str : 0x0 diff --git a/example/example-python-types.ref b/example/example-python-types.ref index 2a0237c57..a8c39e081 100644 --- a/example/example-python-types.ref +++ b/example/example-python-types.ref @@ -34,8 +34,8 @@ class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object) | x.__init__(...) initializes x; see help(type(x)) for signature | | ggeett__aarrrraayy(...) - | Signature : (example.ExamplePythonTypes) -> list[2] | + | Signature : (example.ExamplePythonTypes) -> List[unicode[2]] | Return a C++ array | | ggeett__ddiicctt(...) @@ -44,8 +44,8 @@ class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object) | Return a Python dictionary | | ggeett__ddiicctt__22(...) - | Signature : (example.ExamplePythonTypes) -> dict | + | Signature : (example.ExamplePythonTypes) -> Dict[unicode, unicode] | Return a C++ dictionary | | ggeett__lliisstt(...) @@ -54,8 +54,8 @@ class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object) | Return a Python list | | ggeett__lliisstt__22(...) - | Signature : (example.ExamplePythonTypes) -> list | + | Signature : (example.ExamplePythonTypes) -> List[unicode] | Return a C++ list | | ggeett__sseett(...) @@ -69,53 +69,53 @@ class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object) | Return a C++ set | | ppaaiirr__ppaasssstthhrroouugghh(...) - | Signature : (example.ExamplePythonTypes, (bool, unicode)) -> (unicode, bool) | + | Signature : (example.ExamplePythonTypes, Tuple[bool, unicode]) -> Tuple[unicode, bool] | Return a pair in reversed order | | pprriinntt__aarrrraayy(...) - | Signature : (example.ExamplePythonTypes, list[2]) -> NoneType | + | Signature : (example.ExamplePythonTypes, List[unicode[2]]) -> None | Print entries of a C++ array | | pprriinntt__ddiicctt(...) - | Signature : (example.ExamplePythonTypes, dict) -> NoneType | + | Signature : (example.ExamplePythonTypes, dict) -> None | Print entries of a Python dictionary | | pprriinntt__ddiicctt__22(...) - | Signature : (example.ExamplePythonTypes, dict) -> NoneType | + | Signature : (example.ExamplePythonTypes, Dict[unicode, unicode]) -> None | Print entries of a C++ dictionary | | pprriinntt__lliisstt(...) - | Signature : (example.ExamplePythonTypes, list) -> NoneType | + | Signature : (example.ExamplePythonTypes, list) -> None | Print entries of a Python list | | pprriinntt__lliisstt__22(...) - | Signature : (example.ExamplePythonTypes, list) -> NoneType | + | Signature : (example.ExamplePythonTypes, List[unicode]) -> None | Print entries of a C++ list | | pprriinntt__sseett(...) - | Signature : (example.ExamplePythonTypes, set) -> NoneType | + | Signature : (example.ExamplePythonTypes, set) -> None | Print entries of a Python set | | pprriinntt__sseett__22(...) - | Signature : (example.ExamplePythonTypes, set) -> NoneType | + | Signature : (example.ExamplePythonTypes, Set[unicode]) -> None | Print entries of a C++ set | | tthhrrooww__eexxcceeppttiioonn(...) - | Signature : (example.ExamplePythonTypes) -> NoneType | + | Signature : (example.ExamplePythonTypes) -> None | Throw an exception | | ttuuppllee__ppaasssstthhrroouugghh(...) - | Signature : (example.ExamplePythonTypes, (bool, unicode, int)) -> (int, unicode, bool) | + | Signature : (example.ExamplePythonTypes, Tuple[bool, unicode, int]) -> Tuple[int, unicode, bool] | Return a triple in reversed order | | ---------------------------------------------------------------------- diff --git a/example/issues.ref b/example/issues.ref index 0386d2c66..acb1ed08e 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) -> None 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/cast.h b/include/pybind11/cast.h index 91928adb6..1127abcc8 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -399,7 +399,7 @@ public: static handle cast(void_type, return_value_policy /* policy */, handle /* parent */) { return handle(Py_None).inc_ref(); } - PYBIND11_TYPE_CASTER(void_type, _("NoneType")); + PYBIND11_TYPE_CASTER(void_type, _("None")); }; template <> class type_caster : public type_caster { @@ -440,7 +440,7 @@ public: template using cast_op_type = void*&; operator void *&() { return value; } - static PYBIND11_DESCR name() { return _("capsule"); } + static PYBIND11_DESCR name() { return type_descr(_("capsule")); } private: void *value = nullptr; }; @@ -615,8 +615,8 @@ public: static PYBIND11_DESCR name() { return type_descr( - _("(") + type_caster::type>::name() + - _(", ") + type_caster::type>::name() + _(")")); + _("Tuple[") + type_caster::type>::name() + + _(", ") + type_caster::type>::name() + _("]")); } template using cast_op_type = type; @@ -671,11 +671,12 @@ public: return cast(src, policy, parent, typename make_index_sequence::type()); } + static PYBIND11_DESCR element_names() { + return detail::concat(type_caster::type>::name()...); + } + static PYBIND11_DESCR name() { - return type_descr( - _("(") + - detail::concat(type_caster::type>::name()...) + - _(")")); + return type_descr(_("Tuple[") + element_names() + _("]")); } template typename std::enable_if::value, ReturnValue>::type call(Func &&f) { diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index 9c531fa2e..41da5c504 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -161,8 +161,8 @@ struct type_caster::value && } } - PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[dtype=") + npy_format_descriptor::name() + - _(", shape=(") + rows() + _(", ") + cols() + _(")]")); + PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[") + npy_format_descriptor::name() + + _("[") + rows() + _(", ") + cols() + _("]]")); protected: template ::type = 0> @@ -321,7 +321,7 @@ struct type_caster::value>:: ).release(); } - PYBIND11_TYPE_CASTER(Type, _<(Type::Flags & Eigen::RowMajorBit) != 0>("scipy.sparse.csr_matrix[dtype=", "scipy.sparse.csc_matrix[dtype=") + PYBIND11_TYPE_CASTER(Type, _<(Type::Flags & Eigen::RowMajorBit) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[") + npy_format_descriptor::name() + _("]")); }; diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index d289f6185..e82e520eb 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -65,10 +65,10 @@ public: return cpp_function(std::forward(f_), policy).release(); } - PYBIND11_TYPE_CASTER(type, _("function<") + - type_caster>::name() + _(" -> ") + + PYBIND11_TYPE_CASTER(type, _("Callable[[") + + type_caster>::element_names() + _("], ") + type_caster::name() + - _(">")); + _("]")); }; NAMESPACE_END(detail) diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 0180d95cd..5d355e2fc 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -385,7 +385,7 @@ struct vectorize_helper { }; template struct handle_type_name> { - static PYBIND11_DESCR name() { return _("numpy.ndarray[dtype=") + type_caster::name() + _("]"); } + static PYBIND11_DESCR name() { return _("numpy.ndarray[") + type_caster::name() + _("]"); } }; NAMESPACE_END(detail) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index bfb0f07ad..0016f3718 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -135,8 +135,8 @@ protected: detail::process_attributes::init(extra..., rec); /* Generate a readable signature describing the function's arguments and return value types */ - using detail::descr; - PYBIND11_DESCR signature = cast_in::name() + detail::_(" -> ") + cast_out::name(); + using detail::descr; using detail::_; + PYBIND11_DESCR signature = _("(") + cast_in::element_names() + _(") -> ") + cast_out::name(); /* Register the function with Python from generic (non-templated) code */ initialize_generic(rec, signature.text(), signature.types(), sizeof...(Args)); @@ -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 == 0 && 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 == 0) { + 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; diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index e0177de40..2c47841b5 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -53,7 +53,7 @@ template struct set_caster { return s.release(); } - PYBIND11_TYPE_CASTER(type, _("set<") + key_conv::name() + _(">")); + PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name() + _("]")); }; template struct map_caster { @@ -89,7 +89,7 @@ template struct map_caster { return d.release(); } - PYBIND11_TYPE_CASTER(type, _("dict<") + key_conv::name() + _(", ") + value_conv::name() + _(">")); + PYBIND11_TYPE_CASTER(type, _("Dict[") + key_conv::name() + _(", ") + value_conv::name() + _("]")); }; template struct list_caster { @@ -128,7 +128,7 @@ template struct list_caster { return l.release(); } - PYBIND11_TYPE_CASTER(Type, _("list<") + value_conv::name() + _(">")); + PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name() + _("]")); }; template struct type_caster> @@ -168,7 +168,7 @@ template struct type_caster> } return l.release(); } - PYBIND11_TYPE_CASTER(array_type, _("list<") + value_conv::name() + _(">") + _("[") + _() + _("]")); + PYBIND11_TYPE_CASTER(array_type, _("List[") + value_conv::name() + _("[") + _() + _("]]")); }; template struct type_caster>