From 9ea39dc356531a8bd549ab3d0cc091e07c650288 Mon Sep 17 00:00:00 2001 From: crimsoncor Date: Sun, 24 Jan 2021 12:17:28 -0500 Subject: [PATCH] Force the builtin module key to be the correct type. (#2814) * Force the builtin module key to be the correct type. Previously it was always going to be a std::string which converted into unicode. Python 2 appears to want module keys to be normal str types, so this was breaking code that expected plain string types in the builtins.keys() data structure * Add a simple unit test to ensure all built-in keys are str * Update the unit test so it will also run on pypy * Run pre-commit. Co-authored-by: Jesse Clemens --- include/pybind11/detail/internals.h | 2 +- tests/test_modules.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 812505c22..75fcd3c20 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -266,7 +266,7 @@ PYBIND11_NOINLINE inline internals &get_internals() { const PyGILState_STATE state; } gil; - constexpr auto *id = PYBIND11_INTERNALS_ID; + PYBIND11_STR_TYPE id(PYBIND11_INTERNALS_ID); auto builtins = handle(PyEval_GetBuiltins()); if (builtins.contains(id) && isinstance(builtins[id])) { internals_pp = static_cast(capsule(builtins[id])); diff --git a/tests/test_modules.py b/tests/test_modules.py index 5630ccf9b..3390031af 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -75,3 +75,16 @@ def test_duplicate_registration(): """Registering two things with the same name""" assert m.duplicate_registration() == [] + + +def test_builtin_key_type(): + """Test that all the keys in the builtin modules have type str. + + Previous versions of pybind11 would add a unicode key in python 2. + """ + if hasattr(__builtins__, "keys"): + keys = __builtins__.keys() + else: # this is to make pypy happy since builtins is different there. + keys = __builtins__.__dict__.keys() + + assert {type(k) for k in keys} == {str}