From e16ec8fd9ebc5a35cb6f95b10337a9094e17e5d3 Mon Sep 17 00:00:00 2001 From: Huanchen Zhai Date: Wed, 13 Dec 2023 21:56:56 -0800 Subject: [PATCH 1/5] bugfix: ensure different KeysView/ValuesView type names for int16_t/int32_t or float/double. Fix #4529 --- include/pybind11/stl_bind.h | 14 ++------------ tests/test_stl_binders.cpp | 4 ++++ tests/test_stl_binders.py | 21 ++++++++++++++------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/pybind11/stl_bind.h b/include/pybind11/stl_bind.h index 4d0854f6a8..8beae42004 100644 --- a/include/pybind11/stl_bind.h +++ b/include/pybind11/stl_bind.h @@ -718,18 +718,8 @@ class_ bind_map(handle scope, const std::string &name, Args && } Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); - static constexpr auto key_type_descr = detail::make_caster::name; - static constexpr auto mapped_type_descr = detail::make_caster::name; - std::string key_type_name(key_type_descr.text), mapped_type_name(mapped_type_descr.text); - - // If key type isn't properly wrapped, fall back to C++ names - if (key_type_name == "%") { - key_type_name = detail::type_info_description(typeid(KeyType)); - } - // Similarly for value type: - if (mapped_type_name == "%") { - mapped_type_name = detail::type_info_description(typeid(MappedType)); - } + std::string key_type_name(detail::type_info_description(typeid(KeyType))); + std::string mapped_type_name(detail::type_info_description(typeid(MappedType))); // Wrap KeysView[KeyType] if it wasn't already wrapped if (!detail::get_type_info(typeid(KeysView))) { diff --git a/tests/test_stl_binders.cpp b/tests/test_stl_binders.cpp index e52a03b6d2..8a146f3095 100644 --- a/tests/test_stl_binders.cpp +++ b/tests/test_stl_binders.cpp @@ -187,6 +187,10 @@ TEST_SUBMODULE(stl_binders, m) { py::bind_map>(m, "MapStringDouble"); py::bind_map>(m, "UnorderedMapStringDouble"); + // test_map_string_float + py::bind_map>(m, "MapStringFloat"); + py::bind_map>(m, "UnorderedMapStringFloat"); + // test_map_string_double_const py::bind_map>(m, "MapStringDoubleConst"); py::bind_map>(m, diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index c00d45b926..9013a09e75 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -314,22 +314,29 @@ def test_map_delitem(): def test_map_view_types(): map_string_double = m.MapStringDouble() unordered_map_string_double = m.UnorderedMapStringDouble() + map_string_float = m.MapStringFloat() + unordered_map_string_float = m.UnorderedMapStringFloat() map_string_double_const = m.MapStringDoubleConst() unordered_map_string_double_const = m.UnorderedMapStringDoubleConst() - assert map_string_double.keys().__class__.__name__ == "KeysView[str]" - assert map_string_double.values().__class__.__name__ == "ValuesView[float]" - assert map_string_double.items().__class__.__name__ == "ItemsView[str, float]" + assert map_string_double.values().__class__.__name__ == "ValuesView[double]" + assert map_string_float.values().__class__.__name__ == "ValuesView[float]" keys_type = type(map_string_double.keys()) assert type(unordered_map_string_double.keys()) is keys_type + assert type(map_string_float.keys()) is keys_type + assert type(unordered_map_string_float.keys()) is keys_type assert type(map_string_double_const.keys()) is keys_type assert type(unordered_map_string_double_const.keys()) is keys_type - values_type = type(map_string_double.values()) - assert type(unordered_map_string_double.values()) is values_type - assert type(map_string_double_const.values()) is values_type - assert type(unordered_map_string_double_const.values()) is values_type + values_type_double = type(map_string_double.values()) + assert type(unordered_map_string_double.values()) is values_type_double + assert type(map_string_double_const.values()) is values_type_double + assert type(unordered_map_string_double_const.values()) is values_type_double + + values_type_float = type(map_string_float.values()) + assert values_type_float is not values_type_double + assert type(unordered_map_string_float.values()) is values_type_float items_type = type(map_string_double.items()) assert type(unordered_map_string_double.items()) is items_type From 2e334dfee4cb5ea92ae8d5d149c2906304bea7cc Mon Sep 17 00:00:00 2001 From: Huanchen Zhai Date: Sat, 16 Dec 2023 23:37:28 -0800 Subject: [PATCH 2/5] add the tests for keys() and items() --- tests/test_stl_binders.cpp | 17 ++++++--- tests/test_stl_binders.py | 71 +++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/tests/test_stl_binders.cpp b/tests/test_stl_binders.cpp index 8a146f3095..15508b8d17 100644 --- a/tests/test_stl_binders.cpp +++ b/tests/test_stl_binders.cpp @@ -187,15 +187,24 @@ TEST_SUBMODULE(stl_binders, m) { py::bind_map>(m, "MapStringDouble"); py::bind_map>(m, "UnorderedMapStringDouble"); - // test_map_string_float - py::bind_map>(m, "MapStringFloat"); - py::bind_map>(m, "UnorderedMapStringFloat"); - // test_map_string_double_const py::bind_map>(m, "MapStringDoubleConst"); py::bind_map>(m, "UnorderedMapStringDoubleConst"); + // test_map_view_types + py::bind_map>(m, "MapIntDouble"); + py::bind_map>(m, "UnorderedMapIntDouble"); + + py::bind_map>(m, "MapIntDoubleConst"); + py::bind_map>(m, "UnorderedMapIntDoubleConst"); + + py::bind_map>(m, "MapIntFloat"); + py::bind_map>(m, "UnorderedMapIntFloat"); + + py::bind_map>(m, "MapInt64Double"); + py::bind_map>(m, "MapUInt64Double"); + py::class_(m, "ENC").def(py::init()).def_readwrite("value", &E_nc::value); // test_noncopyable_containers diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index 9013a09e75..1fa6414619 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -312,36 +312,51 @@ def test_map_delitem(): def test_map_view_types(): - map_string_double = m.MapStringDouble() - unordered_map_string_double = m.UnorderedMapStringDouble() - map_string_float = m.MapStringFloat() - unordered_map_string_float = m.UnorderedMapStringFloat() - map_string_double_const = m.MapStringDoubleConst() - unordered_map_string_double_const = m.UnorderedMapStringDoubleConst() - - assert map_string_double.values().__class__.__name__ == "ValuesView[double]" - assert map_string_float.values().__class__.__name__ == "ValuesView[float]" - - keys_type = type(map_string_double.keys()) - assert type(unordered_map_string_double.keys()) is keys_type - assert type(map_string_float.keys()) is keys_type - assert type(unordered_map_string_float.keys()) is keys_type - assert type(map_string_double_const.keys()) is keys_type - assert type(unordered_map_string_double_const.keys()) is keys_type - - values_type_double = type(map_string_double.values()) - assert type(unordered_map_string_double.values()) is values_type_double - assert type(map_string_double_const.values()) is values_type_double - assert type(unordered_map_string_double_const.values()) is values_type_double - - values_type_float = type(map_string_float.values()) + map_int_double = m.MapIntDouble() + unordered_map_int_double = m.UnorderedMapIntDouble() + map_int_double_const = m.MapIntDoubleConst() + unordered_map_int_double_const = m.UnorderedMapIntDoubleConst() + map_int_float = m.MapIntFloat() + unordered_map_int_float = m.UnorderedMapIntFloat() + map_int64_double = m.MapInt64Double() + map_uint64_double = m.MapUInt64Double() + + assert map_int_double.keys().__class__.__name__ == "KeysView[int]" + assert map_int_double.values().__class__.__name__ == "ValuesView[double]" + assert map_int_double.items().__class__.__name__ == "ItemsView[int, double]" + + assert map_int_float.keys().__class__.__name__ == "KeysView[int]" + assert map_int_float.values().__class__.__name__ == "ValuesView[float]" + assert map_int_float.items().__class__.__name__ == "ItemsView[int, float]" + + assert map_int64_double.keys().__class__.__name__ == "KeysView[long]" + assert map_int64_double.values().__class__.__name__ == "ValuesView[double]" + assert map_int64_double.items().__class__.__name__ == "ItemsView[long, double]" + + assert map_uint64_double.keys().__class__.__name__ == "KeysView[unsigned long]" + assert map_uint64_double.values().__class__.__name__ == "ValuesView[double]" + assert map_uint64_double.items().__class__.__name__ == "ItemsView[unsigned long, double]" + + keys_type = type(map_int_double.keys()) + assert type(unordered_map_int_double.keys()) is keys_type + assert type(map_int_float.keys()) is keys_type + assert type(unordered_map_int_float.keys()) is keys_type + assert type(map_int_double_const.keys()) is keys_type + assert type(unordered_map_int_double_const.keys()) is keys_type + + values_type_double = type(map_int_double.values()) + assert type(unordered_map_int_double.values()) is values_type_double + assert type(map_int_double_const.values()) is values_type_double + assert type(unordered_map_int_double_const.values()) is values_type_double + + values_type_float = type(map_int_float.values()) assert values_type_float is not values_type_double - assert type(unordered_map_string_float.values()) is values_type_float + assert type(unordered_map_int_float.values()) is values_type_float - items_type = type(map_string_double.items()) - assert type(unordered_map_string_double.items()) is items_type - assert type(map_string_double_const.items()) is items_type - assert type(unordered_map_string_double_const.items()) is items_type + items_type = type(map_int_double.items()) + assert type(unordered_map_int_double.items()) is items_type + assert type(map_int_double_const.items()) is items_type + assert type(unordered_map_int_double_const.items()) is items_type def test_recursive_vector(): From 32a24ca1ad99d55f8ef343afe508a9e8fcda1ba7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 17 Dec 2023 07:38:02 +0000 Subject: [PATCH 3/5] style: pre-commit fixes --- tests/test_stl_binders.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index 1fa6414619..724699481e 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -335,7 +335,10 @@ def test_map_view_types(): assert map_uint64_double.keys().__class__.__name__ == "KeysView[unsigned long]" assert map_uint64_double.values().__class__.__name__ == "ValuesView[double]" - assert map_uint64_double.items().__class__.__name__ == "ItemsView[unsigned long, double]" + assert ( + map_uint64_double.items().__class__.__name__ + == "ItemsView[unsigned long, double]" + ) keys_type = type(map_int_double.keys()) assert type(unordered_map_int_double.keys()) is keys_type From 7681cecd7845b6b8775f70bd610654854e15a198 Mon Sep 17 00:00:00 2001 From: Huanchen Zhai Date: Sat, 16 Dec 2023 23:51:30 -0800 Subject: [PATCH 4/5] fix C++ type names for int64_t --- tests/test_stl_binders.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index 724699481e..a19bfe14da 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -329,15 +329,15 @@ def test_map_view_types(): assert map_int_float.values().__class__.__name__ == "ValuesView[float]" assert map_int_float.items().__class__.__name__ == "ItemsView[int, float]" - assert map_int64_double.keys().__class__.__name__ == "KeysView[long]" + assert map_int64_double.keys().__class__.__name__ in ["KeysView[long]", "KeysView[long long]", "KeysView[__int64]"] assert map_int64_double.values().__class__.__name__ == "ValuesView[double]" - assert map_int64_double.items().__class__.__name__ == "ItemsView[long, double]" + assert map_int64_double.items().__class__.__name__ in ["ItemsView[long, double]", "ItemsView[long long, double]", "ItemsView[__int64, double]"] - assert map_uint64_double.keys().__class__.__name__ == "KeysView[unsigned long]" + assert map_uint64_double.keys().__class__.__name__ in ["KeysView[unsigned long]", "KeysView[unsigned long long]", "KeysView[unsigned __int64]"] assert map_uint64_double.values().__class__.__name__ == "ValuesView[double]" assert ( map_uint64_double.items().__class__.__name__ - == "ItemsView[unsigned long, double]" + in ["ItemsView[unsigned long, double]", "ItemsView[unsigned long long, double]", "ItemsView[unsigned __int64, double]"] ) keys_type = type(map_int_double.keys()) From 68263a973950f64c0c4182343976a0801464389c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 17 Dec 2023 07:51:51 +0000 Subject: [PATCH 5/5] style: pre-commit fixes --- tests/test_stl_binders.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py index a19bfe14da..3d9cb241f5 100644 --- a/tests/test_stl_binders.py +++ b/tests/test_stl_binders.py @@ -329,16 +329,29 @@ def test_map_view_types(): assert map_int_float.values().__class__.__name__ == "ValuesView[float]" assert map_int_float.items().__class__.__name__ == "ItemsView[int, float]" - assert map_int64_double.keys().__class__.__name__ in ["KeysView[long]", "KeysView[long long]", "KeysView[__int64]"] + assert map_int64_double.keys().__class__.__name__ in [ + "KeysView[long]", + "KeysView[long long]", + "KeysView[__int64]", + ] assert map_int64_double.values().__class__.__name__ == "ValuesView[double]" - assert map_int64_double.items().__class__.__name__ in ["ItemsView[long, double]", "ItemsView[long long, double]", "ItemsView[__int64, double]"] - - assert map_uint64_double.keys().__class__.__name__ in ["KeysView[unsigned long]", "KeysView[unsigned long long]", "KeysView[unsigned __int64]"] + assert map_int64_double.items().__class__.__name__ in [ + "ItemsView[long, double]", + "ItemsView[long long, double]", + "ItemsView[__int64, double]", + ] + + assert map_uint64_double.keys().__class__.__name__ in [ + "KeysView[unsigned long]", + "KeysView[unsigned long long]", + "KeysView[unsigned __int64]", + ] assert map_uint64_double.values().__class__.__name__ == "ValuesView[double]" - assert ( - map_uint64_double.items().__class__.__name__ - in ["ItemsView[unsigned long, double]", "ItemsView[unsigned long long, double]", "ItemsView[unsigned __int64, double]"] - ) + assert map_uint64_double.items().__class__.__name__ in [ + "ItemsView[unsigned long, double]", + "ItemsView[unsigned long long, double]", + "ItemsView[unsigned __int64, double]", + ] keys_type = type(map_int_double.keys()) assert type(unordered_map_int_double.keys()) is keys_type