| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Previously, if a class implemented an interface explicitly, those methods and properties become invisible to Python. To use them, you had to make an explicit cast to the interface type.
Sorry, something went wrong.
Codecov Report
@@ Coverage Diff @@
## master #1233 +/- ##
=======================================
Coverage 86.25% 86.25%
=======================================
Files 1 1
Lines 291 291
=======================================
Hits 251 251
Misses 40 40
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
Sorry, something went wrong.
|
I am not convinced this should be the expected behavior. Technically explicit interface implementations are private methods, and Python.NET does not expose them by design. Is there a scenario, where you can not cast your instance to the desired interface? Or do you just want duck typing for some reason? |
Sorry, something went wrong.
|
Ah, that explains it. I ran into this when trying to switch out IronPython in a project. Since it worked there I got the impression that it would work with Python.NET also. I did not know that external interface implementations are private. Thanks for the explanation! I'll see if there is a way I can do the casting automatically in our module loader, so that end users don't have to worry about it. |
Sorry, something went wrong.
|
@lostmsu Can you link some docs regarding the privacy of explicit interface implementations? I thought they were mainly used to get around name and signature conflicts, I wasn't aware of a semantic significance. |
Sorry, something went wrong.
|
@lostmsu : There's still an issue when a method returns an interface. If the returned object implements its interface explicitly, its methods becomes invisible to Python: public interface ISayHello1
{
string SayHello();
}
public class InterfaceTest2 : ISayHello1
{
public ISayHello1 GetISayHello1()
{
return this;
}
string ISayHello1.SayHello()
{
return "ISayHello1";
}
} def test_interface_object_returned_through_method():
"""Test explicitly implemented methods are visible"""
from Python.Test import InterfaceTest2
ob = InterfaceTest2()
hello1 = ob.GetISayHello1()
assert hello1.SayHello() == 'ISayHello1'This test fails with: > assert hello1.SayHello() == 'ISayHello1' E AttributeError: 'InterfaceTest2' object has no attribute 'SayHello' The caller of GetISayHello1 shouldn't really need to cast the returned object to ISayHello1. The method is already declared to return that type! It also adds to the confusion that casting is only sometimes necessary (namely when the interface has been explicitly implemented, something the caller should not need to know about). I'd be happy for advise on how to handle this. |
Sorry, something went wrong.
|
As said, I'm not aware of any semantic difference between the "usual" and explicit implementation of an interface, so IMO this change makes sense. |
Sorry, something went wrong.
|
The C# documentation ([1]) does say that:
So behaving differently in Python.NET might not be a good idea, although perhaps never a problem in practice. Could the issue with returning an interface from a method be solved some other way? e.g. by doing the same thing that we do when casting to the interface in Python when we convert the return value of a method to a Python value? |
Sorry, something went wrong.
|
@danabr you would need to postprocess after this line: pythonnet/src/runtime/methodbinder.cs Line 698 in 451fae6 and maybe in some other places. |
Sorry, something went wrong.
|
@lostmsu , @filmor : An approach "casting" the object to the interface type before returning it has been implemented in #1240. It comes with its own sets of things to consider. I'd be happy to hear your thoughts on that approach. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
What does this implement/fix? Explain your changes.
Previously, if a class implemented an interface explicitly, those
methods and properties become invisible to Python. To use them, you had
to make an explicit cast to the interface type.
Does this close any currently open issues?
No
Any other comments?
Checklist
Check all those that are applicable and complete.