Skip to content

Commit d44f1da

Browse files
authored
Select correct method to invoke when keyword arguments are used (#1242)
If there were two methods with the same name, but with different arity, `Foo(a)` and `Foo(a,b)`, and the latter was called with a keyword argument `some.Foo(0, b=1)`, `Foo(0)` would be called instead of `Foo(0,1)`. Fixes #1235.
1 parent b5ba815 commit d44f1da

File tree

5 files changed

+16
-2
lines changed

5 files changed

+16
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ details about the cause of the failure
2222
- Fix incorrect dereference in params array handling
2323
- Fix `object[]` parameters taking precedence when should not in overload resolution
2424
- Fixed a bug where all .NET class instances were considered Iterable
25+
- Fix incorrect choice of method to invoke when using keyword arguments.
2526

2627
## [2.5.0][] - 2020-06-14
2728

src/runtime/constructorbinder.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info)
8989
// any extra args are intended for the subclass' __init__.
9090

9191
IntPtr eargs = Runtime.PyTuple_New(0);
92-
binding = Bind(inst, eargs, kw);
92+
binding = Bind(inst, eargs, IntPtr.Zero);
9393
Runtime.XDecref(eargs);
9494

9595
if (binding == null)

src/runtime/methodbinder.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
580580
var match = false;
581581
paramsArray = parameters.Length > 0 ? Attribute.IsDefined(parameters[parameters.Length - 1], typeof(ParamArrayAttribute)) : false;
582582

583-
if (positionalArgumentCount == parameters.Length)
583+
if (positionalArgumentCount == parameters.Length && kwargDict.Count == 0)
584584
{
585585
match = true;
586586
}

src/testing/methodtest.cs

+6
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,12 @@ public string PublicMethod(string echo)
699699
return echo;
700700
}
701701
}
702+
703+
public class MethodArityTest
704+
{
705+
public string Foo(int a) { return "Arity 1"; }
706+
public string Foo(int a, int b) { return "Arity 2"; }
707+
}
702708
}
703709

704710
namespace PlainOldNamespace

src/tests/test_method.py

+7
Original file line numberDiff line numberDiff line change
@@ -1149,3 +1149,10 @@ def test_optional_and_default_params():
11491149

11501150
res = MethodTest.OptionalAndDefaultParams2(b=2, c=3)
11511151
assert res == "0232"
1152+
1153+
def test_keyword_arg_method_resolution():
1154+
from Python.Test import MethodArityTest
1155+
1156+
ob = MethodArityTest()
1157+
assert ob.Foo(1, b=2) == "Arity 2"
1158+

0 commit comments

Comments
 (0)