From 16d43948456ee3c96a2c0b8bd9f446fc85a728b2 Mon Sep 17 00:00:00 2001 From: Andreas Bergmeier Date: Tue, 24 May 2016 09:19:35 +0200 Subject: [PATCH 01/10] Increase available information on invocation error. --- include/pybind11/pybind11.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index ee76a6702..02d81e6f4 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -422,6 +422,14 @@ protected: msg += it2->signature; msg += "\n"; } + msg += " Invoked with: "; + tuple args_(args, true); + for( std::size_t ti = 0; ti != args_.size(); ++ti) + { + msg += static_cast(static_cast(args_[ti]).str()); + if ((ti + 1) != args_.size() ) + msg += ", "; + } PyErr_SetString(PyExc_TypeError, msg.c_str()); return nullptr; } else if (!result) { From 2dd215711aca9428acb6e1512afd49baeee14b96 Mon Sep 17 00:00:00 2001 From: Andreas Bergmeier Date: Tue, 24 May 2016 10:15:43 +0200 Subject: [PATCH 02/10] Fixed expected test examples for more verbose error output. --- example/example11.ref | 2 +- example/example14.ref | 2 +- example/example5.ref | 2 +- example/issues.ref | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/example11.ref b/example/example11.ref index 4c433b75e..f4c23aecd 100644 --- a/example/example11.ref +++ b/example/example11.ref @@ -29,7 +29,7 @@ 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 - + Invoked with: kw_func4: 13 17 kw_func4: 1 2 3 kw_func(x=1234, y=5678) diff --git a/example/example14.ref b/example/example14.ref index c18c7ad2c..44e682098 100644 --- a/example/example14.ref +++ b/example/example14.ref @@ -11,7 +11,7 @@ Got void ptr : 0x7f9ba0f3c430 Called Example1 destructor (0) Caught expected exception: Incompatible function arguments. The following argument types are supported: 1. (capsule) -> NoneType - + Invoked with: [1, 2, 3] None Got null str : 0x0 diff --git a/example/example5.ref b/example/example5.ref index bfc3cb26e..a9c7d465f 100644 --- a/example/example5.ref +++ b/example/example5.ref @@ -14,7 +14,7 @@ Polly is a parrot Molly is a dog The following error is expected: Incompatible function arguments. The following argument types are supported: 1. (example.Dog) -> NoneType - + Invoked with: Callback function 1 called! False Callback function 2 called : Hello, x, True, 5 diff --git a/example/issues.ref b/example/issues.ref index af61939c2..0bfaca04f 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -7,8 +7,8 @@ Yay.. 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 - + Invoked with: None Failed as expected: Incompatible function arguments. The following argument types are supported: 1. (int) -> int - + Invoked with: 5.2 12.0 From b437867338777074af7c80a28f955555d5139515 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Tue, 24 May 2016 21:39:41 +0200 Subject: [PATCH 03/10] eigen.h: relax access to members --- include/pybind11/eigen.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index 00f0347a8..96daf48dd 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -133,7 +133,7 @@ struct type_caster::value>::t operator Type*() { return &value; } operator Type&() { return value; } -private: +protected: template ::type = 0> static PYBIND11_DESCR rows() { return _("m"); } template ::type = 0> @@ -143,7 +143,7 @@ private: template ::type = 0> static PYBIND11_DESCR cols() { return _(); } -private: +protected: Type value; }; @@ -269,7 +269,7 @@ struct type_caster::value>:: operator Type*() { return &value; } operator Type&() { return value; } -private: +protected: Type value; }; From 1e3be73a521d6c888e09e554b8a239ce28fbf5a8 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Tue, 24 May 2016 23:42:05 +0200 Subject: [PATCH 04/10] PYBIND11_OVERLOAD_NAME and PYBIND11_OVERLOAD_PURE_NAME (fixes #205) --- docs/advanced.rst | 10 ++++++++-- example/example12.ref | 2 +- example/issues.ref | 2 +- include/pybind11/pybind11.h | 22 ++++++++++++++-------- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/docs/advanced.rst b/docs/advanced.rst index 4353536f0..032cf8593 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -268,8 +268,14 @@ helper class that is defined as follows: The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have -a default implementation. The binding code also needs a few minor adaptations -(highlighted): +a default implementation. + +There are also two alternate macros :func:`PYBIND11_OVERLOAD_PURE_NAME` and +:func:`PYBIND11_OVERLOAD_NAME` which take a string-valued name argument +after the *Name of the function* slot. This is useful when the C++ and Python +versions of the function have different names, e.g. ``operator()`` vs ``__call__``. + +The binding code also needs a few minor adaptations (highlighted): .. code-block:: cpp :emphasize-lines: 4,6,7 diff --git a/example/example12.ref b/example/example12.ref index 2274cddd2..a25023fae 100644 --- a/example/example12.ref +++ b/example/example12.ref @@ -1,7 +1,7 @@ Constructing Example12.. Original implementation of Example12::run(state=10, value=20) 30 -Caught expected exception: Tried to call pure virtual function "pure_virtual" +Caught expected exception: Tried to call pure virtual function "Example12::pure_virtual" Constructing Example12.. ExtendedExample12::run(20), calling parent.. Original implementation of Example12::run(state=11, value=21) diff --git a/example/issues.ref b/example/issues.ref index 0bfaca04f..4888ea55b 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -1,6 +1,6 @@ const char * c -Failed as expected: Tried to call pure virtual function "dispatch" +Failed as expected: Tried to call pure virtual function "Base::dispatch" Yay.. [Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]] [3, 5, 7, 9, 11, 13, 15] diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 02d81e6f4..34869ebae 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1184,19 +1184,25 @@ inline function get_overload(const void *this_ptr, const char *name) { return overload; } -#define PYBIND11_OVERLOAD_INT(ret_type, class_name, name, ...) { \ +#define PYBIND11_OVERLOAD_INT(ret_type, name, ...) { \ pybind11::gil_scoped_acquire gil; \ - pybind11::function overload = pybind11::get_overload(this, #name); \ + pybind11::function overload = pybind11::get_overload(this, name); \ if (overload) \ return overload(__VA_ARGS__).template cast(); } -#define PYBIND11_OVERLOAD(ret_type, class_name, name, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \ - return class_name::name(__VA_ARGS__) +#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \ + return cname::fn(__VA_ARGS__) -#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \ - pybind11::pybind11_fail("Tried to call pure virtual function \"" #name "\""); +#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \ + pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\""); + +#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) + +#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) NAMESPACE_END(pybind11) From 114bfeb762e623330b3f1efa9d53b090782e7765 Mon Sep 17 00:00:00 2001 From: Yung-Yu Chen Date: Wed, 25 May 2016 20:54:12 +0800 Subject: [PATCH 05/10] pybind11::args should have been derived from tuple args was derived from list, but cpp_function::dispatcher sends a tuple to it->impl (line #346 and #392 in pybind11.h). As a result args::size() and args::operator[] don't work at all. On my mac args::size() returns -1. Making args a subclass of tuple fixes it. --- example/example11.cpp | 4 ++-- include/pybind11/pytypes.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/example11.cpp b/example/example11.cpp index 466eed465..799fa6226 100644 --- a/example/example11.cpp +++ b/example/example11.cpp @@ -27,8 +27,8 @@ py::object call_kw_func(py::function f) { } void args_function(py::args args) { - for (auto item : args) - std::cout << "got argument: " << item << std::endl; + for (size_t it=0; it Date: Thu, 26 May 2016 10:47:11 +0200 Subject: [PATCH 06/10] minor cleanups in pytypes.h --- include/pybind11/pytypes.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 4da205b4f..2ba03c01d 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -323,10 +323,10 @@ public: PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check) }; -inline detail::accessor handle::operator[](handle key) const { return detail::accessor(ptr(), key.ptr(), false); } -inline detail::accessor handle::operator[](const char *key) const { return detail::accessor(ptr(), key, false); } -inline detail::accessor handle::attr(handle key) const { return detail::accessor(ptr(), key.ptr(), true); } -inline detail::accessor handle::attr(const char *key) const { return detail::accessor(ptr(), key, true); } +inline detail::accessor handle::operator[](handle key) const { return detail::accessor(*this, key, false); } +inline detail::accessor handle::operator[](const char *key) const { return detail::accessor(*this, key, false); } +inline detail::accessor handle::attr(handle key) const { return detail::accessor(*this, key, true); } +inline detail::accessor handle::attr(const char *key) const { return detail::accessor(*this, key, true); } inline iterator handle::begin() const { return iterator(PyObject_GetIter(ptr()), false); } inline iterator handle::end() const { return iterator(nullptr, false); } inline detail::args_proxy handle::operator*() const { return detail::args_proxy(*this); } @@ -501,7 +501,7 @@ public: if (!m_ptr) pybind11_fail("Could not allocate dict object!"); } size_t size() const { return (size_t) PyDict_Size(m_ptr); } - detail::dict_iterator begin() const { return (++detail::dict_iterator(ptr(), 0)); } + detail::dict_iterator begin() const { return (++detail::dict_iterator(*this, 0)); } detail::dict_iterator end() const { return detail::dict_iterator(); } void clear() const { PyDict_Clear(ptr()); } }; From 86d825f3302701d81414ddd3d38bcd09433076bc Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 26 May 2016 13:19:27 +0200 Subject: [PATCH 07/10] Redesigned virtual call mechanism and user-facing syntax (breaking change!) Sergey Lyskov pointed out that the trampoline mechanism used to override virtual methods from within Python caused unnecessary overheads when instantiating the original (i.e. non-extended) class. This commit removes this inefficiency, but some syntax changes were needed to achieve this. Projects using this features will need to make a few changes: In particular, the example below shows the old syntax to instantiate a class with a trampoline: class_("MyClass") .alias() .... This is what should be used now: class_("MyClass") .... Importantly, the trampoline class is now specified as the *third* argument to the class_ template, and the alias<..>() call is gone. The second argument with the unique pointer is simply the default holder type used by pybind11. --- docs/advanced.rst | 26 ++++++++++----------- docs/changelog.rst | 11 +++++++++ example/example12.cpp | 12 ++++------ example/issues.cpp | 27 ++++++++++++++++++++-- example/issues.py | 17 ++++++++++++++ example/issues.ref | 6 +++++ include/pybind11/attr.h | 1 + include/pybind11/pybind11.h | 46 +++++++++++++++++++++++++++++-------- 8 files changed, 113 insertions(+), 33 deletions(-) diff --git a/docs/advanced.rst b/docs/advanced.rst index 032cf8593..ba95c2053 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -283,9 +283,8 @@ The binding code also needs a few minor adaptations (highlighted): PYBIND11_PLUGIN(example) { py::module m("example", "pybind11 example plugin"); - py::class_ animal(m, "Animal"); + py::class_, PyAnimal /* <--- trampoline*/> animal(m, "Animal"); animal - .alias() .def(py::init<>()) .def("go", &Animal::go); @@ -297,10 +296,10 @@ The binding code also needs a few minor adaptations (highlighted): return m.ptr(); } -Importantly, the trampoline helper class is used as the template argument to -:class:`class_`, and a call to :func:`class_::alias` informs the binding -generator that this is merely an alias for the underlying type ``Animal``. -Following this, we are able to define a constructor as usual. +Importantly, pybind11 is made aware of the trampoline trampoline helper class +by specifying it as the *third* template argument to :class:`class_`. The +second argument with the unique pointer is simply the default holder type used +by pybind11. Following this, we are able to define a constructor as usual. The Python session below shows how to override ``Animal::go`` and invoke it via a virtual method call. @@ -321,12 +320,12 @@ a virtual method call. .. warning:: - Both :func:`PYBIND11_OVERLOAD` and :func:`PYBIND11_OVERLOAD_PURE` are - macros, which means that they can get confused by commas in a template - argument such as ``PYBIND11_OVERLOAD(MyReturnValue, myFunc)``. In - this case, the preprocessor assumes that the comma indicates the beginnning - of the next parameter. Use a ``typedef`` to bind the template to another - name and use it in the macro to avoid this problem. + The :func:`PYBIND11_OVERLOAD_*` calls are all just macros, which means that + they can get confused by commas in a template argument such as + ``PYBIND11_OVERLOAD(MyReturnValue, myFunc)``. In this case, the + preprocessor assumes that the comma indicates the beginnning of the next + parameter. Use a ``typedef`` to bind the template to another name and use + it in the macro to avoid this problem. .. seealso:: @@ -369,9 +368,8 @@ be realized as follows (important changes highlighted): PYBIND11_PLUGIN(example) { py::module m("example", "pybind11 example plugin"); - py::class_ animal(m, "Animal"); + py::class_, PyAnimal> animal(m, "Animal"); animal - .alias() .def(py::init<>()) .def("go", &Animal::go); diff --git a/docs/changelog.rst b/docs/changelog.rst index 632f2be84..7cf26e107 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,9 +5,11 @@ Changelog 1.8 (Not yet released) ---------------------- +* Redesigned virtual call mechanism and user-facing syntax (breaking change!) * Prevent implicit conversion of floating point values to integral types in function arguments * Transparent conversion of sparse and dense Eigen data types +* ``std::vector<>`` type bindings analogous to Boost.Python's ``indexing_suite`` * Fixed incorrect default return value policy for functions returning a shared pointer * Don't allow casting a ``None`` value into a C++ lvalue reference @@ -16,10 +18,19 @@ Changelog * Extended ``str`` type to also work with ``bytes`` instances * Added ``[[noreturn]]`` attribute to ``pybind11_fail()`` to quench some compiler warnings +* List function arguments in exception text when the dispatch code cannot find + a matching overload * Various minor ``iterator`` and ``make_iterator()`` improvements +* Transparently support ``__bool__`` on Python 2.x and Python 3.x +* Fixed issue with destructor of unpickled object not being called * Minor CMake build system improvements on Windows * Many ``mkdoc.py`` improvements (enumerations, template arguments, ``DOC()`` macro accepts more arguments) +* New ``pybind11::args`` and ``pybind11::kwargs`` types to create functions which + take an arbitrary number of arguments and keyword arguments +* New syntax to call a Python function from C++ using ``*args`` and ``*kwargs`` +* Added an ``ExtraFlags`` template argument to the NumPy ``array_t<>`` wrapper. This + can be used to disable an enforced cast that may lose precision * Documentation improvements (pickling support, ``keep_alive``) 1.7 (April 30, 2016) diff --git a/example/example12.cpp b/example/example12.cpp index 5cc8dc87c..e5555f53a 100644 --- a/example/example12.cpp +++ b/example/example12.cpp @@ -82,15 +82,11 @@ void runExample12Virtual(Example12 *ex) { } void init_ex12(py::module &m) { - /* Important: use the wrapper type as a template - argument to class_<>, but use the original name - to denote the type */ - py::class_(m, "Example12") - /* Declare that 'PyExample12' is really an alias for the original type 'Example12' */ - .alias() + /* Important: indicate the trampoline class PyExample12 using the third + argument to py::class_. The second argument with the unique pointer + is simply the default holder type used by pybind11. */ + py::class_, PyExample12>(m, "Example12") .def(py::init()) - /* Copy constructor (not needed in this case, but should generally be declared in this way) */ - .def(py::init()) /* Reference original class in function definitions */ .def("run", &Example12::run) .def("run_bool", &Example12::run_bool) diff --git a/example/issues.cpp b/example/issues.cpp index d1a1941b7..e1647081f 100644 --- a/example/issues.cpp +++ b/example/issues.cpp @@ -42,8 +42,7 @@ void init_issues(py::module &m) { } }; - py::class_ base(m2, "DispatchIssue"); - base.alias() + py::class_, DispatchIssue>(m2, "DispatchIssue") .def(py::init<>()) .def("dispatch", &Base::dispatch); @@ -108,4 +107,28 @@ void init_issues(py::module &m) { // (no id): don't cast doubles to ints m2.def("expect_float", [](float f) { return f; }); m2.def("expect_int", [](int i) { return i; }); + + // (no id): don't invoke Python dispatch code when instantiating C++ + // classes that were not extended on the Python side + struct A { + virtual ~A() {} + virtual void f() { std::cout << "A.f()" << std::endl; } + }; + + struct PyA : A { + PyA() { std::cout << "PyA.PyA()" << std::endl; } + + void f() override { + std::cout << "PyA.f()" << std::endl; + PYBIND11_OVERLOAD(void, A, f); + } + }; + + auto call_f = [](A *a) { a->f(); }; + + pybind11::class_, PyA>(m2, "A") + .def(py::init<>()) + .def("f", &A::f); + + m2.def("call_f", call_f); } diff --git a/example/issues.py b/example/issues.py index d075e8340..257f08e18 100644 --- a/example/issues.py +++ b/example/issues.py @@ -9,6 +9,7 @@ from example.issues import Placeholder, return_vec_of_reference_wrapper from example.issues import iterator_passthrough from example.issues import ElementList, ElementA, print_element from example.issues import expect_float, expect_int +from example.issues import A, call_f import gc print_cchar("const char *") @@ -55,3 +56,19 @@ except Exception as e: print("Failed as expected: " + str(e)) print(expect_float(12)) + +class B(A): + def __init__(self): + super(B, self).__init__() + + def f(self): + print("In python f()") + +print("C++ version") +a = A() +call_f(a) + +print("Python version") +b = B() +call_f(b) + diff --git a/example/issues.ref b/example/issues.ref index 4888ea55b..58cc7985f 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -12,3 +12,9 @@ Failed as expected: Incompatible function arguments. The following argument type 1. (int) -> int Invoked with: 5.2 12.0 +C++ version +A.f() +Python version +PyA.PyA() +PyA.f() +In python f() diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index d63a44e9f..5e2d8f2e0 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -65,6 +65,7 @@ enum op_type : int; struct undefined_t; template struct op_; template struct init; +template struct init_alias; inline void keep_alive_impl(int Nurse, int Patient, handle args, handle ret); /// Internal data structure which holds metadata about a keyword argument diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 34869ebae..db806b845 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -503,7 +503,7 @@ public: NAMESPACE_BEGIN(detail) /// Generic support for creating new Python heap types class generic_type : public object { - template friend class class_; + template friend class class_; public: PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check) protected: @@ -721,7 +721,7 @@ protected: }; NAMESPACE_END(detail) -template > +template , typename type_alias = type> class class_ : public detail::generic_type { public: typedef detail::instance instance_type; @@ -743,6 +743,11 @@ public: detail::process_attributes::init(extra..., &record); detail::generic_type::initialize(&record); + + if (!std::is_same::value) { + auto &instances = pybind11::detail::get_internals().registered_types_cpp; + instances[std::type_index(typeid(type_alias))] = instances[std::type_index(typeid(type))]; + } } template @@ -780,6 +785,12 @@ public: return *this; } + template + class_ &def(const detail::init_alias &init, const Extra&... extra) { + init.template execute(*this, extra...); + return *this; + } + template class_& def_buffer(Func &&func) { struct capture { Func func; }; capture *ptr = new capture { std::forward(func) }; @@ -856,11 +867,6 @@ public: return *this; } - template class_ alias() { - auto &instances = pybind11::detail::get_internals().registered_types_cpp; - instances[std::type_index(typeid(target))] = instances[std::type_index(typeid(type))]; - return *this; - } private: /// Initialize holder object, variant 1: object derives from enable_shared_from_this template @@ -959,9 +965,31 @@ private: NAMESPACE_BEGIN(detail) template struct init { - template void execute(pybind11::class_ &class_, const Extra&... extra) const { + template ::value, int>::type = 0> + void execute(pybind11::class_ &class_, const Extra&... extra) const { /// Function which calls a specific C++ in-place constructor - class_.def("__init__", [](Base *instance, Args... args) { new (instance) Base(args...); }, extra...); + class_.def("__init__", [](Base *self, Args... args) { new (self) Base(args...); }, extra...); + } + + template ::value && + std::is_constructible::value, int>::type = 0> + void execute(pybind11::class_ &class_, const Extra&... extra) const { + handle cl_type = class_; + class_.def("__init__", [cl_type](handle self, Args... args) { + if (self.get_type() == cl_type) + new (self.cast()) Base(args...); + else + new (self.cast()) Alias(args...); + }, extra...); + } + + template ::value && + !std::is_constructible::value, int>::type = 0> + void execute(pybind11::class_ &class_, const Extra&... extra) const { + class_.def("__init__", [](Alias *self, Args... args) { new (self) Alias(args...); }, extra...); } }; From 69e1a5c91b8fd999da327a39d684745bf689011d Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 26 May 2016 14:29:31 +0200 Subject: [PATCH 08/10] quenched warnings on windows, comments in gil_scoped_release --- include/pybind11/cast.h | 2 +- include/pybind11/pybind11.h | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 31f5cb5a6..def3044dc 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -660,7 +660,7 @@ public: std::get<1>(value).load(kwargs, convert); return true; } - + static handle cast(const type &src, return_value_policy policy, handle parent) { return cast(src, policy, parent, typename make_index_sequence::type()); } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index db806b845..690c63549 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -969,7 +969,7 @@ template struct init { typename std::enable_if::value, int>::type = 0> void execute(pybind11::class_ &class_, const Extra&... extra) const { /// Function which calls a specific C++ in-place constructor - class_.def("__init__", [](Base *self, Args... args) { new (self) Base(args...); }, extra...); + class_.def("__init__", [](Base *self_, Args... args) { new (self_) Base(args...); }, extra...); } template struct init { std::is_constructible::value, int>::type = 0> void execute(pybind11::class_ &class_, const Extra&... extra) const { handle cl_type = class_; - class_.def("__init__", [cl_type](handle self, Args... args) { - if (self.get_type() == cl_type) - new (self.cast()) Base(args...); + class_.def("__init__", [cl_type](handle self_, Args... args) { + if (self_.get_type() == cl_type) + new (self_.cast()) Base(args...); else - new (self.cast()) Alias(args...); + new (self_.cast()) Alias(args...); }, extra...); } @@ -1074,6 +1074,11 @@ template void implicitly_convertible() * can be handy to prevent cases where callbacks issued from an external * thread would otherwise constantly construct and destroy thread state data * structures. + * + * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an + * example which uses features 2 and 3 to migrate the Python thread of + * execution to another thread (to run the event loop on the original thread, + * in this case). */ class gil_scoped_acquire { From 2240ce2adff4b9ce5b5e04441e6a36f0abd27663 Mon Sep 17 00:00:00 2001 From: Yung-Yu Chen Date: Thu, 26 May 2016 22:32:41 +0800 Subject: [PATCH 09/10] Update document version to the next release 1.8 --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 9d25838d2..39d4933e3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,9 +56,9 @@ author = 'Wenzel Jakob' # built documents. # # The short X.Y version. -version = '1.0' +version = '1.8' # The full version, including alpha/beta/rc tags. -release = '1.0' +release = '1.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 2c76c693f642c7bb5b13939581fa4cf0a525ce7e Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 26 May 2016 16:50:15 +0200 Subject: [PATCH 10/10] minor update to release process --- docs/release.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release.rst b/docs/release.rst index d8f9db854..1b24e3360 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -2,7 +2,8 @@ To release a new version of pybind11: - Update the version number and push to pypi - Update ``pybind11/_version.py`` (set release version, remove 'dev') - - Tag release date in ``doc/changelog.rst``. + - Update version in ``docs/conf.py`` + - Tag release date in ``docs/changelog.rst``. - ``git add`` and ``git commit``. - ``git tag -a vX.Y -m 'vX.Y release'``. - ``git push``