mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-28 08:02:00 +00:00
changes from review
This commit is contained in:
parent
0235533fda
commit
d21cee39e8
@ -102,8 +102,8 @@ public:
|
||||
rec = c.get_pointer<function_record>();
|
||||
}
|
||||
while (rec != nullptr) {
|
||||
const int correctingSelfArgument = rec->is_method ? 1 : 0;
|
||||
if (rec->nargs - correctingSelfArgument != sizeof...(Args)) {
|
||||
const size_t self_offset = rec->is_method ? 1 : 0;
|
||||
if (rec->nargs != sizeof...(Args) + self_offset) {
|
||||
rec = rec->next;
|
||||
// if the overload is not feasible in terms of number of arguments, we
|
||||
// continue to the next one. If there is no next one, we return false.
|
||||
@ -129,20 +129,24 @@ public:
|
||||
// See PR #1413 for full details
|
||||
} else {
|
||||
// Check number of arguments of Python function
|
||||
auto getArgCount = [&](PyObject *obj) {
|
||||
// This is faster then doing import inspect and inspect.signature(obj).parameters
|
||||
auto *t = PyObject_GetAttrString(obj, "__code__");
|
||||
auto *argCount = PyObject_GetAttrString(t, "co_argcount");
|
||||
return PyLong_AsLong(argCount);
|
||||
};
|
||||
long argCount = -1;
|
||||
auto argCountFromFuncCode = [&](handle &obj) {
|
||||
// This is faster then doing import inspect and
|
||||
// inspect.signature(obj).parameters
|
||||
|
||||
if (static_cast<bool>(PyObject_HasAttrString(src.ptr(), "__code__"))) {
|
||||
argCount = getArgCount(src.ptr());
|
||||
object argCount = obj.attr("co_argcount");
|
||||
return argCount.template cast<size_t>();
|
||||
};
|
||||
size_t argCount = 0;
|
||||
|
||||
handle codeAttr = PyObject_GetAttrString(src.ptr(), "__code__");
|
||||
if (codeAttr) {
|
||||
argCount = argCountFromFuncCode(codeAttr);
|
||||
} else {
|
||||
if (static_cast<bool>(PyObject_HasAttrString(src.ptr(), "__call__"))) {
|
||||
auto *t2 = PyObject_GetAttrString(src.ptr(), "__call__");
|
||||
argCount = getArgCount(t2) - 1; // we have to remove the self argument
|
||||
handle callAttr = PyObject_GetAttrString(src.ptr(), "__call__");
|
||||
if (callAttr) {
|
||||
handle codeAttr2 = 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
|
||||
return false;
|
||||
@ -150,10 +154,9 @@ public:
|
||||
}
|
||||
// if we are a method, we have to correct the argument count since we are not counting
|
||||
// the self argument
|
||||
const int correctingSelfArgument
|
||||
= static_cast<bool>(PyMethod_Check(src.ptr())) ? 1 : 0;
|
||||
const size_t self_offset = static_cast<bool>(PyMethod_Check(src.ptr())) ? 1 : 0;
|
||||
|
||||
argCount -= correctingSelfArgument;
|
||||
argCount -= self_offset;
|
||||
if (argCount != sizeof...(Args)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -107,13 +107,23 @@ def test_cpp_correct_overload_resolution():
|
||||
def f(a):
|
||||
return a
|
||||
|
||||
class A:
|
||||
def __call__(self, a):
|
||||
return a
|
||||
|
||||
assert m.dummy_function_overloaded_std_func_arg(f) == 9
|
||||
assert m.dummy_function_overloaded_std_func_arg(A()) == 9
|
||||
assert m.dummy_function_overloaded_std_func_arg(lambda i: i) == 9
|
||||
|
||||
def f2(a, b):
|
||||
return a + b
|
||||
|
||||
class B:
|
||||
def __call__(self, a, b):
|
||||
return a + b
|
||||
|
||||
assert m.dummy_function_overloaded_std_func_arg(f2) == 14
|
||||
assert m.dummy_function_overloaded_std_func_arg(B()) == 14
|
||||
assert m.dummy_function_overloaded_std_func_arg(lambda i, j: i + j) == 14
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user