Implicit conversion of pointer-type arguments
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Issue description
The current implicit conversion system doesn't allow to specify conversion for pointer type arguments, even though the same call would work in c++ (see the code).
The main problem seems to be that pybind11's function type detection always assumes the base type (i.e. A) to be the exposed one. If there were a possibility to declare a py::class_<A*>(m, "APtr") and force the function to accept it instead of A (by specifying an attribute on py::arg for example) it would solve the problem without making the more common use case any more cumbersome.
EDIT: you could solve this problem by defining a copyable wrapper class around A and Container_of_A convertible to it.
Reproducible example code
#include <pybind11/pybind11.h>
#include <iostream>
using namespace std;
namespace py = pybind11;
struct A {
A(const A& a) = delete;
explicit A(int value) : value(value) { };
int value;
};
struct Container_of_A {
A* a;
// define conversion
operator A* () { return this->a; }
};
int test1(A* a) {
return a->value;
}
PYBIND11_MODULE(conversion, m) {
// sanity check
A a(10);
Container_of_A cont = {&a};
cout << "Test 2: " << test1(cont) << endl;
py::class_<A>(m, "A")
.def(py::init<int>());
//.def(py::init<Container_of_A>) doesn't work, since you can't initalize an instance of A with a pointer
py::class_<Container_of_A>(m, "Container_of_A")
.def(py::init<A*>());
py::implicitly_convertible<Container_of_A, A>();
m.def("test1", &test1, py::return_value_policy::reference);
}
#!/usr/bin/env python3
import conversion as conv
a = conv.A(10)
container = conv.Container_of_A(a)
print('Success 1: ', conv.test1(a))
print('Failure 1: ', conv.test1(container))
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
The named entry points are py::implicitly_convertible, py::arg, py::class_, and the bound test1(A*) function; start by tracing function type detection for pointer arguments. Use the supplied C++ and Python reproducer as regression coverage. Done means conv.test1(container) succeeds while conv.test1(a) continues to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100