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

Enable user classes to override how Python.NET processes parameters of their functions#835

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

Closed
lostmsu wants to merge11 commits intopythonnet:masterfromlosttech:PR/PyArgConverter

Conversation

lostmsu
Copy link
Member

What does this implement/fix? Explain your changes.

This change introducesIPyArgumentConverter, that enables hooking into the
process of converting Python argument values into CLR types when invoking
.NET functions from Python. See anexample on the new wiki page.

If a user class needs custom conversion for the parameters of its functions, it can specify
the desired implementation ofIPyArgumentConverter usingPyArgConverter attribute
either on the class/struct, or for the entire assembly.

Does this close any currently open issues?

This implements#823

Any other comments?

This is but one option on how to achieve#823 . I am concerned, that it does not let users specify the converter per instance, and does not allow specifying converter for 3rd-party classes.

This change has an additional performance overhead on the firstBind call on each instance ofMethodBinder due to the need to look the attribute up.

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 (seean example)
  • Add yourself toAUTHORS
  • Updated theCHANGELOG

@codecov
Copy link

codecovbot commentedMar 28, 2019
edited
Loading

Codecov Report

❗ No coverage uploaded for pull request base (master@33db56d).Click here to learn what that means.
The diff coverage is86.58%.

Impacted file tree graph

@@           Coverage Diff            @@##             master    #835   +/-   ##========================================  Coverage          ?   65.2%           ========================================  Files             ?      66             Lines             ?    5970             Branches          ?     994           ========================================  Hits              ?    3893             Misses            ?    1719             Partials          ?     358
FlagCoverage Δ
#setup_linux65.3% <ø> (?)
#setup_windows64.43% <86.58%> (?)
Impacted FilesCoverage Δ
src/runtime/pyargconverter.cs81.81% <81.81%> (ø)
src/runtime/methodbinder.cs64.54% <87.09%> (ø)
src/runtime/defaultpyargconverter.cs87.5% <87.5%> (ø)

Continue to review full report at Codecov.

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

@lostmsulostmsu marked this pull request as ready for reviewMarch 28, 2019 23:39
Copy link
Member

@filmorfilmor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is already a huge step forward, thank you very much :)

Regarding your concerns, I can't think of a case where one would want per-instance conversion. In that case I'd rather extend the interface to pass the instance object along s.t. the converter can branch out on its own.

Third party conversion should be quite simple to add, I commented on the respective section.

using System.Reflection;

namespace Python.Runtime
{
using System.Linq;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Move this to the top.

?? method.DeclaringType?.Assembly
.GetCustomAttributes(typeof(PyArgConverterAttribute), inherit: false)
.OfType<PyArgConverterAttribute>()
.SingleOrDefault();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Here you could additionally introduce a "global" (maybe per engine) lookup table (class -> converter) into which one could register the marshalers even if one can't modify the declaring assembly.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Did not want to overoptimize at first. Weren't there some issues with AppDomains for global caches?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Oh yes, there is plenty of brokenness in that general direction, that's why I put the "(maybe per engine)" there. We have other global data though already, and for the one usecase of multiple AppDomains that I know of (reloading code in Unity) it works because they take down the PythonEngine and restart it, s.t. always exactly one is running. The comment was also more of a "fyi", not a requirement for merging :)

@filmorfilmor added this to the2.4.1 milestoneApr 12, 2019
@lostmsu
Copy link
MemberAuthor

The build is failing, but does not seem to be related to the changes in this PR.

@filmor
Copy link
Member

I've retriggered the build and will have a look at your changes :)

@lostmsu
Copy link
MemberAuthor

@filmor I've discovered, that this does not entirely cover my own use case as-is. Perhaps it needs more refining before upstreaming.

The use case I have is .NET wrapper classes for Python classes. E.g. classes in .NET, that have interface, that copies some Python class, and a singlePyObject field pointing to the actual Python object.

Problem I faced is that it is unclear what to do when a wrapper class is inherited.

// using default arg converterclassWrapper{PyObjectimpl;publicvirtualvoidOverridable(CustomTypeo)=>impl.overridable(o);publicvoidNonOverridable(CustomTypeo)=>impl.non_overridable(o);}[PyArgConverter(typeof(CustomArgConverter))]classUserDerived:Wrapper{publicoverridevoidOverridable(CustomTypeo)=>o.DoSomething();}

Now I send a wrapped instance ofUserDerived to Python code. While it is clear, that if Python callsOverridable on it, the argument should be converted usingCustomArgConverter, it is unclear what converter should be used in case Python callsNonOverridable.

In my use case,CustomArgConverter must be applied toNonOverridable too. However, the implementation in this PR will not do this, asNonOverridable.DeclaringType isWrapper, which does not havePyArgConverter attribute.

I can also see an opposite case, when the base class actually relies on using a specific converter.

@lostmsu
Copy link
MemberAuthor

Nevermind, I figured it out. It works as is.

@lostmsu
Copy link
MemberAuthor

lostmsu commentedJun 17, 2019
edited
Loading

@filmor do not rush this change. After playing a bit with it, I think we might need to changeinherit: false intoinherit: true, and add a couple of tests. The point being that the custom converter should be applied to derived classes automatically (which would be a breaking change if made later on).

Also, looks like it reformats.csproj file, which is unnecessary.

@filmor
Copy link
Member

Yeah, this one I saw as well. I just wanted to see how this fares test-wise against master :)

@lostmsu
Copy link
MemberAuthor

Hm, the .csproj change seems to be a result offda9499

@lostmsu
Copy link
MemberAuthor

Alrightie. Caught a bug in the original implementation, caused by partial initialization ofMethodBinder whenMethodInfo to be invoked is explicitly passed toBind. Should now be mergeable.

@codecov-io
Copy link

codecov-io commentedAug 23, 2019
edited
Loading

Codecov Report

Merging#835 intomaster willincrease coverage by0.04%.
The diff coverage is100%.

Impacted file tree graph

@@            Coverage Diff             @@##           master     #835      +/-   ##==========================================+ Coverage   86.71%   86.75%   +0.04%==========================================  Files           1        1                Lines         301      302       +1     ==========================================+ Hits          261      262       +1  Misses         40       40
FlagCoverage Δ
#setup_linux65.56% <100%> (+0.11%)⬆️
#setup_windows71.52% <100%> (+0.09%)⬆️
Impacted FilesCoverage Δ
setup.py86.75% <100%> (+0.04%)⬆️

Continue to review full report at Codecov.

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

@lostmsulostmsu requested a review fromfilmorAugust 23, 2019 00:38
@lostmsu
Copy link
MemberAuthor

@filmor , any chance you could review this? It is ready for merging.

@filmor
Copy link
Member

Could you rebase it on the current master? There was a change in the MethodBinder in between.

@lostmsu
Copy link
MemberAuthor

AppVeyor seems to have succeeded, but for some reason not being picked up:https://ci.appveyor.com/project/pythonnet/pythonnet/builds/28269629

@filmor rebased on master

@lostmsu
Copy link
MemberAuthor

@filmor review?

@lostmsulostmsu removed this from the2.4.1 milestoneFeb 27, 2020
@lostmsu
Copy link
MemberAuthor

Removed from 2.x, will review for 3.x. Might have been superseded by codecs#1022

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@filmorfilmorAwaiting requested review from filmor

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@lostmsu@filmor@codecov-io

[8]ページ先頭

©2009-2025 Movatter.jp