From 5c8746ff135abb390bf95944be593e895a586a50 Mon Sep 17 00:00:00 2001 From: Krzysztof Fornalczyk Date: Tue, 11 Sep 2018 10:59:56 +0200 Subject: [PATCH] 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 --- include/pybind11/pybind11.h | 5 ++++- tests/test_enum.cpp | 14 ++++++++++++++ tests/test_enum.py | 6 ++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index e986d007a..8e40c9f8e 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1463,7 +1463,10 @@ public: enum_& value(char const* name, Type value, const char *doc = nullptr) { auto v = pybind11::cast(value, return_value_policy::copy); this->attr(name) = v; - m_entries[pybind11::str(name)] = std::make_pair(v, doc); + auto name_converted = pybind11::str(name); + if (m_entries.contains(name_converted)) + throw value_error("Enum error - element with name: " + std::string(name) + " already exists"); + m_entries[name_converted] = std::make_pair(v, doc); return *this; } diff --git a/tests/test_enum.cpp b/tests/test_enum.cpp index 4cd14a96a..498a00e16 100644 --- a/tests/test_enum.cpp +++ b/tests/test_enum.cpp @@ -68,4 +68,18 @@ TEST_SUBMODULE(enums, m) { m.def("test_enum_to_int", [](int) { }); m.def("test_enum_to_uint", [](uint32_t) { }); m.def("test_enum_to_long_long", [](long long) { }); + + // test_duplicate_enum_name + enum SimpleEnum + { + ONE, TWO, THREE + }; + + m.def("register_bad_enum", [m]() { + py::enum_(m, "SimpleEnum") + .value("ONE", SimpleEnum::ONE) //NOTE: all value function calls are called with the same first parameter value + .value("ONE", SimpleEnum::TWO) + .value("ONE", SimpleEnum::THREE) + .export_values(); + }); } diff --git a/tests/test_enum.py b/tests/test_enum.py index c2c272a25..a031d9570 100644 --- a/tests/test_enum.py +++ b/tests/test_enum.py @@ -148,3 +148,9 @@ def test_enum_to_int(): m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode) m.test_enum_to_long_long(m.Flags.Read) m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode) + + +def test_duplicate_enum_name(): + with pytest.raises(ValueError) as excinfo: + m.register_bad_enum() + assert str(excinfo.value) == "Enum error - element with name: ONE already exists"