-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Closed
Labels
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
Problem description
In the following example the Struct has a Python binding and is convertible on its own. Also std::unordered_set works in general for build in types. However for the combination std::unordered_set<Struct> the conversion fails at runtime with the error by calling test_func()
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: Unable to convert function return value to a Python type! The signature was
() -> Set[test_module.Struct]
- The removal of
py::is_operator()in the binding fixes the problem. - The example does work for version 2.5.0, but fails for 2.6.0, 2.7.1, 2.8.1 and 2.9.0.
- It does also not work for an
std::set, but for anstd::vector. - The code was compiled with
clang13.0.0onx86_64(Ubuntu20.04)
Reproducible example code
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = ::pybind11;
struct Struct
{
std::string member;
};
bool operator==(const Struct& lhs, const Struct& rhs)
{
return lhs.member == rhs.member;
}
namespace std
{
template <>
struct hash<Struct>
{
std::size_t operator()(const Struct& selector) const;
};
} // namespace std
std::size_t std::hash<Struct>::operator()(const Struct& selector) const
{
return std::hash<std::string>()(selector.member);
}
PYBIND11_MODULE(test_module, module)
{
py::class_<Struct>(module, "Struct")
// Removing the binding makes the example work.
.def(
"__eq__",
[](const Struct& lhs, const Struct& rhs) {
return lhs == rhs;
},
py::is_operator());
module.def("test_func", []() {
return std::unordered_set<Struct>{{"one"}, {"two"}};
});
}bluenote10 and Skylion007