Commit 8de0437e by Wenzel Jakob

type_caster<std::function>: allow None values in both directions

parent 0b63231b
...@@ -38,6 +38,9 @@ py::cpp_function test_callback5() { ...@@ -38,6 +38,9 @@ py::cpp_function test_callback5() {
int dummy_function(int i) { return i + 1; } int dummy_function(int i) { return i + 1; }
int dummy_function2(int i, int j) { return i + j; } int dummy_function2(int i, int j) { return i + j; }
std::function<int(int)> roundtrip(std::function<int(int)> f) { std::function<int(int)> roundtrip(std::function<int(int)> f) {
if (!f)
std::cout << "roundtrip (got None).." << std::endl;
else
std::cout << "roundtrip.." << std::endl; std::cout << "roundtrip.." << std::endl;
return f; return f;
} }
......
...@@ -68,6 +68,8 @@ from example import roundtrip ...@@ -68,6 +68,8 @@ from example import roundtrip
test_dummy_function(dummy_function) test_dummy_function(dummy_function)
test_dummy_function(roundtrip(dummy_function)) test_dummy_function(roundtrip(dummy_function))
if roundtrip(None) is not None:
print("Problem!")
test_dummy_function(lambda x: x + 2) test_dummy_function(lambda x: x + 2)
try: try:
......
...@@ -30,6 +30,7 @@ Copy constructions: 1 ...@@ -30,6 +30,7 @@ Copy constructions: 1
Move constructions: True Move constructions: True
argument matches dummy_function argument matches dummy_function
eval(1) = 2 eval(1) = 2
roundtrip (got None)..
roundtrip.. roundtrip..
argument matches dummy_function argument matches dummy_function
eval(1) = 2 eval(1) = 2
......
...@@ -20,6 +20,9 @@ template <typename Return, typename... Args> struct type_caster<std::function<Re ...@@ -20,6 +20,9 @@ template <typename Return, typename... Args> struct type_caster<std::function<Re
typedef typename std::conditional<std::is_same<Return, void>::value, void_type, Return>::type retval_type; typedef typename std::conditional<std::is_same<Return, void>::value, void_type, Return>::type retval_type;
public: public:
bool load(handle src_, bool) { bool load(handle src_, bool) {
if (src_.ptr() == Py_None)
return true;
src_ = detail::get_function(src_); src_ = detail::get_function(src_);
if (!src_ || !PyCallable_Check(src_.ptr())) if (!src_ || !PyCallable_Check(src_.ptr()))
return false; return false;
...@@ -58,6 +61,9 @@ public: ...@@ -58,6 +61,9 @@ public:
template <typename Func> template <typename Func>
static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {
if (!f_)
return handle(Py_None).inc_ref();
auto result = f_.template target<Return (*)(Args...)>(); auto result = f_.template target<Return (*)(Args...)>();
if (result) if (result)
return cpp_function(*result, policy).release(); return cpp_function(*result, policy).release();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment