Skip to content

[BUG]: Regression from 2.5.0 to 2.6.0: Existance of operator breaks binding of some collections #3600

Closed
@marlamb

Description

@marlamb

Required prerequisites

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 an std::vector.
  • The code was compiled with clang13.0.0 on x86_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"}};
  });
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions