Skip to content

Commit

Permalink
functional.h: support more kinds of Python functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Wenzel Jakob committed Nov 16, 2015
1 parent 3ee91b2 commit eb7c0b8
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
3 changes: 2 additions & 1 deletion include/pybind11/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ template <typename Return, typename... Args> struct type_caster<std::function<Re
public:

bool load(PyObject *src_, bool) {
if (!PyFunction_Check(src_))
src_ = detail::get_function(src_);
if (!src_ || !(PyFunction_Check(src_) || PyCFunction_Check(src_)))
return false;
object src(src_, true);
value = [src](Args... args) -> Return {
Expand Down
24 changes: 14 additions & 10 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ class iterator : public object {
};

NAMESPACE_BEGIN(detail)
inline PyObject *get_function(PyObject *value) {
if (value == nullptr)
return nullptr;
#if PY_MAJOR_VERSION >= 3
if (PyInstanceMethod_Check(value))
value = PyInstanceMethod_GET_FUNCTION(value);
#endif
if (PyMethod_Check(value))
value = PyMethod_GET_FUNCTION(value);
return value;
}

class accessor {
public:
accessor(PyObject *obj, PyObject *key, bool attr)
Expand Down Expand Up @@ -346,16 +358,8 @@ class function : public object {
PYBIND11_OBJECT_DEFAULT(function, object, PyFunction_Check)

bool is_cpp_function() {
PyObject *ptr = m_ptr;
if (ptr == nullptr)
return false;
#if PY_MAJOR_VERSION >= 3
if (PyInstanceMethod_Check(ptr))
ptr = PyInstanceMethod_GET_FUNCTION(ptr);
#endif
if (PyMethod_Check(ptr))
ptr = PyMethod_GET_FUNCTION(ptr);
return PyCFunction_Check(ptr);
PyObject *ptr = detail::get_function(m_ptr);
return ptr != nullptr && PyCFunction_Check(ptr);
}
};

Expand Down

0 comments on commit eb7c0b8

Please sign in to comment.