diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-05-16 11:18:59 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2022-05-16 13:16:09 +0200 |
commit | 34640e263f4e4653ed43dc589baf95b4ec1b857c (patch) | |
tree | 1c3da1dd7d2c0d5e1760b6bc0b0a8e9ec924a5d2 | |
parent | 5cd417c3613519dd295707460ba3be4ac92e6c4d (diff) | |
download | cython-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.c | 34 |
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", |