Skip to content

enum instance equality broken in pybind11 2.3 #1830

Description

@anntzer

Issue description

In pybind11 2.3, comparing an enum instance with a non-enum attempts to cast the non-enum to int, resulting in broken behaviors when the non-enum is not castable to an int, or a string that can be cast to an int.

Reproducible example code

#include <pybind11/pybind11.h>

enum Foo { a = 1 };

PYBIND11_MODULE(python_example, m) {
    pybind11::enum_<Foo>(m, "Foo")
        .value("a", Foo::a);
}

compile using the python_example example repo.

With pybind11 2.2.4:

$ python -c 'from python_example import Foo; print(Foo.a == None)'
False
$ python -c 'from python_example import Foo; print(Foo.a == "1")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: __eq__(): incompatible function arguments. The following argument types are supported:
    1. (self: python_example.Foo, arg0: python_example.Foo) -> bool
    2. (self: python_example.Foo, arg0: int) -> bool

Invoked with: Foo.a, '1'

With pybind11 2.3:

$ python -c 'from python_example import Foo; print(Foo.a == None)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
$ python -c 'from python_example import Foo; print(Foo.a == "1")'
True

I would prefer that equality checks always return True or False (consistently with the stdlib's enum.Enum), although I can understand raising a TypeError too. On the other hand, returning True when comparing with the string "1" is clearly incorrect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions