pybind / pybind/pybind11

[BUG] cannot pass random.random() as std::function<double()> argument

Open
#2,853 2 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.