Skip to content

Commit 5c8746f

Browse files
cysiekwjakob
authored andcommitted
check for already existing enum value added; added test (#1453)
* check for already existing enum value added; added test * added enum value name to exception message * test for defining enum with multiple identical names moved to test_enum.cpp/py
1 parent 35c82c7 commit 5c8746f

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

include/pybind11/pybind11.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,10 @@ template <typename Type> class enum_ : public class_<Type> {
14631463
enum_& value(char const* name, Type value, const char *doc = nullptr) {
14641464
auto v = pybind11::cast(value, return_value_policy::copy);
14651465
this->attr(name) = v;
1466-
m_entries[pybind11::str(name)] = std::make_pair(v, doc);
1466+
auto name_converted = pybind11::str(name);
1467+
if (m_entries.contains(name_converted))
1468+
throw value_error("Enum error - element with name: " + std::string(name) + " already exists");
1469+
m_entries[name_converted] = std::make_pair(v, doc);
14671470
return *this;
14681471
}
14691472

tests/test_enum.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,18 @@ TEST_SUBMODULE(enums, m) {
6868
m.def("test_enum_to_int", [](int) { });
6969
m.def("test_enum_to_uint", [](uint32_t) { });
7070
m.def("test_enum_to_long_long", [](long long) { });
71+
72+
// test_duplicate_enum_name
73+
enum SimpleEnum
74+
{
75+
ONE, TWO, THREE
76+
};
77+
78+
m.def("register_bad_enum", [m]() {
79+
py::enum_<SimpleEnum>(m, "SimpleEnum")
80+
.value("ONE", SimpleEnum::ONE) //NOTE: all value function calls are called with the same first parameter value
81+
.value("ONE", SimpleEnum::TWO)
82+
.value("ONE", SimpleEnum::THREE)
83+
.export_values();
84+
});
7185
}

tests/test_enum.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,9 @@ def test_enum_to_int():
148148
m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)
149149
m.test_enum_to_long_long(m.Flags.Read)
150150
m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)
151+
152+
153+
def test_duplicate_enum_name():
154+
with pytest.raises(ValueError) as excinfo:
155+
m.register_bad_enum()
156+
assert str(excinfo.value) == "Enum error - element with name: ONE already exists"

0 commit comments

Comments
 (0)