diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index 8a8c32c0ec..0107c67fb0 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -14,6 +14,7 @@ #include "pybind11.h" #include +#include PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) @@ -129,7 +130,7 @@ struct type_caster> { // See PR #1413 for full details } else { // Check number of arguments of Python function - auto argCountFromFuncCode = [&](handle &obj) { + auto argCountFromFuncCode = [](handle &obj) { // This is faster then doing import inspect and // inspect.signature(obj).parameters @@ -138,20 +139,40 @@ struct type_caster> { }; size_t argCount = 0; - handle codeAttr = PyObject_GetAttrString(src.ptr(), "__code__"); - if (codeAttr) { + std::cout << "BEFORE " << std::endl; + auto codeAttr + = reinterpret_borrow (PyObject_GetAttrString(src.ptr(), "__code__")); + assert(((codeAttr) + == static_cast(PyObject_HasAttrString(src.ptr(), "__code__"))) + && "ptr and " + "HasAttrString " + "inconsistent for __code__"); + if (static_cast(PyObject_HasAttrString(src.ptr(), "__code__"))) { + std::cout << "__code__ exists" << std::endl; argCount = argCountFromFuncCode(codeAttr); } else { - handle callAttr = PyObject_GetAttrString(src.ptr(), "__call__"); - if (callAttr) { - handle codeAttr2 = PyObject_GetAttrString(callAttr.ptr(), "__code__"); + auto callAttr + = reinterpret_borrow (PyObject_GetAttrString(src.ptr(), "__call__")); + assert( + ((callAttr) + == static_cast(PyObject_HasAttrString(src.ptr(), "__call__"))) && "ptr and " + "HasAttrString " + "inconsistent for __call__"); + if (callAttr.ptr()!=nullptr) { + std::cout << "__call__ exists" << std::endl; + auto codeAttr2 = reinterpret_borrow (PyObject_GetAttrString( + callAttr.ptr(), "__code__")); argCount = argCountFromFuncCode(codeAttr2) - 1; // we have to remove the self argument } else { // No __code__ or __call__ attribute, this is not a proper Python function + std::cout << "No __code__ or __call__ attribute, this is not a proper Python " + "function" + << std::endl; return false; } } + std::cout << "AFTER " << std::endl; // if we are a method, we have to correct the argument count since we are not counting // the self argument const size_t self_offset = static_cast(PyMethod_Check(src.ptr())) ? 1 : 0;