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

Improved support for generic method overloading#1657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lostmsu merged 1 commit intopythonnet:masterfromlosttech:bugs/1522
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletionssrc/runtime/methodbinder.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -86,16 +86,17 @@ internal void AddMethod(MethodBase m)

/// <summary>
/// Given a sequence of MethodInfo and a sequence of type parameters,
/// return the MethodInfo that represents the matching closed generic.
/// return the MethodInfo(s) that represents the matching closed generic.
/// If unsuccessful, returns null and may set a Python error.
/// </summary>
internal static MethodInfo? MatchParameters(MethodBase[] mi, Type[]? tp)
internal static MethodInfo[] MatchParameters(MethodBase[] mi, Type[]? tp)
{
if (tp == null)
{
returnnull;
returnArray.Empty<MethodInfo>();
}
int count = tp.Length;
var result = new List<MethodInfo>();
foreach (MethodInfo t in mi)
{
if (!t.IsGenericMethodDefinition)
Expand All@@ -111,16 +112,14 @@ internal void AddMethod(MethodBase m)
{
// MakeGenericMethod can throw ArgumentException if the type parameters do not obey the constraints.
MethodInfo method = t.MakeGenericMethod(tp);
Exceptions.Clear();
return method;
result.Add(method);
}
catch (ArgumentException e)
catch (ArgumentException)
{
Exceptions.SetError(e);
// The error will remain set until cleared by a successful match.
}
}
returnnull;
returnresult.ToArray();
}


Expand DownExpand Up@@ -381,9 +380,6 @@ public MismatchedMethod(Exception exception, MethodBase mb)
}
}

var pynargs = (int)Runtime.PyTuple_Size(args);
var isGeneric = false;

MethodBase[] _methods;
if (info != null)
{
Expand All@@ -395,11 +391,19 @@ public MismatchedMethod(Exception exception, MethodBase mb)
_methods = GetMethods();
}

var argMatchedMethods = new List<MatchedMethod>(_methods.Length);
return Bind(inst, args, kwargDict, _methods, matchGenerics: true);
}

static Binding? Bind(BorrowedReference inst, BorrowedReference args, Dictionary<string, PyObject> kwargDict, MethodBase[] methods, bool matchGenerics)
{
var pynargs = (int)Runtime.PyTuple_Size(args);
var isGeneric = false;

var argMatchedMethods = new List<MatchedMethod>(methods.Length);
var mismatchedMethods = new List<MismatchedMethod>();

// TODO: Clean up
foreach (MethodBase mi in_methods)
foreach (MethodBase mi inmethods)
{
if (mi.IsGenericMethod)
{
Expand DownExpand Up@@ -535,17 +539,17 @@ public MismatchedMethod(Exception exception, MethodBase mb)

return new Binding(mi, target, margs, outs);
}
else if (isGeneric &&info == null && methodinfo != null)
else if (matchGenerics &&isGeneric)
{
// We weren't able to find a matching method but at least one
// is a generic method and info is null. That happens when a generic
// method was not called using the [] syntax. Let's introspect the
// type of the arguments and use it to construct the correct method.
Type[]? types = Runtime.PythonArgsToTypeArray(args, true);
MethodInfo? mi = MatchParameters(methodinfo, types);
if (mi !=null)
MethodInfo[] overloads = MatchParameters(methods, types);
if (overloads.Length !=0)
{
return Bind(inst, args,kw, mi, null);
return Bind(inst, args,kwargDict, overloads, matchGenerics: false);
}
}
if (mismatchedMethods.Count > 0)
Expand Down
11 changes: 7 additions & 4 deletionssrc/runtime/methodbinding.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,15 +43,18 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference
return Exceptions.RaiseTypeError("type(s) expected");
}

MethodBase? mi = self.m.IsInstanceConstructor
? self.m.type.Value.GetConstructor(types)
MethodBase[] overloads = self.m.IsInstanceConstructor
? self.m.type.Value.GetConstructor(types) is { } ctor
? new[] { ctor }
: Array.Empty<MethodBase>()
: MethodBinder.MatchParameters(self.m.info, types);
if (mi ==null)
if (overloads.Length ==0)
{
return Exceptions.RaiseTypeError("No match found for given type params");
}

var mb = new MethodBinding(self.m, self.target, self.targetType) { info = mi };
MethodObject overloaded = self.m.WithOverloads(overloads);
var mb = new MethodBinding(overloaded, self.target, self.targetType);
return mb.Alloc();
}

Expand Down
5 changes: 4 additions & 1 deletionsrc/runtime/methodobject.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,7 +27,7 @@ internal class MethodObject : ExtensionType
internal PyString? doc;
internal MaybeType type;

public MethodObject(Type type, string name, MethodBase[] info, bool allow_threads = MethodBinder.DefaultAllowThreads)
public MethodObject(MaybeType type, string name, MethodBase[] info, bool allow_threads = MethodBinder.DefaultAllowThreads)
{
this.type = type;
this.name = name;
Expand All@@ -47,6 +47,9 @@ public MethodObject(Type type, string name, MethodBase[] info, bool allow_thread

public bool IsInstanceConstructor => name == "__init__";

public MethodObject WithOverloads(MethodBase[] overloads)
=> new(type, name, overloads, allow_threads: binder.allow_threads);

internal MethodBase[] info
{
get
Expand Down
3 changes: 3 additions & 0 deletionssrc/testing/methodtest.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -646,6 +646,9 @@ public static int Overloaded(int i, string s)
return i;
}

public virtual void OverloadedConstrainedGeneric<T>(T generic) where T : MethodTest { }
public virtual void OverloadedConstrainedGeneric<T>(T generic, string str) where T: MethodTest { }

public static string CaseSensitive()
{
return "CaseSensitive";
Expand Down
12 changes: 12 additions & 0 deletionstests/test_generic.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -762,6 +762,18 @@ def test_missing_generic_type():
with pytest.raises(TypeError):
IList[bool]

# https://github.com/pythonnet/pythonnet/issues/1522
def test_overload_generic_parameter():
from Python.Test import MethodTest, MethodTestSub

inst = MethodTest()
generic = MethodTestSub()
inst.OverloadedConstrainedGeneric(generic)
inst.OverloadedConstrainedGeneric[MethodTestSub](generic)

inst.OverloadedConstrainedGeneric[MethodTestSub](generic, '42')
inst.OverloadedConstrainedGeneric[MethodTestSub](generic, System.String('42'))

def test_invalid_generic_type_parameter():
from Python.Test import GenericTypeWithConstraint
with pytest.raises(TypeError):
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp