Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow python builtins to be used as callbacks #1413

Merged
merged 20 commits into from
Jul 27, 2021

Conversation

davidhewitt
Copy link
Contributor

@davidhewitt davidhewitt commented May 26, 2018

At the moment when passing python builtins like sum() as callback functions to c++, the std::function caster will fail with RuntimeError: Unable to extract capsule contents. This is because of the machinery to extract stateless c++ function pointers to avoid the c++ -> python -> c++ overhead.

I've added a simple check that the definition being extracted is indeed a capsule and an accompanying test that I can now use sum() as a callback. Hope you find this useful.

Suggested changelog entry:

Allow Python builtins to be used as callbacks in CPython

@jagerman
Copy link
Member

The change looks good to me. There's one minor change needed in the added python test to fix the flake warning (two blank lines needed before the added test).

@davidhewitt
Copy link
Contributor Author

Great, I'll find a moment to tidy that up at the weekend!

@davidhewitt
Copy link
Contributor Author

@jagerman should be all good now. Thanks

@davidhewitt
Copy link
Contributor Author

@jagerman just wanted to make sure this wasn't forgotten - I still run into this every so often.

@TobiasBruell
Copy link

I just ran into the same problem. Many thanks!

@lycantropos
Copy link

what about progress on this one?

@YannickJadoul
Copy link
Collaborator

what about progress on this one?

We're in the middle of cleaning up issues and PRs. Give us a little bit of time, please.

If you want to help this PR progress, fixing the merge conflicts would help us greatly! :-)

@Skylion007 Skylion007 requested a review from rwgk July 17, 2021 14:43
Copy link
Collaborator

@rwgk rwgk left a comment

Choose a reason for hiding this comment

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

Looks great! Is the original author still around? If someone rebases on current master and the CI comes back green I think we should merge this straightaway.

@Skylion007
Copy link
Collaborator

@rwgk @henryiii I added an xfail for PyPy, but I would appreciate if you either of you could see if there is an easy fix / workaround we are missing. Like maybe wrapping it in a lambda or something?

#if defined(PYPY_VERSION)
// PyPy will segfault otherwise when passing in raw builtin functions.
return false;
//pybind11_fail("Passing raw builtin functions not supported with PyPy. Wrap in function.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do a fail her also caused a segfault. Weird.

@Skylion007
Copy link
Collaborator

Now it segfaults on every PyPy EXCEPT Ubuntu. So weird...

#if defined(PYPY_VERSION)
// PyPy will segfault otherwise when passing in raw builtin functions.
// This will lead to a TypeError instead.
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

So it looks like this test case ALWAYS segfaulted on non-ubuntu PyPy then which means that that the code is still better than before. I am really stumped on how to avoid this segfault though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I just counted, we have 19 xfail for PyPy already.

Copy link
Collaborator

Choose a reason for hiding this comment

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

PyPy has bugs. If we aren't adding a new one or making it worse (which it appears we are not), then I'm happy with it if it passes Google's testing.

@davidhewitt
Copy link
Contributor Author

👋 original author still here! Sorry it's taken me a couple of days to reply. It looks like you've got this one under control without me, so I won't push anything unless you ask me to.

These days I don't use C++ much any more, I tend to use Rust instead. I'm still very much working in the Python + native domain though, I am a maintainer of PyO3.

I still watch progress here closely; I like to think that both projects can benefit from sharing ideas and pushing the ecosystem forward. Sadly we're still some way behind in PyO3 so I don't think there's much learning from PyO3 that would interest you yet.

Do feel free to ping me any time (on this issue or any other) if you want my input as a "neighbour" 😄

@rwgk
Copy link
Collaborator

rwgk commented Jul 23, 2021

I imported this PR into the Google environment and ran ASAN & MSAN. Both are happy. I'm now submitting this PR to our global testing system. I'll report on the results tomorrow.

@rwgk
Copy link
Collaborator

rwgk commented Jul 23, 2021

EDIT: SEE NEXT COMMENT

Unfortunately there is a problem, triggered by code that's not open source, so I cannot easily point or share. It's a compilation failure (using some very modern clang version). I'll share the full traceback non-publicly. Here is the result of grep functional in the traceback:

pybind11/functional.h(90,74): error: use of undeclared identifier 'func_handle'
pybind11/functional.h(99,17): error: no matching conversion for functional-style cast from 'func_handle' to 'func_wrapper'
pybind11/functional.h(88,16): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'func_handle' to 'const func_wrapper' for 1st argument
pybind11/functional.h(88,16): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'func_handle' to 'func_wrapper' for 1st argument
pybind11/functional.h(88,16): note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
pybind11/functional.h(99,17): error: no matching conversion for functional-style cast from 'func_handle' to 'func_wrapper'
pybind11/functional.h(88,16): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'func_handle' to 'const func_wrapper' for 1st argument
pybind11/functional.h(88,16): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'func_handle' to 'func_wrapper' for 1st argument
pybind11/functional.h(88,16): note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided

@rwgk
Copy link
Collaborator

rwgk commented Jul 23, 2021

WAIT: after reporting the above I tried to reproduce the errors interactively, but it works!
I'm confused...

@rwgk
Copy link
Collaborator

rwgk commented Jul 23, 2021

It turns out to be some kind of Windows build.
I never had such failures before and don't know how to reproduce interactively.

@rwgk
Copy link
Collaborator

rwgk commented Jul 23, 2021

In the meantime the author of #1883 gave me some pointers, including how to reproduce the error interactively. Theory: we could be up against a bug in the Windows clang compiler. I'll try to get the attention of the team maintaining that compiler.

@Skylion007
Copy link
Collaborator

I'll split off the bugprone checks into their own PR.

@Skylion007 Skylion007 merged commit a0b9759 into pybind:master Jul 27, 2021
@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Jul 27, 2021
@Skylion007 Skylion007 added this to the v2.8 milestone Jul 27, 2021
henryiii pushed a commit to henryiii/pybind11 that referenced this pull request Jul 29, 2021
* Allow python builtins to be used as callbacks

* Try to fix pypy segfault

* Add expected fail for PyPy

* Fix typo

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add more info to xfail

* Add env

* Try returning false

* Try removing the move for pypy

* Fix bugs

* Try removing move

* Just keep ignoring for PyPy

* Add back xfail

* Fix ctors

* Revert change of std::move

* Change to skip

* Fix bug and edit comments

* Remove clang-tidy bugprone fix skip bug

Co-authored-by: Aaron Gokaslan <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
@henryiii henryiii removed the needs changelog Possibly needs a changelog entry label Sep 16, 2021
Sign up for free to 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.

8 participants