1414#include " pybind11.h"
1515
1616#include < functional>
17+ #include < iostream>
1718
1819PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
1920PYBIND11_NAMESPACE_BEGIN(detail)
@@ -129,7 +130,7 @@ struct type_caster<std::function<Return(Args...)>> {
129130 // See PR #1413 for full details
130131 } else {
131132 // Check number of arguments of Python function
132- auto argCountFromFuncCode = [& ](handle &obj) {
133+ auto argCountFromFuncCode = [](handle &obj) {
133134 // This is faster then doing import inspect and
134135 // inspect.signature(obj).parameters
135136
@@ -138,20 +139,42 @@ struct type_caster<std::function<Return(Args...)>> {
138139 };
139140 size_t argCount = 0 ;
140141
141- handle codeAttr = PyObject_GetAttrString (src.ptr (), " __code__" );
142+ std::cout << " BEFORE " << std::endl;
143+ handle empty;
144+ object codeAttr = getattr (src, " __code__" , empty);
145+ // = reinterpret_borrow<object>(PyObject_GetAttrString(src.ptr(), "__code__"));
146+ assert ((static_cast <bool >(codeAttr)
147+ == static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __code__" )))
148+ && " ptr and "
149+ " HasAttrString "
150+ " inconsistent for __code__" );
142151 if (codeAttr) {
152+ std::cout << " __code__ exists" << std::endl;
143153 argCount = argCountFromFuncCode (codeAttr);
144154 } else {
145- handle callAttr = PyObject_GetAttrString (src.ptr (), " __call__" );
155+ object callAttr = getattr (src, " __call__" , empty);
156+ // = reinterpret_borrow<object>(PyObject_GetAttrString(src.ptr(), "__call__"));
157+ assert ((static_cast <bool >(callAttr)
158+ == static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __call__" )))
159+ && " ptr and "
160+ " HasAttrString "
161+ " inconsistent for __call__" );
146162 if (callAttr) {
147- handle codeAttr2 = PyObject_GetAttrString (callAttr.ptr (), " __code__" );
163+ std::cout << " __call__ exists" << std::endl;
164+ object codeAttr2 = getattr (callAttr ," __code__" );
165+ // reinterpret_borrow<object>(
166+ // PyObject_GetAttrString(callAttr.ptr(), "__code__"));
148167 argCount = argCountFromFuncCode (codeAttr2)
149168 - 1 ; // we have to remove the self argument
150169 } else {
151170 // No __code__ or __call__ attribute, this is not a proper Python function
171+ std::cout << " No __code__ or __call__ attribute, this is not a proper Python "
172+ " function"
173+ << std::endl;
152174 return false ;
153175 }
154176 }
177+ std::cout << " AFTER " << std::endl;
155178 // if we are a method, we have to correct the argument count since we are not counting
156179 // the self argument
157180 const size_t self_offset = static_cast <bool >(PyMethod_Check (src.ptr ())) ? 1 : 0 ;
0 commit comments