mirror of
https://github.com/python/cpython.git
synced 2026-10-28 18:35:21 +08:00
Py_GetVersion() now allocates memory on the heap, instead of using a static buffer, to no longer truncate the version if it's longer than 299 bytes. Update Py_GetCompiler() and Py_GetBuildInfo() tests: they are now always a part of sys.version.
80 lines
2.0 KiB
C
80 lines
2.0 KiB
C
|
|
/* 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;
|