@@ -59,8 +59,8 @@ struct type_caster<std::function<Return(Args...)>> {
59
59
rec = c.get_pointer <function_record>();
60
60
}
61
61
while (rec != nullptr ) {
62
- const int correctingSelfArgument = rec->is_method ? 1 : 0 ;
63
- if (rec->nargs - correctingSelfArgument != sizeof ...(Args)) {
62
+ const int self_offset = rec->is_method ? 1 : 0 ;
63
+ if (rec->nargs != sizeof ...(Args) + self_offset ) {
64
64
rec = rec->next ;
65
65
// if the overload is not feasible in terms of number of arguments, we
66
66
// continue to the next one. If there is no next one, we return false.
@@ -86,31 +86,34 @@ struct type_caster<std::function<Return(Args...)>> {
86
86
// See PR #1413 for full details
87
87
} else {
88
88
// Check number of arguments of Python function
89
- auto getArgCount = [&](PyObject *obj) {
90
- // This is faster then doing import inspect and inspect.signature(obj).parameters
91
- auto *t = PyObject_GetAttrString (obj, " __code__" );
92
- auto *argCount = PyObject_GetAttrString (t, " co_argcount" );
93
- return PyLong_AsLong (argCount);
89
+ auto argCountFromFuncCode = [&](handle &obj) {
90
+ // This is faster then doing import inspect and
91
+ // inspect.signature(obj).parameters
92
+
93
+ object argCount = obj.attr (" co_argcount" );
94
+ return argCount.template cast <long >();
94
95
};
95
96
long argCount = -1 ;
96
97
97
- if (static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __code__" ))) {
98
- argCount = getArgCount (src.ptr ());
98
+ handle codeAttr = PyObject_GetAttrString (src.ptr (), " __code__" );
99
+ if (codeAttr) {
100
+ argCount = argCountFromFuncCode (codeAttr);
99
101
} else {
100
- if (static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __call__" ))) {
101
- auto *t2 = PyObject_GetAttrString (src.ptr (), " __call__" );
102
- argCount = getArgCount (t2) - 1 ; // we have to remove the self argument
102
+ handle callAttr = PyObject_GetAttrString (src.ptr (), " __call__" );
103
+ if (callAttr) {
104
+ handle codeAttr2 = callAttr.attr (" __code__" );
105
+ argCount = argCountFromFuncCode (codeAttr2)
106
+ - 1 ; // we have to remove the self argument
103
107
} else {
104
108
// No __code__ or __call__ attribute, this is not a proper Python function
105
109
return false ;
106
110
}
107
111
}
108
112
// if we are a method, we have to correct the argument count since we are not counting
109
113
// the self argument
110
- const int correctingSelfArgument
111
- = static_cast <bool >(PyMethod_Check (src.ptr ())) ? 1 : 0 ;
114
+ const int self_offset = static_cast <bool >(PyMethod_Check (src.ptr ())) ? 1 : 0 ;
112
115
113
- argCount -= correctingSelfArgument ;
116
+ argCount -= self_offset ;
114
117
if (argCount != sizeof ...(Args)) {
115
118
return false ;
116
119
}
0 commit comments