Commit d41a2730 by Jason Rhinelander

Only support ==/!= int on unscoped enums

This makes the Python interface mirror the C++ interface:
pybind11-exported scoped enums aren't directly comparable to the
underlying integer values.
parent 61354194
...@@ -22,7 +22,26 @@ print(test_function(7)) ...@@ -22,7 +22,26 @@ print(test_function(7))
print(test_function(EMyEnumeration.EFirstEntry)) print(test_function(EMyEnumeration.EFirstEntry))
print(test_function(EMyEnumeration.ESecondEntry)) print(test_function(EMyEnumeration.ESecondEntry))
test_ecenum(ECMyEnum.Three) test_ecenum(ECMyEnum.Three)
test_ecenum(ECMyEnum.Two) z = ECMyEnum.Two
test_ecenum(z)
try:
z == 2
print("Bad: expected a TypeError exception")
except TypeError:
try:
z != 3
print("Bad: expected a TypeError exception")
except TypeError:
print("Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons")
y = EMyEnumeration.ESecondEntry
try:
y == 2
y != 2
print("Good: no TypeError exception for unscoped enum ==/!= int comparisions")
except TypeError:
print("Bad: caught TypeError exception for unscoped enum ==/!= int comparisons")
print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry)) print("enum->integer = %i" % int(EMyEnumeration.ESecondEntry))
print("integer->enum = %s" % str(EMyEnumeration(2))) print("integer->enum = %s" % str(EMyEnumeration(2)))
......
...@@ -12,6 +12,8 @@ test_function(enum=2) ...@@ -12,6 +12,8 @@ test_function(enum=2)
None None
test_ecenum(ECMyEnum::Three) test_ecenum(ECMyEnum::Three)
test_ecenum(ECMyEnum::Two) test_ecenum(ECMyEnum::Two)
Good: caught expected TypeError exceptions for scoped enum ==/!= int comparisons
Good: no TypeError exception for unscoped enum ==/!= int comparisions
enum->integer = 2 enum->integer = 2
integer->enum = EMyEnumeration.ESecondEntry integer->enum = EMyEnumeration.ESecondEntry
A constant = 14 A constant = 14
......
...@@ -1019,9 +1019,14 @@ public: ...@@ -1019,9 +1019,14 @@ public:
this->def("__init__", [](Type& value, UnderlyingType i) { new (&value) Type((Type) i); }); this->def("__init__", [](Type& value, UnderlyingType i) { new (&value) Type((Type) i); });
this->def("__int__", [](Type value) { return (UnderlyingType) value; }); this->def("__int__", [](Type value) { return (UnderlyingType) value; });
this->def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; }); this->def("__eq__", [](const Type &value, Type *value2) { return value2 && value == *value2; });
this->def("__eq__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value == value2; });
this->def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; }); this->def("__ne__", [](const Type &value, Type *value2) { return !value2 || value != *value2; });
if (std::is_convertible<Type, UnderlyingType>::value) {
// Don't provide comparison with the underlying type if the enum isn't convertible,
// i.e. if Type is a scoped enum, mirroring the C++ behaviour. (NB: we explicitly
// convert Type to UnderlyingType below anyway because this needs to compile).
this->def("__eq__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value == value2; });
this->def("__ne__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value != value2; }); this->def("__ne__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value != value2; });
}
this->def("__hash__", [](const Type &value) { return (UnderlyingType) value; }); this->def("__hash__", [](const Type &value) { return (UnderlyingType) value; });
m_entries = entries; m_entries = entries;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment