]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-145410: Add _sysconfig.get_platform() function (#146145)
authorVictor Stinner <vstinner@python.org>
Wed, 18 Mar 2026 23:28:21 +0000 (00:28 +0100)
committerGitHub <noreply@github.com>
Wed, 18 Mar 2026 23:28:21 +0000 (00:28 +0100)
On Windows, sysconfig.get_platform() now gets the platform from the
_sysconfig module instead of parsing sys.version string.

Lib/sysconfig/__init__.py
Lib/test/test_sysconfig.py
Misc/NEWS.d/next/Library/2026-03-18-23-54-36.gh-issue-145410.NvLWj5.rst [new file with mode: 0644]
Modules/_sysconfig.c
Modules/clinic/_sysconfig.c.h

index 8ff9c99435bb1aa44be6fad08e110ec3d6dfb688..6507a7b5b0f695379033c07b0de817064afaa5f0 100644 (file)
@@ -665,12 +665,10 @@ def get_platform():
 
     For other non-POSIX platforms, currently just returns :data:`sys.platform`."""
     if os.name == 'nt':
-        if 'amd64' in sys.version.lower():
-            return 'win-amd64'
-        if '(arm)' in sys.version.lower():
-            return 'win-arm32'
-        if '(arm64)' in sys.version.lower():
-            return 'win-arm64'
+        import _sysconfig
+        platform = _sysconfig.get_platform()
+        if platform:
+            return platform
         return sys.platform
 
     if os.name != "posix" or not hasattr(os, 'uname'):
index 502103ce6293585cc942678eb4f9110f5b68dc30..e43f91eb9238f9c8f0dbdec37f9b02f272f999cf 100644 (file)
@@ -7,6 +7,7 @@ import subprocess
 import shutil
 import json
 import textwrap
+from unittest.mock import patch
 from copy import copy
 
 from test import support
@@ -247,19 +248,15 @@ class TestSysConfig(unittest.TestCase, VirtualEnvironmentMixin):
         self.assertIsInstance(actual_platform, str)
         self.assertTrue(actual_platform)
 
-        # windows XP, 32bits
+        # Windows
         os.name = 'nt'
-        sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
-                       '[MSC v.1310 32 bit (Intel)]')
-        sys.platform = 'win32'
-        self.assertEqual(get_platform(), 'win32')
-
-        # windows XP, amd64
-        os.name = 'nt'
-        sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
-                       '[MSC v.1310 32 bit (Amd64)]')
-        sys.platform = 'win32'
-        self.assertEqual(get_platform(), 'win-amd64')
+        with patch('_sysconfig.get_platform', create=True, return_value='win32'):
+            self.assertEqual(get_platform(), 'win32')
+        with patch('_sysconfig.get_platform', create=True, return_value='win-amd64'):
+            self.assertEqual(get_platform(), 'win-amd64')
+        sys.platform = 'test-plaform'
+        with patch('_sysconfig.get_platform', create=True, return_value=None):
+            self.assertEqual(get_platform(), 'test-plaform')
 
         # macbook
         os.name = 'posix'
diff --git a/Misc/NEWS.d/next/Library/2026-03-18-23-54-36.gh-issue-145410.NvLWj5.rst b/Misc/NEWS.d/next/Library/2026-03-18-23-54-36.gh-issue-145410.NvLWj5.rst
new file mode 100644 (file)
index 0000000..8d84b70
--- /dev/null
@@ -0,0 +1,3 @@
+On Windows, :func:`sysconfig.get_platform` now gets the platform from the
+``_sysconfig`` module instead of parsing :data:`sys.version` string. Patch
+by Victor Stinner.
index 345498e670dd6a15bda74b2e0ea57f08f00b1e06..bcb9d108174f4390d396249aed6af4c8edf78ad9 100644 (file)
@@ -81,11 +81,48 @@ _sysconfig_config_vars_impl(PyObject *module)
     return config;
 }
 
+#ifdef MS_WINDOWS
+/*[clinic input]
+_sysconfig.get_platform
+
+Return a string that identifies the current platform.
+[clinic start generated code]*/
+
+static PyObject *
+_sysconfig_get_platform_impl(PyObject *module)
+/*[clinic end generated code: output=4ecbbe2b77633f3e input=c0b43abda44f9a01]*/
+{
+#ifdef MS_WIN64
+#  if defined(_M_X64) || defined(_M_AMD64)
+#    define SYSCONFIG_PLATFORM "win-amd64"
+#  elif defined(_M_ARM64)
+#    define SYSCONFIG_PLATFORM "win-arm64"
+#  endif
+#endif
+
+#if defined(MS_WIN32) && !defined(MS_WIN64)
+#  if defined(_M_IX86)
+#    define SYSCONFIG_PLATFORM "win32"
+#  elif defined(_M_ARM)
+#    define SYSCONFIG_PLATFORM "win-arm32"
+#  endif
+#endif
+
+#ifdef SYSCONFIG_PLATFORM
+    return PyUnicode_FromString(SYSCONFIG_PLATFORM);
+#else
+    Py_RETURN_NONE;
+#endif
+}
+#endif  // MS_WINDOWS
+
+
 PyDoc_STRVAR(sysconfig__doc__,
 "A helper for the sysconfig module.");
 
 static struct PyMethodDef sysconfig_methods[] = {
     _SYSCONFIG_CONFIG_VARS_METHODDEF
+    _SYSCONFIG_GET_PLATFORM_METHODDEF
     {NULL, NULL}
 };
 
index eb3d396298bb21652f203f48111829612af31220..031a738cf47c7be9118656cc4d8c5d3f86a7a139 100644 (file)
@@ -19,4 +19,30 @@ _sysconfig_config_vars(PyObject *module, PyObject *Py_UNUSED(ignored))
 {
     return _sysconfig_config_vars_impl(module);
 }
-/*[clinic end generated code: output=25d395cf02eced1f input=a9049054013a1b77]*/
+
+#if defined(MS_WINDOWS)
+
+PyDoc_STRVAR(_sysconfig_get_platform__doc__,
+"get_platform($module, /)\n"
+"--\n"
+"\n"
+"Return a string that identifies the current platform.");
+
+#define _SYSCONFIG_GET_PLATFORM_METHODDEF    \
+    {"get_platform", (PyCFunction)_sysconfig_get_platform, METH_NOARGS, _sysconfig_get_platform__doc__},
+
+static PyObject *
+_sysconfig_get_platform_impl(PyObject *module);
+
+static PyObject *
+_sysconfig_get_platform(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return _sysconfig_get_platform_impl(module);
+}
+
+#endif /* defined(MS_WINDOWS) */
+
+#ifndef _SYSCONFIG_GET_PLATFORM_METHODDEF
+    #define _SYSCONFIG_GET_PLATFORM_METHODDEF
+#endif /* !defined(_SYSCONFIG_GET_PLATFORM_METHODDEF) */
+/*[clinic end generated code: output=558531e148f92320 input=a9049054013a1b77]*/