Skip to content

Overload resolution incorrectly assumes any array parameter in last position is a params array #200

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

Closed
omnicognate opened this issue Apr 6, 2016 · 1 comment

Comments

@omnicognate
Copy link
Contributor

There is a trivial one-line fix for this, which I'll paste below. I've tested the fix and would like to have submitted a pull request, but I am unable do so due to proxy restrictions at work.

The problem arises when you have an overloading situation like the following:

void SomeFunc(int param1, int[] param2);
void SomeFunc(int param1, int param2, int param3);

and you make a call like SomeFunc(1,2,3).

During overload resolution, if pythonnet encounters an overload with fewer parameters than are supplied in the call, but whose last parameter is of array type, it assumes that the last parameter is a "params" array. i.e. it treats the first overload above as if it were declared:

void SomeFunc(int param1, params int[] param2);

The result is that pythonnet calls the first overload and passes the second and third arguments as a 2-element array in param2, when it should be calling the second overload and passing all three arguments normally. (The actual situation we are experiencing is more complex, but the above example should reproduce the behaviour.)

The fix belongs in methodbinder.cs. At line 271, there is the following code:

} else if ((pynargs > clrnargs) && (clrnargs > 0) &&
(pi[clrnargs-1].ParameterType.IsArray)) {
// The last argument of the mananged functions seems to
// accept multiple arguments as a array. Hopefully it's a
// spam(params object[] egg) style method

This needs to be changed to explicitly check for the case of a params array. The following replacement works for me:

} else if ((pynargs > clrnargs) && (clrnargs > 0) && 
              Attribute.IsDefined(pi[clrnargs-1], typeof(ParamArrayAttribute))) {
@omnicognate
Copy link
Contributor Author

I found a way to submit a pull request after all. Typing code on a mobile phone, what fun :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant