@@ -102,8 +102,8 @@ struct type_caster<std::function<Return(Args...)>> {
102
102
rec = c.get_pointer <function_record>();
103
103
}
104
104
while (rec != nullptr ) {
105
- const int correctingSelfArgument = rec->is_method ? 1 : 0 ;
106
- if (rec->nargs - correctingSelfArgument != sizeof ...(Args)) {
105
+ const size_t self_offset = rec->is_method ? 1 : 0 ;
106
+ if (rec->nargs != sizeof ...(Args) + self_offset ) {
107
107
rec = rec->next ;
108
108
// if the overload is not feasible in terms of number of arguments, we
109
109
// continue to the next one. If there is no next one, we return false.
@@ -129,31 +129,34 @@ struct type_caster<std::function<Return(Args...)>> {
129
129
// See PR #1413 for full details
130
130
} else {
131
131
// Check number of arguments of Python function
132
- auto getArgCount = [&](PyObject *obj) {
133
- // This is faster then doing import inspect and inspect.signature(obj).parameters
134
- auto *t = PyObject_GetAttrString (obj, " __code__" );
135
- auto *argCount = PyObject_GetAttrString (t, " co_argcount" );
136
- return PyLong_AsLong (argCount);
132
+ auto argCountFromFuncCode = [&](handle &obj) {
133
+ // This is faster then doing import inspect and
134
+ // inspect.signature(obj).parameters
135
+
136
+ object argCount = obj.attr (" co_argcount" );
137
+ return argCount.template cast <size_t >();
137
138
};
138
- long argCount = -1 ;
139
+ size_t argCount = -1 ;
139
140
140
- if (static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __code__" ))) {
141
- argCount = getArgCount (src.ptr ());
141
+ handle codeAttr = PyObject_GetAttrString (src.ptr (), " __code__" );
142
+ if (codeAttr) {
143
+ argCount = argCountFromFuncCode (codeAttr);
142
144
} else {
143
- if (static_cast <bool >(PyObject_HasAttrString (src.ptr (), " __call__" ))) {
144
- auto *t2 = PyObject_GetAttrString (src.ptr (), " __call__" );
145
- argCount = getArgCount (t2) - 1 ; // we have to remove the self argument
145
+ handle callAttr = PyObject_GetAttrString (src.ptr (), " __call__" );
146
+ if (callAttr) {
147
+ handle codeAttr2 = callAttr.attr (" __code__" );
148
+ argCount = argCountFromFuncCode (codeAttr2)
149
+ - 1 ; // we have to remove the self argument
146
150
} else {
147
151
// No __code__ or __call__ attribute, this is not a proper Python function
148
152
return false ;
149
153
}
150
154
}
151
155
// if we are a method, we have to correct the argument count since we are not counting
152
156
// the self argument
153
- const int correctingSelfArgument
154
- = static_cast <bool >(PyMethod_Check (src.ptr ())) ? 1 : 0 ;
157
+ const size_t self_offset = static_cast <bool >(PyMethod_Check (src.ptr ())) ? 1 : 0 ;
155
158
156
- argCount -= correctingSelfArgument ;
159
+ argCount -= self_offset ;
157
160
if (argCount != sizeof ...(Args)) {
158
161
return false ;
159
162
}
0 commit comments