You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pythonnet 3.0 breaks access to methods whos signature returns an interface but clients want to use the concrete type #1914
tldr; #1240 changes the behavior of pythonnet to wrap only the interface methods/members of objects returned by a .NET method whose method declaration states that it returns an interface. Prior to this change, the python object that pythonnet created for the return object wrapped the returned object instance, but did not necessarily implement the interface. The prior behavior was useful for idiomatic C# patterns like the factory pattern.
My preferred fix, for what its worth, is option 4 (from the list of options mentioned by Victor in that thread):
IronPython apparently allows explicit interface implementations to be called (instead of returning interface-wrapped instances), if there’s no conflict with regular methods. Perhaps we should consider this as an option.
changed the title [-]pythonnet 3.0 breaks idiomatic C# patterns[/-][+]pythonnet 3.0 breaks access to methods whos signature returns an interface but clients want to use the concrete type[/+]on Aug 15, 2022
What you are proposing is not an idiomatic C# pattern. In C# if you get an instance of interface returned from a method, you have to cast it to a specific type before you can call public methods that are not part of the interface.
Inhowfar? It's exactly like it is in C#: You ask for an ISomething and you get one back. If you wanted the behaviour you are asking for, you'd use dynamic or cast explicitly.I don't think we support either of this nicely right now, but both options would be preferable, IMO.
@filmor dynamically typed languages don't have return types, so what you get back is always some concrete implementation.
Anyways - I prefer not to get into a philosophical debate here, sorry for inviting one by using the term idiomatic earlier in the thread. This is mostly a practical problem when interfacing a C# library with python using pythonnet without having to rewrite the C# library (in many cases the development of the python interface and the C# library may be handled by separate teams or organizations).
Logically, you can think of the return value in this case the same way as a super object, e.g. super(IInterface, obj) except you can also unwrap the result and get obj out of it. The super object does not permit access to obj members outside of IInterface.
I think we agree from the maintainer side that we are not going to change this behaviour. Adding an explicit cast (clr.cast[SomeType](result) or a "make this dynamic" (clr.dynamic(result)) would definitely be an option, though.
Activity
[-]pythonnet 3.0 breaks idiomatic C# patterns[/-][+]pythonnet 3.0 breaks access to methods whos signature returns an interface but clients want to use the concrete type[/+]lostmsu commentedon Aug 16, 2022
What you are proposing is not an idiomatic C# pattern. In C# if you get an instance of interface returned from a method, you have to cast it to a specific type before you can call public methods that are not part of the interface.
koubaa commentedon Aug 17, 2022
@lostmsu fair point. It's idiomatic for dynamically typed languages, which C# is not. I do still think the current behavior is problematic.
filmor commentedon Aug 17, 2022
Inhowfar? It's exactly like it is in C#: You ask for an
ISomethingand you get one back. If you wanted the behaviour you are asking for, you'd usedynamicor cast explicitly.I don't think we support either of this nicely right now, but both options would be preferable, IMO.koubaa commentedon Aug 18, 2022
@filmor dynamically typed languages don't have return types, so what you get back is always some concrete implementation.
Anyways - I prefer not to get into a philosophical debate here, sorry for inviting one by using the term idiomatic earlier in the thread. This is mostly a practical problem when interfacing a C# library with python using pythonnet without having to rewrite the C# library (in many cases the development of the python interface and the C# library may be handled by separate teams or organizations).
lostmsu commentedon Aug 21, 2022
Logically, you can think of the return value in this case the same way as a
superobject, e.g.super(IInterface, obj)except you can also unwrap the result and getobjout of it. Thesuperobject does not permit access toobjmembers outside ofIInterface.filmor commentedon Sep 14, 2022
I think we agree from the maintainer side that we are not going to change this behaviour. Adding an explicit cast (
clr.cast[SomeType](result)or a "make this dynamic" (clr.dynamic(result)) would definitely be an option, though.