Skip to content

Priority overload - #1131

Merged
henryiii merged 6 commits into
pybind:masterfrom
henryiii:priority_overload
Oct 6, 2020
Merged

Priority overload#1131
henryiii merged 6 commits into
pybind:masterfrom
henryiii:priority_overload

Conversation

@henryiii

@henryiiihenryiii commented Oct 9, 2017

Copy link
Copy Markdown
Collaborator

Adds py::prepend() as an optional tag when defining a function, which causes an added function to be prepended to the beginning of the overload chain. This can be used to override a default constructor that was provided earlier, for example. When combined with #1122, this will allow the default string (or the old int) constructors for enums to be replaced by users.

No performance penalty, it just prepends instead of appends to the call chain. Provides a possible solution to, and docs for, so closes#2537, so targeting 2.6.0 (related to the original use case, actually :) )

Also adds get_pointer/set_pointer for py::capsule.

@wjakob

Copy link
Copy Markdown
Member

Although I understand the motivation, I'm not in favor of this modification, which further increases the runtime cost and complexity of an already very complex dispatch routine. I think that we ought to make this part of pybind11 shorter and faster, not the other way.

@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

Does this increase the runtime? All it does is allow someone to attach a function at the beginning of the overload chain instead of the end, but the overload chain is the same length either way. It doesn't even increase the size of the struct, since there's one bit left over for alignment. So in the setup (runtime) phase, it adds one if statement.

This functionality seems useful in a more general case, where a user needs to pre-insert a call. But up to you.

@wjakob

Copy link
Copy Markdown
Member

Aha -- I misread the patch in that case. I was assuming that the priority tag was handled in the method dispatch function, but I see now that it is in the part of the code that creates Python function overloads.

I've recently heard from users who found that Boost.Python dispatches methods faster than pybind11 (!?!?), which still has me a bit concerned that we are piling on too much stuff.

@wjakob

Copy link
Copy Markdown
Member

One naming suggestion: how about calling it py::prepend or py::prepend_overload instead of priority_overload, which is IMO a bit more clear in terms of what happens (preventing question s like: "what does it mean to have two priority overloads?").

@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

I took the name from the original comment from @jagerman, I don't think he meant it to be final. I like py::prepend.

Unrelated: Any numbers or profile code for the boost Python comparison?

@jagerman

Copy link
Copy Markdown
Member

prepend sounds fine to me. priority_overload was just a spur-of-the-moment name.

@henryiiihenryiii changed the title Priority overloadWIP: Priority overloadOct 10, 2017
@wjakob

Copy link
Copy Markdown
Member

Unrelated: Any numbers or profile code for the boost Python comparison?

Unfortunately we don't currently have a good way of tracking performance over time, which is a bit of a concern. It would be nice to have a CI to catch performance regressions similarly to how we catch bugs with Travis and friends. I played around with Unladen Swallow at some point but haven't had enough free clock cycles to turn it into something useful.

Comment threadtests/test_methods_and_attributes.cpp Outdated
Comment threadtests/test_methods_and_attributes.py Outdated
Comment threadtests/test_methods_and_attributes.py Outdated
@jagerman

Copy link
Copy Markdown
Member

I've pushed a commit to your branch that ought to get this working (a86451d). Basically the start of the chain was only being half-updated: it also needed to be updated inside the capsule rec_capsule that gets bound as the self argument for dispatcher because dispatcher starts from that pointer, not the local chain_start variable (which only gets used to regenerate the docstring).

@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

FYI, I'll polish off the tests as soon as I get a chance, hopefully around this weekend.

@henryiiihenryiii changed the title WIP: Priority overloadPriority overloadApr 4, 2018
@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

@jagerman That was a very long weekend, but it should be ready for review finally!

@jagermanjagerman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two very minor comments, aside from those it looks good to me.

Comment threadinclude/pybind11/attr.h Outdated
Comment threadtests/test_methods_and_attributes.cpp Outdated
@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

Could this be useful in 2.3.0?

@henryiiihenryiii added this to the v2.6.0 milestone Oct 2, 2020
@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

Maybe we could also add a mention in the upgrade guide that __str__ on enums is now defined, so you need to use py::prepend() to override?

rwgk
rwgk approved these changes Oct 2, 2020

@rwgkrwgk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks great! I have just some minor naming suggestions.

Comment threadinclude/pybind11/attr.h Outdated
Comment threadinclude/pybind11/attr.h Outdated
Comment threaddocs/classes.rst Outdated

@YannickJadoulYannickJadoul left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should be rather painless, I think, yes :-)

Comment threadinclude/pybind11/pybind11.h
Comment threadinclude/pybind11/pybind11.h
rwgk
rwgk approved these changes Oct 4, 2020

@rwgkrwgk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This PR was included in Google-global testing: no issues found.

@wjakobwjakob left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The implementation looks all good to me, but documentation could be improved IMO.

Comment threaddocs/classes.rst Outdated
Comment threadinclude/pybind11/attr.h Outdated
@wjakob

Copy link
Copy Markdown
Member

(Really sorry that this has been stuck here in 2017. The flurry of recent activity has been wonderful -- thank you for all of your help! @henryiii@YannickJadoul@bstaletic@rwgk@EricCousineau-TRI and @ax3l)

@wjakob

Copy link
Copy Markdown
Member

My vote would also go for set_pointer btw, it promotes clarity.

I feel less strongly about the following: For consistency, we could also have a get_pointer. We will need to continue to provide the operator-based getter, but it could be implemented in terms of this new get_pointer function.

@henryiii

Copy link
Copy Markdown
CollaboratorAuthor

FWIW, I would be in favor of adding a .get_pointer() too, for consistency, and I think it's a bit more discoverable (ie, Xcode would show it in a completion list while conversions don't show up).

@henryiii
henryiiiforce-pushed the priority_overload branch 2 times, most recently from d34a67a to 92268fdCompareOctober 5, 2020 20:45
@henryiii
henryiii merged commit 9a0c96d into pybind:masterOct 6, 2020
@henryiii
henryiii deleted the priority_overload branch October 6, 2020 02:36
@rwgkrwgk mentioned this pull request Feb 9, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Allow for __str__ to be usable with enums (again)

5 participants

@henryiii@wjakob@jagerman@rwgk@YannickJadoul