From 1df246774e5663567266e5fd8e3301449ad9582c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 2 Feb 2022 07:07:04 -0800 Subject: [PATCH 1/4] Minimal reproducer for clash when binding types defined in the unnamed namespace. --- tests/CMakeLists.txt | 2 ++ tests/test_unnamed_namespace_a.cpp | 9 +++++++++ tests/test_unnamed_namespace_a.py | 6 ++++++ tests/test_unnamed_namespace_b.cpp | 9 +++++++++ tests/test_unnamed_namespace_b.py | 6 ++++++ 5 files changed, 32 insertions(+) create mode 100644 tests/test_unnamed_namespace_a.cpp create mode 100644 tests/test_unnamed_namespace_a.py create mode 100644 tests/test_unnamed_namespace_b.cpp create mode 100644 tests/test_unnamed_namespace_b.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 491f215cef..285f43b5b9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -156,6 +156,8 @@ set(PYBIND11_TEST_FILES test_tagbased_polymorphic test_thread test_union + test_unnamed_namespace_a + test_unnamed_namespace_b test_virtual_functions) # Invoking cmake with something like: diff --git a/tests/test_unnamed_namespace_a.cpp b/tests/test_unnamed_namespace_a.cpp new file mode 100644 index 0000000000..4f6472c386 --- /dev/null +++ b/tests/test_unnamed_namespace_a.cpp @@ -0,0 +1,9 @@ +#include "pybind11_tests.h" + +namespace { +struct any_struct {}; +} // namespace + +TEST_SUBMODULE(unnamed_namespace_a, m) { + py::class_(m, "unnamed_namespace_a_any_struct"); +} diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py new file mode 100644 index 0000000000..301470f903 --- /dev/null +++ b/tests/test_unnamed_namespace_a.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from pybind11_tests import unnamed_namespace_a as m + + +def test_have_type(): + assert hasattr(m, "unnamed_namespace_a_any_struct") diff --git a/tests/test_unnamed_namespace_b.cpp b/tests/test_unnamed_namespace_b.cpp new file mode 100644 index 0000000000..8c9b140098 --- /dev/null +++ b/tests/test_unnamed_namespace_b.cpp @@ -0,0 +1,9 @@ +#include "pybind11_tests.h" + +namespace { +struct any_struct {}; +} // namespace + +TEST_SUBMODULE(unnamed_namespace_b, m) { + py::class_(m, "unnamed_namespace_b_any_struct"); +} diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py new file mode 100644 index 0000000000..cdef3d792c --- /dev/null +++ b/tests/test_unnamed_namespace_b.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from pybind11_tests import unnamed_namespace_b as m + + +def test_have_type(): + assert hasattr(m, "unnamed_namespace_b_any_struct") From 95caa032643cf9d6327990508bb3c1397d759638 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 4 Nov 2022 03:19:55 -0700 Subject: [PATCH 2/4] pre-commit pyupgrade auto-fix --- tests/test_unnamed_namespace_a.py | 1 - tests/test_unnamed_namespace_b.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/test_unnamed_namespace_a.py b/tests/test_unnamed_namespace_a.py index 301470f903..b823376a4b 100644 --- a/tests/test_unnamed_namespace_a.py +++ b/tests/test_unnamed_namespace_a.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from pybind11_tests import unnamed_namespace_a as m diff --git a/tests/test_unnamed_namespace_b.py b/tests/test_unnamed_namespace_b.py index cdef3d792c..0550bc4347 100644 --- a/tests/test_unnamed_namespace_b.py +++ b/tests/test_unnamed_namespace_b.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from pybind11_tests import unnamed_namespace_b as m From 28e953551a1cb074bceb78272edc4eca7eb4d16f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 4 Nov 2022 04:46:43 -0700 Subject: [PATCH 3/4] Debug `printf()`s in `type_equal_to` ``` g++ (Debian 12.2.0-3) 12.2.0 ============================ LOOOK __GLIBCXX__ [lhs=N12_GLOBAL__N_110any_structE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/../detail/internals.h:124 LOOOK __GLIBCXX__ [rhs=N12_GLOBAL__N_110any_structE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/../detail/internals.h:125 LOOOK __GLIBCXX__ [(lhs==rhs)=FALSE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/../detail/internals.h:129 Debian clang version 14.0.6-2 ============================= LOOOK __GLIBCXX__ [lhs=N12_GLOBAL__N_110any_structE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/internals.h:124 LOOOK __GLIBCXX__ [rhs=N12_GLOBAL__N_110any_structE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/internals.h:125 LOOOK __GLIBCXX__ [(lhs==rhs)=TRUE] /usr/local/google/home/rwgk/forked/pybind11/include/pybind11/detail/internals.h:129 ImportError while loading conftest '/usr/local/google/home/rwgk/forked/pybind11/tests/conftest.py'. conftest.py:16: in import pybind11_tests E ImportError: generic_type: type "unnamed_namespace_b_any_struct" is already registered! ``` --- include/pybind11/detail/internals.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 6fd61098c4..2616c7116b 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -117,7 +117,20 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { #if defined(__GLIBCXX__) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; -using type_equal_to = std::equal_to; +// using type_equal_to = std::equal_to; +struct type_equal_to { + bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { + bool result = (lhs == rhs); + printf("\nLOOOK __GLIBCXX__ [lhs=%s] %s:%d\n", lhs.name(), __FILE__, __LINE__); + printf("LOOOK __GLIBCXX__ [rhs=%s] %s:%d\n", rhs.name(), __FILE__, __LINE__); + printf("LOOOK __GLIBCXX__ [(lhs==rhs)=%s] %s:%d\n", + (result ? "TRUE" : "FALSE"), + __FILE__, + __LINE__); + fflush(stdout); + return result; + } +}; #else inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; @@ -136,7 +149,16 @@ struct type_hash { struct type_equal_to { bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { - return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; + // return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; + bool result = (lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0); + printf("\nLOOOK ___OTHER___ [lhs=%s] %s:%d\n", lhs.name(), __FILE__, __LINE__); + printf("LOOOK ___OTHER___ [rhs=%s] %s:%d\n", rhs.name(), __FILE__, __LINE__); + printf("LOOOK ___OTHER___ [(lhs==rhs)=%s] %s:%d\n", + (result ? "TRUE" : "FALSE"), + __FILE__, + __LINE__); + fflush(stdout); + return result; } }; #endif From 7ac511bcbea45d1ec3e3bf9ced7859b946b95d18 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 4 Nov 2022 05:36:29 -0700 Subject: [PATCH 4/4] Revert "Debug `printf()`s in `type_equal_to`" This reverts commit 28e953551a1cb074bceb78272edc4eca7eb4d16f. --- include/pybind11/detail/internals.h | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 2616c7116b..6fd61098c4 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -117,20 +117,7 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) { #if defined(__GLIBCXX__) inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } using type_hash = std::hash; -// using type_equal_to = std::equal_to; -struct type_equal_to { - bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { - bool result = (lhs == rhs); - printf("\nLOOOK __GLIBCXX__ [lhs=%s] %s:%d\n", lhs.name(), __FILE__, __LINE__); - printf("LOOOK __GLIBCXX__ [rhs=%s] %s:%d\n", rhs.name(), __FILE__, __LINE__); - printf("LOOOK __GLIBCXX__ [(lhs==rhs)=%s] %s:%d\n", - (result ? "TRUE" : "FALSE"), - __FILE__, - __LINE__); - fflush(stdout); - return result; - } -}; +using type_equal_to = std::equal_to; #else inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; @@ -149,16 +136,7 @@ struct type_hash { struct type_equal_to { bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { - // return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; - bool result = (lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0); - printf("\nLOOOK ___OTHER___ [lhs=%s] %s:%d\n", lhs.name(), __FILE__, __LINE__); - printf("LOOOK ___OTHER___ [rhs=%s] %s:%d\n", rhs.name(), __FILE__, __LINE__); - printf("LOOOK ___OTHER___ [(lhs==rhs)=%s] %s:%d\n", - (result ? "TRUE" : "FALSE"), - __FILE__, - __LINE__); - fflush(stdout); - return result; + return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; } }; #endif