extra python version sanity check at import time

Python 3.5 can often import pybind11 modules compiled compiled for
Python 3.4 (i.e. all symbols can be resolved), but this leads to crashes
later on due to changes in various Python-internal data structures. This
commit adds an extra sanity check to prevent a successful import when
the Python versions don't match.
This commit is contained in:
Wenzel Jakob 2016-10-09 19:40:15 +02:00
parent f66610153f
commit 4c00fd9ef6

View File

@ -144,16 +144,28 @@ extern "C" {
#define PYBIND11_INTERNALS_ID "__pybind11_" \ #define PYBIND11_INTERNALS_ID "__pybind11_" \
PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
#define PYBIND11_PLUGIN(name) \ #define PYBIND11_PLUGIN(name) \
static PyObject *pybind11_init(); \ static PyObject *pybind11_init(); \
PYBIND11_PLUGIN_IMPL(name) { \ PYBIND11_PLUGIN_IMPL(name) { \
try { \ int major, minor; \
return pybind11_init(); \ if (sscanf(Py_GetVersion(), "%i.%i", &major, &minor) != 2) { \
} catch (const std::exception &e) { \ PyErr_SetString(PyExc_ImportError, "Can't parse Python version."); \
PyErr_SetString(PyExc_ImportError, e.what()); \ return nullptr; \
return nullptr; \ } else if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) { \
} \ PyErr_Format(PyExc_ImportError, \
} \ "Python version mismatch: module was compiled for " \
"version %i.%i, while the interpreter is running " \
"version %i.%i.", PY_MAJOR_VERSION, PY_MINOR_VERSION, \
major, minor); \
return nullptr; \
} \
try { \
return pybind11_init(); \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
PyObject *pybind11_init() PyObject *pybind11_init()
NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(pybind11)