| /* Return the full version string. */ | |
| #include "Python.h" | |
| #include "pycore_initconfig.h" // _PyStatus_NO_MEMORY() | |
| static int initialized = 0; | |
| // Use the smallest possible buffer: it's only needed if malloc() fails *and* | |
| // Py_GetVersion() is called before Py_Initialize(). The buffer should be big | |
| // enough to store "3.16.0a0 " string. | |
| static char static_version[20]; | |
| static char *heap_version = NULL; | |
| PyStatus | |
| _Py_GetVersion_Init(void) | |
| { | |
| if (initialized) { | |
| return _PyStatus_OK(); | |
| } | |
| #ifdef Py_GIL_DISABLED | |
| const char *format = "%s free-threading build (%s) %s"; | |
| size_t format_len = strlen(" free-threading build () "); | |
| #else | |
| const char *format = "%s (%s) %s"; | |
| size_t format_len = strlen(" () "); | |
| #endif | |
| const char *version_str = PY_VERSION; | |
| const char *buildinfo = Py_GetBuildInfo(); | |
| const char *compiler = Py_GetCompiler(); | |
| // +1 for the trailing NUL byte | |
| size_t len = (format_len + strlen(version_str) + strlen(buildinfo) | |
| + strlen(compiler) + 1); | |
| // Always format the static version | |
| PyOS_snprintf(static_version, sizeof(static_version), format, | |
| version_str, buildinfo, compiler); | |
| heap_version = malloc(len); | |
| if (heap_version == NULL) { | |
| // If malloc() failed, don't set initialized to 1, so next | |
| // Py_GetVersion() will try again to allocate memory. | |
| return _PyStatus_NO_MEMORY(); | |
| } | |
| PyOS_snprintf(heap_version, len, format, | |
| version_str, buildinfo, compiler); | |
| initialized = 1; | |
| return _PyStatus_OK(); | |
| } | |
| void | |
| _Py_GetVersion_Fini(void) | |
| { | |
| if (heap_version) { | |
| free(heap_version); | |
| heap_version = NULL; | |
| } | |
| } | |
| const char * | |
| Py_GetVersion(void) | |
| { | |
| PyStatus status = _Py_GetVersion_Init(); | |
| // Ignore error: Py_GetVersion() API cannot report error | |
| (void)status; | |
| if (heap_version) { | |
| return heap_version; | |
| } | |
| else { | |
| return static_version; | |
| } | |
| } | |
| // Export the Python hex version as a constant. | |
| const unsigned long Py_Version = PY_VERSION_HEX; |