summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-05-16 11:18:59 +0100
committerStefan Behnel <stefan_ml@behnel.de>2022-05-16 13:16:09 +0200
commit34640e263f4e4653ed43dc589baf95b4ec1b857c (patch)
tree1c3da1dd7d2c0d5e1760b6bc0b0a8e9ec924a5d2
parent5cd417c3613519dd295707460ba3be4ac92e6c4d (diff)
downloadcython-34640e263f4e4653ed43dc589baf95b4ec1b857c.tar.gz
Fix version detection and compile/runtime Python version warning with double-digit versions such as Py3.10 (GH-4777)
See https://github.com/cython/cython/issues/2542#issuecomment-1121484721
-rw-r--r--Cython/Utility/ModuleSetupCode.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 81d9b2c03..87f60e1a2 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -1223,11 +1223,37 @@ static int __Pyx_check_binary_version(void);
/////////////// CheckBinaryVersion ///////////////
static int __Pyx_check_binary_version(void) {
- char ctversion[4], rtversion[4];
- PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
- PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
- if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char ctversion[5];
+ int same=1, i, found_dot;
+ const char* rt_from_call = Py_GetVersion();
+ PyOS_snprintf(ctversion, 5, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ // slightly convoluted, but now that we're into double digit version numbers we can no longer just rely on the length.
+ found_dot = 0;
+ for (i = 0; i < 4; i++) {
+ if (!ctversion[i]) {
+ // if they are the same, just check that the runtime version doesn't continue with further numbers
+ same = (rt_from_call[i] < '0' || rt_from_call[i] > '9');
+ break;
+ }
+ if (rt_from_call[i] != ctversion[i]) {
+ same = 0;
+ break;
+ }
+ }
+
+ if (!same) {
+ char rtversion[5] = {'\0'};
+ // copy the runtime-version for the error message
char message[200];
+ for (i=0; i<4; ++i) {
+ if (rt_from_call[i] == '.') {
+ if (found_dot) break;
+ found_dot = 1;
+ } else if (rt_from_call[i] < '0' || rt_from_call[i] > '9') {
+ break;
+ }
+ rtversion[i] = rt_from_call[i];
+ }
PyOS_snprintf(message, sizeof(message),
"compiletime version %s of module '%.100s' "
"does not match runtime version %s",