From 3a1e11c11cc2ad6c75913dbf1cd623679ccc71a3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 23 Jul 2026 13:07:49 -0400 Subject: [PATCH 1/3] Soft-deprecate ctypes.util.find_msvcrt --- Doc/library/ctypes.rst | 4 ++++ Lib/ctypes/util.py | 29 +++++++++-------------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 34c8636abaa925d..a88afabd2a1f0cc 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1867,6 +1867,10 @@ like ``find_library("c")`` will fail and return ``None``. .. availability:: Windows + .. soft-deprecated:: 3.16 + This function now always returns ``None``, as there are no more + VC runtime DLLs that are a single file and supported by Microsoft. + .. _ctypes-listing-loaded-shared-libraries: diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index b035bfb99feee0a..551004126dff165 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -40,29 +40,18 @@ def _get_build_version(): return None def find_msvcrt(): - """Return the name of the VC runtime dll""" - version = _get_build_version() - if version is None: - # better be safe than sorry - return None - if version <= 6: - clibname = 'msvcrt' - elif version <= 13: - clibname = 'msvcr%d' % (version * 10) - else: - # CRT is no longer directly loadable. See issue23606 for the - # discussion about alternative approaches. - return None - - # If python was built with in debug mode - import importlib.machinery - if '_d.pyd' in importlib.machinery.EXTENSION_SUFFIXES: - clibname += 'd' - return clibname+'.dll' + """Return the name of the VC runtime dll. + This is soft deprecated as of Python 3.16.""" + # See gh-154199. In short, this function wasn't able to return + # newer msvcrt versions (because there was no single msvcrt DLL), + # and the versions that are a single DLL are no longer supported + # by Microsoft. + return None def find_library(name): if name in ('c', 'm'): - return find_msvcrt() + # See gh-67794; there is no single VC runtime DLL anymore. + return None # See MSDN for the REAL search order. for directory in os.environ['PATH'].split(os.pathsep): fname = os.path.join(directory, name) From 6764e1cc094874656152ccb8d77c877973e9838f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 23 Jul 2026 13:09:28 -0400 Subject: [PATCH 2/3] Add blurb. --- .../next/Library/2026-07-23-13-09-25.gh-issue-154199.hmBfrS.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-07-23-13-09-25.gh-issue-154199.hmBfrS.rst diff --git a/Misc/NEWS.d/next/Library/2026-07-23-13-09-25.gh-issue-154199.hmBfrS.rst b/Misc/NEWS.d/next/Library/2026-07-23-13-09-25.gh-issue-154199.hmBfrS.rst new file mode 100644 index 000000000000000..37463944a5de51b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-23-13-09-25.gh-issue-154199.hmBfrS.rst @@ -0,0 +1,2 @@ +Make :func:`ctypes.util.find_msvcrt` always return ``None`` for +compatibility reasons. From b04411dda99b4c56651801e5e141b14657c08ab4 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 23 Jul 2026 17:10:44 -0400 Subject: [PATCH 3/3] Remove _get_build_version --- Lib/ctypes/util.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 551004126dff165..963d454835f6ce1 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -13,32 +13,6 @@ # find_library(name) returns the pathname of a library, or None. if os.name == "nt": - - def _get_build_version(): - """Return the version of MSVC that was used to build Python. - - For Python 2.3 and up, the version number is included in - sys.version. For earlier versions, assume the compiler is MSVC 6. - """ - # This function was copied from Lib/distutils/msvccompiler.py - prefix = "MSC v." - i = sys.version.find(prefix) - if i == -1: - return 6 - i = i + len(prefix) - s, rest = sys.version[i:].split(" ", 1) - majorVersion = int(s[:-2]) - 6 - if majorVersion >= 13: - majorVersion += 1 - minorVersion = int(s[2:3]) / 10.0 - # I don't think paths are affected by minor version in version 6 - if majorVersion == 6: - minorVersion = 0 - if majorVersion >= 6: - return majorVersion + minorVersion - # else we don't know what version of the compiler this is - return None - def find_msvcrt(): """Return the name of the VC runtime dll. This is soft deprecated as of Python 3.16."""