Skip to content

Method precedence #552

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
AlexCatarino opened this issue Oct 4, 2017 · 8 comments
Closed

Method precedence #552

AlexCatarino opened this issue Oct 4, 2017 · 8 comments

Comments

@AlexCatarino
Copy link
Contributor

Environment

  • Pythonnet version: 2.4.0
  • Python version: 2.7
  • Operating System: Windows 10

Details

We have a series of overloads for a given method in existing base class and we want to add new overloads that should take precedence. To be more precise, we have the following case:
public IEnumerable<Slice> History(int periods)
that is consumed by C# classes and we have
public PyObject History(int periods)
that is consumed by Python classes
To achieve it, we have created a subclass where the second overload is defined:

public class QCAlgorithm
{
    public IEnumerable<Slice> History(int periods) 
    {
    }
}
public class QCPyAlgorithm : QCAlgorithm
{
    public new PyObject History(int periods) 
    {
    }
}

When we use reflection to get the methods from QCPyAlgorithm, the new method comes first. However, after the sorting performed by pythonnet here, the method from QCAlgorithm comes first. Consequently it is called in my python script and returns an enumerable of Slice.

The issue/question is:
How do I keep the methods from the declaring type on the top of the list of methods are try to bind?

My first guess is to send the first overload behind by adding the following line in the GetPrecedence method:

val += mi.DeclaringType == mi.ReflectedType ? 0 : 3000;
@den-run-ai
Copy link
Contributor

den-run-ai commented Oct 5, 2017 via email

@AlexCatarino
Copy link
Contributor Author

In our particular case (QuantConnect/Lean), we want users coding in C# and Python to use the exact same method call. We don't want them to learn all the overloads or use a different method signature.

@filmor
Copy link
Member

filmor commented Oct 27, 2017

You can fix the method sorting by not trying to do it via a mere .Sort call but instead by building that list yourself, starting with the reflected type and going upwards in the inheritance tree, appending the methods (sorted using the existing MethodSorter) as you go.

I usually don't expose the .NET objects directly to the user and instead wrap it in a more pythonic library, essentially using Python.NET as an FFI, that's another option.

@den-run-ai
Copy link
Contributor

#552

@den-run-ai
Copy link
Contributor

fix merged

@christabella
Copy link
Contributor

I usually don't expose the .NET objects directly to the user and instead wrap it in a more pythonic library, essentially using Python.NET as an FFI, that's another option.

@filmor I'm interested in using Python.NET as an FFI, do you have any resources for doing so, or should I refer to your repo https://github.com/filmor/clr-loader/ as an example of what you meant? Thank you!

@filmor
Copy link
Member

filmor commented Nov 4, 2020

@christabella This is unrelated to clr-loader. What I meant is that I usually don't expose the objects directly to the users, e.g.:

public class SomeClass {
    public int SomeMethod(string param) { ... }
}
from My.Dotnet.Library import SomeClass as ClrSomeClass

class SomeClass:
    def __init__(self):
        self._clr_instance = ClrSomeClass()

    def some_method(self, param):
        return self._clr_instance.SomeMethod(param)

@christabella
Copy link
Contributor

@filmor thank you for the illuminating example, this looks like a great solution for keeping the Python interface clean while using Python.NET to load CLR namespaces as Python packages!

Just in case, do you have any examples of this pattern in action? (I was looking at QuantConnect/Lean repo mentioned earlier in this thread but maybe it's not exactly what you meant)

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

4 participants