From 29fccdb78d38e1b4f9352dea99273c93f713a24a Mon Sep 17 00:00:00 2001 From: Daniel Abrahamsson Date: Wed, 30 Sep 2020 07:47:49 +0200 Subject: [PATCH] Select correct method to invoke when keyword arguments are used 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. --- CHANGELOG.md | 1 + src/runtime/constructorbinder.cs | 2 +- src/runtime/methodbinder.cs | 2 +- src/testing/methodtest.cs | 6 ++++++ src/tests/test_method.py | 7 +++++++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0559c43c..0c48ecb90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ details about the cause of the failure - Fix incorrect dereference in params array handling - Fix `object[]` parameters taking precedence when should not in overload resolution - Fixed a bug where all .NET class instances were considered Iterable +- Fix incorrect choice of method to invoke when using keyword arguments. ## [2.5.0][] - 2020-06-14 diff --git a/src/runtime/constructorbinder.cs b/src/runtime/constructorbinder.cs index 0f9806c0e..973707f02 100644 --- a/src/runtime/constructorbinder.cs +++ b/src/runtime/constructorbinder.cs @@ -89,7 +89,7 @@ internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info) // any extra args are intended for the subclass' __init__. IntPtr eargs = Runtime.PyTuple_New(0); - binding = Bind(inst, eargs, kw); + binding = Bind(inst, eargs, IntPtr.Zero); Runtime.XDecref(eargs); if (binding == null) diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index 49bf5b171..df8579ca4 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -580,7 +580,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa var match = false; paramsArray = parameters.Length > 0 ? Attribute.IsDefined(parameters[parameters.Length - 1], typeof(ParamArrayAttribute)) : false; - if (positionalArgumentCount == parameters.Length) + if (positionalArgumentCount == parameters.Length && kwargDict.Count == 0) { match = true; } diff --git a/src/testing/methodtest.cs b/src/testing/methodtest.cs index 9a4c408d6..30e42ac9f 100644 --- a/src/testing/methodtest.cs +++ b/src/testing/methodtest.cs @@ -699,6 +699,12 @@ public string PublicMethod(string echo) return echo; } } + + public class MethodArityTest + { + public string Foo(int a) { return "Arity 1"; } + public string Foo(int a, int b) { return "Arity 2"; } + } } namespace PlainOldNamespace diff --git a/src/tests/test_method.py b/src/tests/test_method.py index c9fc89c7c..a358025a5 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -1149,3 +1149,10 @@ def test_optional_and_default_params(): res = MethodTest.OptionalAndDefaultParams2(b=2, c=3) assert res == "0232" + +def test_keyword_arg_method_resolution(): + from Python.Test import MethodArityTest + + ob = MethodArityTest() + assert ob.Foo(1, b=2) == "Arity 2" + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy