Skip to content

Commit 96997a4

Browse files
committed
Change internals ID and versioning scheme to avoid module conflicts
The current PYBIND11_INTERNALS_ID depends on the version of the library in order to isolate binary incompatible internals capsules. However, this does not preclude conflicts between modules built from different (binary incompatible) commits with the same version number. For example, if one module was built with an early v2.2.dev and submitted to PyPI, it could not be loaded alongside a v2.2.x release module -- it would segfault because of incompatible internals with the same ID. This PR changes the ID to depend on PYBIND11_INTERNALS_VERSION which is independent of the main library version. It's an integer which should be incremented whenever a binary incompatible change is made to internals. PYBIND11_INTERNALS_KIND is also introduced for a similar reason. The same versioning scheme is also applied to `type_info` and the `module_local` type attribute.
1 parent 024932b commit 96997a4

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

include/pybind11/cast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ class type_caster_generic {
603603
/// Try to load with foreign typeinfo, if available. Used when there is no
604604
/// native typeinfo, or when the native one wasn't able to produce a value.
605605
PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {
606-
constexpr auto *local_key = "_pybind11_module_local_typeinfo";
606+
constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;
607607
const auto pytype = src.get_type();
608608
if (!hasattr(pytype, local_key))
609609
return false;

include/pybind11/detail/internals.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ struct overload_hash {
6262
};
6363

6464
/// Internal data structure used to track registered instances and types.
65+
/// Whenever binary incompatible changes are made to this structure,
66+
/// `PYBIND11_INTERNALS_VERSION` must be incremented.
6567
struct internals {
6668
type_map<void *> registered_types_cpp; // std::type_index -> type_info
6769
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s)
@@ -83,6 +85,7 @@ struct internals {
8385
};
8486

8587
/// Additional type information which does not fit into the PyTypeObject.
88+
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
8689
struct type_info {
8790
PyTypeObject *type;
8891
const std::type_info *cpptype;
@@ -107,8 +110,20 @@ struct type_info {
107110
bool module_local : 1;
108111
};
109112

110-
#define PYBIND11_INTERNALS_ID "__pybind11_" \
111-
PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
113+
/// Tracks the `internals` and `type_info` ABI version independent of the main library version
114+
#define PYBIND11_INTERNALS_VERSION 1
115+
116+
#if defined(WITH_THREAD)
117+
# define PYBIND11_INTERNALS_KIND ""
118+
#else
119+
# define PYBIND11_INTERNALS_KIND "_without_thread"
120+
#endif
121+
122+
#define PYBIND11_INTERNALS_ID "__pybind11_internals_v" \
123+
PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__"
124+
125+
#define PYBIND11_MODULE_LOCAL_ID "__pybind11_module_local_v" \
126+
PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__"
112127

113128
/// Each module locally stores a pointer to the `internals` data. The data
114129
/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.

include/pybind11/pybind11.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ class generic_type : public object {
870870
if (rec.module_local) {
871871
// Stash the local typeinfo and loader so that external modules can access it.
872872
tinfo->module_local_load = &type_caster_generic::local_load;
873-
setattr(m_ptr, "_pybind11_module_local_typeinfo", capsule(tinfo));
873+
setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo));
874874
}
875875
}
876876

0 commit comments

Comments
 (0)