diff --git a/include/pybind11/compat/README.txt b/include/pybind11/compat/README.txt index 09ddca0bc..9a2c53ba4 100644 --- a/include/pybind11/compat/README.txt +++ b/include/pybind11/compat/README.txt @@ -8,3 +8,8 @@ The C++ code here and nothing else. DO NOT ADD CODE WITH OTHER EXTERNAL DEPENDENCIES TO THIS DIRECTORY. + +Read on: + +pybind11_conduit_v1.h — Type-safe interoperability between different + independent Python/C++ bindings systems. diff --git a/include/pybind11/compat/pybind11_conduit_v1.h b/include/pybind11/compat/pybind11_conduit_v1.h index 37e5715a8..e3a453453 100644 --- a/include/pybind11/compat/pybind11_conduit_v1.h +++ b/include/pybind11/compat/pybind11_conduit_v1.h @@ -1,5 +1,70 @@ // Copyright (c) 2024 The pybind Community. +/* The pybind11_conduit_v1 feature enables type-safe interoperability between + +* different independent Python/C++ bindings systems, + +* including pybind11 versions with different PYBIND11_INTERNALS_VERSION's. + +The naming of the feature is a bit misleading: + +* The feature is in no way tied to pybind11 internals. + +* It just happens to originate from pybind11 and currently still lives there. + +* The only external dependency is . + +The implementation is a VERY light-weight dependency. It is designed to be +compatible with any ISO C++11 (or higher) compiler, and does NOT require +C++ Exception Handling to be enabled. + +Please see https://github.com/pybind/pybind11/pull/5296 for more background. + +The implementation involves a + +def _pybind11_conduit_v1_( + self, + pybind11_platform_abi_id: bytes, + cpp_type_info_capsule: capsule, + pointer_kind: bytes) -> capsule + +method that is meant to be added to Python objects wrapping C++ objects +(e.g. pybind11::class_-wrapped types). + +The design of the _pybind11_conduit_v1_ feature provides two layers of +protection against C++ ABI mismatches: + +* The first and most important layer is that the pybind11_platform_abi_id's + must match between extensions. — This will never be perfect, but is the same + pragmatic approach used in pybind11 since 2017 + (https://github.com/pybind/pybind11/commit/96997a4b9d4ec3d389a570604394af5d5eee2557, + PYBIND11_INTERNALS_ID). + +* The second layer is that the typeid(std::type_info).name()'s must match + between extensions. + +The implementation below (which is shorter than this comment!), serves as a +battle-tested specification. The main API is this one function: + +auto *cpp_pointer = pybind11_conduit_v1::get_type_pointer_ephemeral(py_obj); + +It is meant to be a minimalistic reference implementation, intentionally +without comprehensive error reporting. It is expected that major bindings +systems will roll their own, compatible implementations, potentially with +system-specific error reporting. The essential specifications all bindings +systems need to agree on are merely: + +* PYBIND11_PLATFORM_ABI_ID (const char* literal). + +* The cpp_type_info capsule (see below: a void *ptr and a const char *name). + +* The cpp_conduit capsule (see below: a void *ptr and a const char *name). + +* "raw_pointer_ephemeral" means: the lifetime of the pointer is the lifetime + of the py_obj. + +*/ + // THIS MUST STAY AT THE TOP! #include "pybind11_platform_abi_id.h"