| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c4238d9 commit fabb22c
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,16 +86,17 @@ internal void AddMethod(MethodBase m) | |||
| 86 | 86 | ||
| 87 | 87 | /// <summary> | |
| 88 | 88 | /// Given a sequence of MethodInfo and a sequence of type parameters, | |
| 89 | - /// return the MethodInfo that represents the matching closed generic. | ||
| 89 | + /// return the MethodInfo(s) that represents the matching closed generic. | ||
| 90 | 90 | /// If unsuccessful, returns null and may set a Python error. | |
| 91 | 91 | /// </summary> | |
| 92 | - internal static MethodInfo? MatchParameters(MethodBase[] mi, Type[]? tp) | ||
| 92 | + internal static MethodInfo[] MatchParameters(MethodBase[] mi, Type[]? tp) | ||
| 93 | 93 | { | |
| 94 | 94 | if (tp == null) | |
| 95 | 95 | { | |
| 96 | - return null; | ||
| 96 | + return Array.Empty<MethodInfo>(); | ||
| 97 | 97 | } | |
| 98 | 98 | int count = tp.Length; | |
| 99 | + var result = new List<MethodInfo>(); | ||
| 99 | 100 | foreach (MethodInfo t in mi) | |
| 100 | 101 | { | |
| 101 | 102 | if (!t.IsGenericMethodDefinition) | |
@@ -111,16 +112,14 @@ internal void AddMethod(MethodBase m) | |||
| 111 | 112 | { | |
| 112 | 113 | // MakeGenericMethod can throw ArgumentException if the type parameters do not obey the constraints. | |
| 113 | 114 | MethodInfo method = t.MakeGenericMethod(tp); | |
| 114 | - Exceptions.Clear(); | ||
| 115 | - return method; | ||
| 115 | + result.Add(method); | ||
| 116 | 116 | } | |
| 117 | - catch (ArgumentException e) | ||
| 117 | + catch (ArgumentException) | ||
| 118 | 118 | { | |
| 119 | - Exceptions.SetError(e); | ||
| 120 | 119 | // The error will remain set until cleared by a successful match. | |
| 121 | 120 | } | |
| 122 | 121 | } | |
| 123 | - return null; | ||
| 122 | + return result.ToArray(); | ||
| 124 | 123 | } | |
| 125 | 124 | ||
| 126 | 125 | ||
@@ -381,9 +380,6 @@ public MismatchedMethod(Exception exception, MethodBase mb) | |||
| 381 | 380 | } | |
| 382 | 381 | } | |
| 383 | 382 | ||
| 384 | - var pynargs = (int)Runtime.PyTuple_Size(args); | ||
| 385 | - var isGeneric = false; | ||
| 386 | - | ||
| 387 | 383 | MethodBase[] _methods; | |
| 388 | 384 | if (info != null) | |
| 389 | 385 | { | |
@@ -395,11 +391,19 @@ public MismatchedMethod(Exception exception, MethodBase mb) | |||
| 395 | 391 | _methods = GetMethods(); | |
| 396 | 392 | } | |
| 397 | 393 | ||
| 398 | - var argMatchedMethods = new List<MatchedMethod>(_methods.Length); | ||
| 394 | + return Bind(inst, args, kwargDict, _methods, matchGenerics: true); | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + static Binding? Bind(BorrowedReference inst, BorrowedReference args, Dictionary<string, PyObject> kwargDict, MethodBase[] methods, bool matchGenerics) | ||
| 398 | + { | ||
| 399 | + var pynargs = (int)Runtime.PyTuple_Size(args); | ||
| 400 | + var isGeneric = false; | ||
| 401 | + | ||
| 402 | + var argMatchedMethods = new List<MatchedMethod>(methods.Length); | ||
| 399 | 403 | var mismatchedMethods = new List<MismatchedMethod>(); | |
| 400 | 404 | ||
| 401 | 405 | // TODO: Clean up | |
| 402 | - foreach (MethodBase mi in _methods) | ||
| 406 | + foreach (MethodBase mi in methods) | ||
| 403 | 407 | { | |
| 404 | 408 | if (mi.IsGenericMethod) | |
| 405 | 409 | { | |
@@ -535,17 +539,17 @@ public MismatchedMethod(Exception exception, MethodBase mb) | |||
| 535 | 539 | ||
| 536 | 540 | return new Binding(mi, target, margs, outs); | |
| 537 | 541 | } | |
| 538 | - else if (isGeneric && info == null && methodinfo != null) | ||
| 542 | + else if (matchGenerics && isGeneric) | ||
| 539 | 543 | { | |
| 540 | 544 | // We weren't able to find a matching method but at least one | |
| 541 | 545 | // is a generic method and info is null. That happens when a generic | |
| 542 | 546 | // method was not called using the [] syntax. Let's introspect the | |
| 543 | 547 | // type of the arguments and use it to construct the correct method. | |
| 544 | 548 | Type[]? types = Runtime.PythonArgsToTypeArray(args, true); | |
| 545 | - MethodInfo? mi = MatchParameters(methodinfo, types); | ||
| 546 | - if (mi != null) | ||
| 549 | + MethodInfo[] overloads = MatchParameters(methods, types); | ||
| 550 | + if (overloads.Length != 0) | ||
| 547 | 551 | { | |
| 548 | - return Bind(inst, args, kw, mi, null); | ||
| 552 | + return Bind(inst, args, kwargDict, overloads, matchGenerics: false); | ||
| 549 | 553 | } | |
| 550 | 554 | } | |
| 551 | 555 | if (mismatchedMethods.Count > 0) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,15 +43,18 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference | |||
| 43 | 43 | return Exceptions.RaiseTypeError("type(s) expected"); | |
| 44 | 44 | } | |
| 45 | 45 | ||
| 46 | - MethodBase? mi = self.m.IsInstanceConstructor | ||
| 47 | - ? self.m.type.Value.GetConstructor(types) | ||
| 46 | + MethodBase[] overloads = self.m.IsInstanceConstructor | ||
| 47 | + ? self.m.type.Value.GetConstructor(types) is { } ctor | ||
| 48 | + ? new[] { ctor } | ||
| 49 | + : Array.Empty<MethodBase>() | ||
| 48 | 50 | : MethodBinder.MatchParameters(self.m.info, types); | |
| 49 | - if (mi == null) | ||
| 51 | + if (overloads.Length == 0) | ||
| 50 | 52 | { | |
| 51 | 53 | return Exceptions.RaiseTypeError("No match found for given type params"); | |
| 52 | 54 | } | |
| 53 | 55 | ||
| 54 | - var mb = new MethodBinding(self.m, self.target, self.targetType) { info = mi }; | ||
| 56 | + MethodObject overloaded = self.m.WithOverloads(overloads); | ||
| 57 | + var mb = new MethodBinding(overloaded, self.target, self.targetType); | ||
| 55 | 58 | return mb.Alloc(); | |
| 56 | 59 | } | |
| 57 | 60 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,7 @@ internal class MethodObject : ExtensionType | |||
| 27 | 27 | internal PyString? doc; | |
| 28 | 28 | internal MaybeType type; | |
| 29 | 29 | ||
| 30 | - public MethodObject(Type type, string name, MethodBase[] info, bool allow_threads = MethodBinder.DefaultAllowThreads) | ||
| 30 | + public MethodObject(MaybeType type, string name, MethodBase[] info, bool allow_threads = MethodBinder.DefaultAllowThreads) | ||
| 31 | 31 | { | |
| 32 | 32 | this.type = type; | |
| 33 | 33 | this.name = name; | |
@@ -47,6 +47,9 @@ public MethodObject(Type type, string name, MethodBase[] info, bool allow_thread | |||
| 47 | 47 | ||
| 48 | 48 | public bool IsInstanceConstructor => name == "__init__"; | |
| 49 | 49 | ||
| 50 | + public MethodObject WithOverloads(MethodBase[] overloads) | ||
| 51 | + => new(type, name, overloads, allow_threads: binder.allow_threads); | ||
| 52 | + | ||
| 50 | 53 | internal MethodBase[] info | |
| 51 | 54 | { | |
| 52 | 55 | get | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -646,6 +646,9 @@ public static int Overloaded(int i, string s) | |||
| 646 | 646 | return i; | |
| 647 | 647 | } | |
| 648 | 648 | ||
| 649 | + public virtual void OverloadedConstrainedGeneric<T>(T generic) where T : MethodTest { } | ||
| 650 | + public virtual void OverloadedConstrainedGeneric<T>(T generic, string str) where T: MethodTest { } | ||
| 651 | + | ||
| 649 | 652 | public static string CaseSensitive() | |
| 650 | 653 | { | |
| 651 | 654 | return "CaseSensitive"; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -762,6 +762,18 @@ def test_missing_generic_type(): | |||
| 762 | 762 | with pytest.raises(TypeError): | |
| 763 | 763 | IList[bool] | |
| 764 | 764 | ||
| 765 | + # https://github.com/pythonnet/pythonnet/issues/1522 | ||
| 766 | + def test_overload_generic_parameter(): | ||
| 767 | + from Python.Test import MethodTest, MethodTestSub | ||
| 768 | + | ||
| 769 | + inst = MethodTest() | ||
| 770 | + generic = MethodTestSub() | ||
| 771 | + inst.OverloadedConstrainedGeneric(generic) | ||
| 772 | + inst.OverloadedConstrainedGeneric[MethodTestSub](generic) | ||
| 773 | + | ||
| 774 | + inst.OverloadedConstrainedGeneric[MethodTestSub](generic, '42') | ||
| 775 | + inst.OverloadedConstrainedGeneric[MethodTestSub](generic, System.String('42')) | ||
| 776 | + | ||
| 765 | 777 | def test_invalid_generic_type_parameter(): | |
| 766 | 778 | from Python.Test import GenericTypeWithConstraint | |
| 767 | 779 | with pytest.raises(TypeError): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments