From ecced6c5ae399d7c0214b57a5b24ba8c1fbebd1b Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Sun, 31 Jul 2016 20:03:18 +0200 Subject: [PATCH 1/2] Use generic arg names for functions without explicitly named arguments Example signatures (old => new): foo(int) => foo(arg0: int) bar(Object, int) => bar(self: Object, arg0: int) The change makes the signatures uniform for named and unnamed arguments and it helps static analysis tools reconstruct function signatures from docstrings. This also tweaks the signature whitespace style to better conform to PEP 8 for annotations and default arguments: " : " => ": " " = " => "=" --- example/example-arg-keywords-and-defaults.cpp | 11 +++++- example/example-arg-keywords-and-defaults.py | 17 ++++++--- example/example-arg-keywords-and-defaults.ref | 38 ++++++++++++++----- example/example-callbacks.ref | 2 +- example/issues.ref | 6 +-- include/pybind11/pybind11.h | 25 +++++++----- 6 files changed, 71 insertions(+), 28 deletions(-) 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..68895743e 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 c2e8eef5d..d6ab75eb6 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 0386d2c66..90d8ce17f 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 bfb0f07ad..26124ae98 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; From ed23dda93b3735e220c5931f646dc8193d2d1b31 Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Thu, 4 Aug 2016 01:40:40 +0200 Subject: [PATCH 2/2] Adopt PEP 484 type hints for C++ types exported to Python --- example/eigen.py | 6 ++++ example/eigen.ref | 5 ++++ example/example-arg-keywords-and-defaults.ref | 28 +++++++++---------- example/example-callbacks.py | 3 ++ example/example-callbacks.ref | 5 +++- example/example-numpy-vectorize.py | 2 ++ example/example-numpy-vectorize.ref | 1 + example/example-opaque-types.ref | 2 +- example/example-python-types.ref | 26 ++++++++--------- example/issues.ref | 2 +- include/pybind11/cast.h | 17 +++++------ include/pybind11/eigen.h | 6 ++-- include/pybind11/functional.h | 6 ++-- include/pybind11/numpy.h | 2 +- include/pybind11/pybind11.h | 8 +++--- include/pybind11/stl.h | 8 +++--- 16 files changed, 74 insertions(+), 53 deletions(-) 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.ref b/example/example-arg-keywords-and-defaults.ref index 68895743e..d3ca99765 100644 --- a/example/example-arg-keywords-and-defaults.ref +++ b/example/example-arg-keywords-and-defaults.ref @@ -1,51 +1,51 @@ Help on built-in function kw_func0 in module example kkww__ffuunncc00(...) - kw_func0(arg0: int, arg1: int) -> NoneType + 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) -> NoneType + 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) -> NoneType + args_function(*args) -> None Help on built-in function args_kwargs_function in module example aarrggss__kkwwaarrggss__ffuunnccttiioonn(...) - args_kwargs_function(*args, **kwargs) -> NoneType + args_kwargs_function(*args, **kwargs) -> None -foo0(self: KWClass, arg0: int, arg1: float) -> NoneType -foo1(self: KWClass, x: int, y: float) -> NoneType +foo0(self: KWClass, arg0: int, arg1: float) -> None +foo1(self: KWClass, x: int, y: float) -> None kw_func(x=5, y=10) @@ -58,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 d6ab75eb6..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. (arg0: 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 90d8ce17f..acb1ed08e 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -6,7 +6,7 @@ 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. (arg0: 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. (arg0: int) -> int 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 26124ae98..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)); @@ -183,7 +183,7 @@ protected: if (c == '{') { // Write arg name for everything except *args, **kwargs and return type. - if (type_depth == 1 && text[char_index] != '*' && arg_index < args) { + 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_) { @@ -196,7 +196,7 @@ protected: ++type_depth; } else if (c == '}') { --type_depth; - if (type_depth == 1) { + if (type_depth == 0) { if (arg_index < rec->args.size() && rec->args[arg_index].descr) { signature += "="; signature += rec->args[arg_index].descr; 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>