[BUG] cannot pass random.random() as std::function<double()> argument
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Issue description
When passing random.random() as an argument while testing PyArmadillo, a RuntimeError is caused whenever the argument is called (see below). However, if the function is modified to accept py::function instead, the function works as intended. If the function is called through a lambda function, the function works as well. Functions defined by the user work fine.
It appears that passing a function of the Python class builtin_function_or_method as opposed to function does not work.
Expected behaviour: passing random.random as a std::function<> should work (i.e. the function should be callable and the return value should be available in C++)
Actual behaviour: throws a RuntimeError: Unable to extract capsule contents!
Reproducible example code
pybindtest.cpp
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
namespace py = pybind11;
using namespace std;
PYBIND11_MODULE(pybindtest, m) {
m.def("foo", [](const std::function<double()> &f) { return f(); })
.def("bar", [](const py::function &f) { return f(); });
}
pybindtest.py
from pybindtest import *
from random import random
def baz():
return 123.456
# These work as intended
foo(baz)
foo(lambda: random())
foo(lambda: baz())
bar(random)
bar(baz)
bar(lambda: random())
bar(lambda: baz())
# RuntimeError: Unable to extract capsule contents!
foo(random)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the std::function conversion path included from pybind11/functional.h, using the pybindtest.cpp and pybindtest.py reproducer. Compare the handling of random.random with user-defined functions and lambdas. Done means foo(random) is callable from Python without the capsule extraction RuntimeError and returns the function result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100