I'm curious if there's a way to avoid repeating myself. I have several classes that are not related by parentage:
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
class Foo {
public:
Foo(int x)
: x(x)
{}
int x;
};
class Bar {
public:
Bar(int y)
: y(y)
{}
int y;
};
using FooBarType = std::variant<Foo, Bar>;
PYBIND11_MODULE(my_module, m)
{
py::class_<Foo>(m, "Foo")
.def(py::init<int>())
.def_readwrite("x", &Foo::x);
py::class_<Bar>(m, "Bar")
.def(py::init<int>())
.def_readwrite("y", &Bar::y);
}
And my Python code:
from typing import TypeAlias
from my_moduleimport Foo, Bar
FooBarType: TypeAlias = Foo | Bar
def check_foo_bar(value: FooBarType, expected: int):
if isinstance(value, Foo):
assert value.x == expected
elif isinstance(value, Bar):
assert value.y == expected
else:
raise ValueError(f"Unknown type: {type(value)}")
def test_foo_bar():
foo: FooBarType = Foo(1)
bar: FooBarType = Bar(2)
check_foo_bar(foo, 1)
check_foo_bar(bar, 2)
I'm trying to create a binding to using FooBarType = std::variant<Foo, Bar> so I don't have to define FooBarType: TypeAlias = Foo | Bar.
I've tried using pybind11::type::of:
m.def("FooBarType", py::type::of<FooBarType>());
But that blows up with
In file included from test.cpp:4:
In file included from /home/user/work/external/pybind11/include/pybind11/operators.h:12:
In file included from /home/user/work/external/pybind11/include/pybind11/pybind11.h:13:
In file included from /home/user/work/external/pybind11/include/pybind11/detail/class.h:12:
In file included from /home/user/work/external/pybind11/include/pybind11/attr.h:14:
/home/user/work/external/pybind11/include/pybind11/cast.h:1646:5: error: static_assert failed due to requirement 'std::is_base_of<pybind11::detail::type_caster_generic, pybind11::detail::type_caster<std::variant<Foo, Bar>, void>>::value' "py::type::of<T> only supports the case where T is a registered C++ types."
static_assert(std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/work/external/pybind11/include/pybind11/pytypes.h:1392:27: note: in instantiation of function template specialization 'pybind11::type::handle_of<std::variant<Foo, Bar>>' requested here
return type(type::handle_of<T>(), borrowed_t{});
^
test.cpp:125:35: note: in instantiation of function template specialization 'pybind11::type::of<std::variant<Foo, Bar>>' requested here
m.def("FooBarType", py::type::of<FooBarType>());
^
In file included from test.cpp:4:
In file included from /home/user/work/external/pybind11/include/pybind11/operators.h:12:
In file included from /home/user/work/external/pybind11/include/pybind11/pybind11.h:13:
In file included from /home/user/work/external/pybind11/include/pybind11/detail/class.h:12:
In file included from /home/user/work/external/pybind11/include/pybind11/attr.h:13:
/home/user/work/external/pybind11/include/pybind11/detail/common.h:867:49: error: reference to overloaded function could not be resolved; did you mean to call it?
using type = typename remove_class<decltype(&F::operator())>::type;
Any help is appreciated.
Cheers!