Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Explicit interface implementations#1233

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

danabr
Copy link
Contributor

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.

  • Make sure to include one or more tests for your change
  • If an enhancement PR, please create docs and at best an example
  • Add yourself toAUTHORS
  • Updated theCHANGELOG

Previously, if a class implemented an interface explicitly, thosemethods and properties become invisible to Python. To use them, you hadto make an explicit cast to the interface type.
@dnfadmin
Copy link

dnfadmin commentedSep 23, 2020
edited
Loading

CLA assistant check
All CLA requirements met.

@codecov-commenter
Copy link

codecov-commenter commentedSep 23, 2020
edited
Loading

Codecov Report

Merging#1233 intomaster willnot change coverage.
The diff coverage isn/a.

Impacted file tree graph

@@           Coverage Diff           @@##           master    #1233   +/-   ##=======================================  Coverage   86.25%   86.25%           =======================================  Files           1        1             Lines         291      291           =======================================  Hits          251      251             Misses         40       40
FlagCoverage Δ
#setup_linux64.94% <ø> (ø)
#setup_windows72.50% <ø> (ø)

Flags with carried forward coverage won't be shown.Click here to find out more.


Continue to review full report at Codecov.

Legend -Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing data
Powered byCodecov. Last update451fae6...080d0c1. Read thecomment docs.

@lostmsu
Copy link
Member

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?

@danabr
Copy link
ContributorAuthor

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.

@danabrdanabr closed thisSep 24, 2020
@filmor
Copy link
Member

@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.

@danabr
Copy link
ContributorAuthor

danabr commentedSep 24, 2020
edited
Loading

@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:

publicinterfaceISayHello1{stringSayHello();}publicclassInterfaceTest2:ISayHello1{publicISayHello1GetISayHello1(){returnthis;}stringISayHello1.SayHello(){return"ISayHello1";}}
deftest_interface_object_returned_through_method():"""Test explicitly implemented methods are visible"""fromPython.TestimportInterfaceTest2ob=InterfaceTest2()hello1=ob.GetISayHello1()asserthello1.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 toISayHello1. 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.

@lostmsu
Copy link
Member

@danabr this actually seems a legitimate reason for a change. When method explicitly returns an interface type, Python should see the object as an instance of that interface with all its methods available.@filmor thoughts?

@filmor
Copy link
Member

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.

@filmorfilmor reopened thisSep 24, 2020
@danabr
Copy link
ContributorAuthor

The C# documentation ([1]) does say that:

It's possible to implement an interface member explicitly—creating a class member that is only called through the interface, and is specific to that interface.
[...]
The class member IControl.Paint is only available through the IControl interface, and ISurface.Paint is only available through ISurface. Both method implementations are separate, and neither are available directly on the class.

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?

[1]https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation

filmor reacted with thumbs up emoji

@lostmsu
Copy link
Member

lostmsu commentedSep 24, 2020
edited
Loading

@danabr you would need to postprocess after this line:

result=binding.info.Invoke(binding.inst,BindingFlags.Default,null,binding.args,null);

and maybe in some other places.

@danabr
Copy link
ContributorAuthor

@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.

@lostmsulostmsu closed thisOct 1, 2020
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

5 participants
@danabr@dnfadmin@codecov-commenter@lostmsu@filmor

[8]ページ先頭

©2009-2025 Movatter.jp