8000 Fix bug where the wrong overload is selected. by tonyroberts · Pull Request #151 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

Fix bug where the wrong overload is selected. #151

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 15, 2016
Merged
Changes from all 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
139 changes: 84 additions & 55 deletions src/runtime/methodbinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ internal void AddMethod(MethodBase m) {
//====================================================================

internal static MethodInfo MatchSignature(MethodInfo[] mi, Type[] tp) {
int count = tp.Length;
if (tp == null) {
return null;
}
int count = tp.Length;
for (int i = 0; i < mi.Length; i++) {
ParameterInfo[] pi = mi[i].GetParameters();
if (pi.Length != count) {
Expand Down Expand Up @@ -92,51 +95,54 @@ internal static MethodInfo MatchParameters(MethodInfo[] mi, Type[] tp) {
}


//====================================================================
// Given a sequence of MethodInfo and two sequences of type parameters,
// return the MethodInfo that matches the signature and the closed generic.
//====================================================================

internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp)
{
int genericCount = genericTp.Length;
int signatureCount = sigTp.Length;
for (int i = 0; i < mi.Length; i++)
{
if (!mi[i].IsGenericMethodDefinition)
{
continue;
}
Type[] genericArgs = mi[i].GetGenericArguments();
if (genericArgs.Length != genericCount)
{
continue;
}
ParameterInfo[] pi = mi[i].GetParameters();
if (pi.Length != signatureCount)
{
continue;
}
for (int n = 0; n < pi.Length; n++)
{
if (sigTp[n] != pi[n].ParameterType)
{
break;
}
if (n == (pi.Length - 1))
{
MethodInfo match = mi[i];
if (match.IsGenericMethodDefinition)
{
Type[] typeArgs = match.GetGenericArguments();
return match.MakeGenericMethod(genericTp);
}
return match;
}
}
}
return null;
}
//====================================================================
// Given a sequence of MethodInfo and two sequences of type parameters,
// return the MethodInfo that matches the signature and the closed generic.
//====================================================================

internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp)
{
if ((genericTp == null) || (sigTp == null)) {
return null;
}
int genericCount = genericTp.Length;
int signatureCount = sigTp.Length;
for (int i = 0; i < mi.Length; i++)
{
if (!mi[i].IsGenericMethodDefinition)
{
continue;
}
Type[] genericArgs = mi[i].GetGenericArguments();
if (genericArgs.Length != genericCount)
{
continue;
}
ParameterInfo[] pi = mi[i].GetParameters();
if (pi.Length != signatureCount)
{
continue;
}
for (int n = 0; n < pi.Length; n++)
{
if (sigTp[n] != pi[n].ParameterType)
{
break;
}
if (n == (pi.Length - 1))
{
MethodInfo match = mi[i];
if (match.IsGenericMethodDefinition)
{
Type[] typeArgs = match.GetGenericArguments();
return match.MakeGenericMethod(genericTp);
}
return match;
}
}
}
return null;
}


//====================================================================
Expand Down Expand Up @@ -239,9 +245,10 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
else {
_methods = GetMethods();
}

Type type;
for (int i = 0; i < _methods.Length; i++) {
MethodBase mi = _methods[i];

if (mi.IsGenericMethod) { isGeneric = true; }
ParameterInfo[] pi = mi.GetParameters();
int clrnargs = pi.Length;
Expand Down Expand Up @@ -275,19 +282,41 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,

for (int n = 0; n < clrnargs; n++) {
IntPtr op;
if (n < pynargs)
{
if (arrayStart == n)
{
if (n < pynargs) {
if (arrayStart == n) {
// map remaining Python arguments to a tuple since
// the managed function accepts it - hopefully :]
op = Runtime.PyTuple_GetSlice(args, arrayStart, pynargs);
}
else
{
else {
op = Runtime.PyTuple_GetItem(args, n);
}
Type type = pi[n].ParameterType;

// this logic below handles cases when multiple overloading methods
// are ambiguous, hence comparison between Python and CLR types
// is necessary
type = null;

if (_methods.Length>1) {
IntPtr pyoptype = IntPtr.Zero;
pyoptype = Runtime.PyObject_Type(op);
Exceptions.Clear();
if (pyoptype != IntPtr.Zero) { }
type = Converter.GetTypeByAlias(pyoptype);
Runtime.Decref(pyoptype);
}


if (type != null) {
if (pi[n].ParameterType != type) {
margs = null;
break;
}
}
else {
type = pi[n].ParameterType;
}

if (pi[n].IsOut || type.IsByRef)
{
outs++;
Expand Down Expand Up @@ -348,7 +377,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
MethodInfo mi = MethodBinder.MatchParameters(methodinfo, types);
return Bind(inst, args, kw, mi, null);
}
return null;
return null;
}

internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {
Expand Down
0