diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index f804e7c8..f036269a 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -13,6 +13,10 @@ #define PYBIND11_VERSION_MINOR 6 #define PYBIND11_VERSION_PATCH 3.dev1 +// Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html +// Additional convention: 0xD = dev +#define PYBIND11_VERSION_HEX 0x020603D1 + #define PYBIND11_NAMESPACE_BEGIN(name) namespace name { #define PYBIND11_NAMESPACE_END(name) } diff --git a/setup.py b/setup.py index 3a032798..ced3d695 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,36 @@ VERSION_REGEX = re.compile( r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE ) + +def build_expected_version_hex(matches): + patch_level_serial = matches["PATCH"] + serial = None + try: + major = int(matches["MAJOR"]) + minor = int(matches["MINOR"]) + flds = patch_level_serial.split(".") + if flds: + patch = int(flds[0]) + level = None + if len(flds) == 1: + level = "0" + serial = 0 + elif len(flds) == 2: + level_serial = flds[1] + for level in ("a", "b", "c", "dev"): + if level_serial.startswith(level): + serial = int(level_serial[len(level) :]) + break + except ValueError: + pass + if serial is None: + msg = 'Invalid PYBIND11_VERSION_PATCH: "{}"'.format(patch_level_serial) + raise RuntimeError(msg) + return "0x{:02x}{:02x}{:02x}{}{:x}".format( + major, minor, patch, level[:1].upper(), serial + ) + + # PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers # files, and the sys.prefix files (CMake and headers). @@ -49,6 +79,15 @@ if version != cpp_version: ) raise RuntimeError(msg) +version_hex = matches.get("HEX", "MISSING") +expected_version_hex = build_expected_version_hex(matches) +if version_hex != expected_version_hex: + msg = "PYBIND11_VERSION_HEX {} does not match expected value {}!".format( + version_hex, + expected_version_hex, + ) + raise RuntimeError(msg) + def get_and_replace(filename, binary=False, **opts): with open(filename, "rb" if binary else "r") as f: