Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc81c3c3

Browse files
Fix kwarg func resolution (#1136)
Fix function resolution when calling overloads with keyword argumentsCo-authored-by: Benedikt Reinartz <filmor@gmail.com>
1 parent7870a9f commitc81c3c3

File tree

4 files changed

+120
-3
lines changed

4 files changed

+120
-3
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ details about the cause of the failure
2525

2626
- Fix incorrect dereference of wrapper object in`tp_repr`, which may result in a program crash
2727
- Fix incorrect dereference in params array handling
28+
- Fixes issue with function resolution when calling overloaded function with keyword arguments from python ([#1097][i1097])
2829
- Fix`object[]` parameters taking precedence when should not in overload resolution
2930
- Fixed a bug where all .NET class instances were considered Iterable
3031
- Fix incorrect choice of method to invoke when using keyword arguments.

‎src/runtime/methodbinder.cs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,23 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info)
279279
returnBind(inst,args,kw,info,null);
280280
}
281281

282+
privatereadonlystructMatchedMethod{
283+
publicMatchedMethod(intkwargsMatched,intdefaultsNeeded,object[]margs,intouts,MethodBasemb)
284+
{
285+
KwargsMatched=kwargsMatched;
286+
DefaultsNeeded=defaultsNeeded;
287+
ManagedArgs=margs;
288+
Outs=outs;
289+
Method=mb;
290+
}
291+
292+
publicintKwargsMatched{get;}
293+
publicintDefaultsNeeded{get;}
294+
publicobject[]ManagedArgs{get;}
295+
publicintOuts{get;}
296+
publicMethodBaseMethod{get;}
297+
}
298+
282299
internalBindingBind(IntPtrinst,IntPtrargs,IntPtrkw,MethodBaseinfo,MethodInfo[]methodinfo)
283300
{
284301
// loop to find match, return invoker w/ or /wo error
@@ -311,6 +328,8 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
311328
_methods=GetMethods();
312329
}
313330

331+
varargMatchedMethods=newList<MatchedMethod>(_methods.Length);
332+
314333
// TODO: Clean up
315334
foreach(MethodBasemiin_methods)
316335
{
@@ -321,8 +340,10 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
321340
ParameterInfo[]pi=mi.GetParameters();
322341
ArrayListdefaultArgList;
323342
boolparamsArray;
343+
intkwargsMatched;
344+
intdefaultsNeeded;
324345

325-
if(!MatchesArgumentCount(pynargs,pi,kwargDict,outparamsArray,outdefaultArgList))
346+
if(!MatchesArgumentCount(pynargs,pi,kwargDict,outparamsArray,outdefaultArgList,outkwargsMatched,outdefaultsNeeded))
326347
{
327348
continue;
328349
}
@@ -336,6 +357,47 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
336357
continue;
337358
}
338359

360+
varmatchedMethod=newMatchedMethod(kwargsMatched,defaultsNeeded,margs,outs,mi);
361+
argMatchedMethods.Add(matchedMethod);
362+
}
363+
if(argMatchedMethods.Count>0)
364+
{
365+
varbestKwargMatchCount=argMatchedMethods.Max(x=>x.KwargsMatched);
366+
varfewestDefaultsRequired=argMatchedMethods.Where(x=>x.KwargsMatched==bestKwargMatchCount).Min(x=>x.DefaultsNeeded);
367+
368+
intbestCount=0;
369+
intbestMatchIndex=-1;
370+
371+
for(intindex=0;index<argMatchedMethods.Count;index++)
372+
{
373+
vartestMatch=argMatchedMethods[index];
374+
if(testMatch.DefaultsNeeded==fewestDefaultsRequired&&testMatch.KwargsMatched==bestKwargMatchCount)
375+
{
376+
bestCount++;
377+
if(bestMatchIndex==-1)
378+
bestMatchIndex=index;
379+
}
380+
}
381+
382+
if(bestCount>1&&fewestDefaultsRequired>0)
383+
{
384+
// Best effort for determining method to match on gives multiple possible
385+
// matches and we need at least one default argument - bail from this point
386+
returnnull;
387+
}
388+
389+
// If we're here either:
390+
// (a) There is only one best match
391+
// (b) There are multiple best matches but none of them require
392+
// default arguments
393+
// in the case of (a) we're done by default. For (b) regardless of which
394+
// method we choose, all arguments are specified _and_ can be converted
395+
// from python to C# so picking any will suffice
396+
MatchedMethodbestMatch=argMatchedMethods[bestMatchIndex];
397+
varmargs=bestMatch.ManagedArgs;
398+
varouts=bestMatch.Outs;
399+
varmi=bestMatch.Method;
400+
339401
objecttarget=null;
340402
if(!mi.IsStatic&&inst!=IntPtr.Zero)
341403
{
@@ -575,11 +637,16 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
575637
staticboolMatchesArgumentCount(intpositionalArgumentCount,ParameterInfo[]parameters,
576638
Dictionary<string,IntPtr>kwargDict,
577639
outboolparamsArray,
578-
outArrayListdefaultArgList)
640+
outArrayListdefaultArgList,
641+
outintkwargsMatched,
642+
outintdefaultsNeeded)
579643
{
580644
defaultArgList=null;
581645
varmatch=false;
582646
paramsArray=parameters.Length>0?Attribute.IsDefined(parameters[parameters.Length-1],typeof(ParamArrayAttribute)):false;
647+
varkwargCount=kwargDict.Count;
648+
kwargsMatched=0;
649+
defaultsNeeded=0;
583650

584651
if(positionalArgumentCount==parameters.Length&&kwargDict.Count==0)
585652
{
@@ -599,6 +666,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
599666
// no need to check for a default parameter, but put a null
600667
// placeholder in defaultArgList
601668
defaultArgList.Add(null);
669+
kwargsMatched++;
602670
}
603671
elseif(parameters[v].IsOptional)
604672
{
@@ -607,6 +675,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
607675
// The GetDefaultValue() extension method will return the value
608676
// to be passed in as the parameter value
609677
defaultArgList.Add(parameters[v].GetDefaultValue());
678+
defaultsNeeded++;
610679
}
611680
elseif(!paramsArray)
612681
{

‎src/testing/methodtest.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,25 @@ public static string OptionalAndDefaultParams2([Optional]int a, [Optional]int b,
684684
returnstring.Format("{0}{1}{2}{3}",a,b,c,d);
685685
}
686686

687-
687+
publicstaticstringDefaultParamsWithOverloading(inta=2,intb=1)
688+
{
689+
return$"{a}{b}";
690+
}
691+
692+
publicstaticstringDefaultParamsWithOverloading(stringa="a",stringb="b")
693+
{
694+
return$"{a}{b}X";
695+
}
696+
697+
publicstaticstringDefaultParamsWithOverloading(inta=0,intb=1,intc=2)
698+
{
699+
return$"{a}{b}{c}XX";
700+
}
701+
702+
publicstaticstringDefaultParamsWithOverloading(inta=5,intb=6,intc=7,intd=8)
703+
{
704+
return$"{a}{b}{c}{d}XXX";
705+
}
688706
}
689707

690708

‎src/tests/test_method.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,35 @@ def test_optional_and_default_params():
11531153
res=MethodTest.OptionalAndDefaultParams2(b=2,c=3)
11541154
assertres=="0232"
11551155

1156+
deftest_default_params_overloads():
1157+
res=MethodTest.DefaultParamsWithOverloading(1,2)
1158+
assertres=="12"
1159+
1160+
res=MethodTest.DefaultParamsWithOverloading(b=5)
1161+
assertres=="25"
1162+
1163+
res=MethodTest.DefaultParamsWithOverloading("d")
1164+
assertres=="dbX"
1165+
1166+
res=MethodTest.DefaultParamsWithOverloading(b="c")
1167+
assertres=="acX"
1168+
1169+
res=MethodTest.DefaultParamsWithOverloading(c=3)
1170+
assertres=="013XX"
1171+
1172+
res=MethodTest.DefaultParamsWithOverloading(5,c=2)
1173+
assertres=="512XX"
1174+
1175+
res=MethodTest.DefaultParamsWithOverloading(c=0,d=1)
1176+
assertres=="5601XXX"
1177+
1178+
res=MethodTest.DefaultParamsWithOverloading(1,d=1)
1179+
assertres=="1671XXX"
1180+
1181+
deftest_default_params_overloads_ambiguous_call():
1182+
withpytest.raises(TypeError):
1183+
MethodTest.DefaultParamsWithOverloading()
1184+
11561185
deftest_keyword_arg_method_resolution():
11571186
fromPython.TestimportMethodArityTest
11581187

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp