diff options
Diffstat (limited to 'ext/pybind11/include/pybind11/functional.h')
-rw-r--r-- | ext/pybind11/include/pybind11/functional.h | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/ext/pybind11/include/pybind11/functional.h b/ext/pybind11/include/pybind11/functional.h index a99ee737f..eda14ba58 100644 --- a/ext/pybind11/include/pybind11/functional.h +++ b/ext/pybind11/include/pybind11/functional.h @@ -12,7 +12,7 @@ #include "pybind11.h" #include <functional> -NAMESPACE_BEGIN(pybind11) +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) NAMESPACE_BEGIN(detail) template <typename Return, typename... Args> @@ -22,14 +22,18 @@ struct type_caster<std::function<Return(Args...)>> { using function_type = Return (*) (Args...); public: - bool load(handle src_, bool) { - if (src_.is_none()) + bool load(handle src, bool convert) { + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) return false; return true; + } - src_ = detail::get_function(src_); - if (!src_ || !PyCallable_Check(src_.ptr())) + if (!isinstance<function>(src)) return false; + auto func = reinterpret_borrow<function>(src); + /* When passing a C++ function as an argument to another C++ function via Python, every function call would normally involve @@ -38,21 +42,21 @@ public: stateless (i.e. function pointer or lambda function without captured variables), in which case the roundtrip can be avoided. */ - if (PyCFunction_Check(src_.ptr())) { - auto c = reinterpret_borrow<capsule>(PyCFunction_GET_SELF(src_.ptr())); + if (auto cfunc = func.cpp_function()) { + auto c = reinterpret_borrow<capsule>(PyCFunction_GET_SELF(cfunc.ptr())); auto rec = (function_record *) c; - if (rec && rec->is_stateless && rec->data[1] == &typeid(function_type)) { + if (rec && rec->is_stateless && + same_type(typeid(function_type), *reinterpret_cast<const std::type_info *>(rec->data[1]))) { struct capture { function_type f; }; value = ((capture *) &rec->data)->f; return true; } } - auto src = reinterpret_borrow<object>(src_); - value = [src](Args... args) -> Return { + value = [func](Args... args) -> Return { gil_scoped_acquire acq; - object retval(src(std::forward<Args>(args)...)); + object retval(func(std::forward<Args>(args)...)); /* Visual studio 2015 parser issue: need parentheses around this expression */ return (retval.template cast<Return>()); }; @@ -78,4 +82,4 @@ public: }; NAMESPACE_END(detail) -NAMESPACE_END(pybind11) +NAMESPACE_END(PYBIND11_NAMESPACE) |