diff --git a/.gitignore b/.gitignore
index 2a8dd6a7c3eabd..81b6bf967d3007 100644
--- a/.gitignore
+++ b/.gitignore
@@ -124,10 +124,14 @@ PCbuild/*-pgo
PCbuild/*.VC.db
PCbuild/*.VC.opendb
PCbuild/amd64/
+PCbuild/amd64t/
PCbuild/arm32/
+PCbuild/arm32t/
PCbuild/arm64/
+PCbuild/arm64t/
PCbuild/obj/
PCbuild/win32/
+PCbuild/win32t/
Tools/unicode/data/
/autom4te.cache
/build/
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index a4de7cb09cca9d..acd6c2f97348e1 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1866,6 +1866,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/Doc/license.rst b/Doc/license.rst
index 23860815e7c107..47c4fa9d582de3 100644
--- a/Doc/license.rst
+++ b/Doc/license.rst
@@ -1216,3 +1216,52 @@ license::
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
+
+
+Unicode Character Database
+--------------------------
+
+An extract of the `Unicode Character Database `__,
+converted to an internal format, is used by the :mod:`unicodedata` module and
+for the Unicode support of the :class:`str` type. The original Unicode data
+files are distributed under the `Unicode License `__::
+
+ UNICODE LICENSE V3
+
+ COPYRIGHT AND PERMISSION NOTICE
+
+ Copyright © 1991-2026 Unicode, Inc.
+
+ NOTICE TO USER: Carefully read the following legal agreement. BY
+ DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
+ SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+ TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+ DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of data files and any associated documentation (the "Data Files") or
+ software and any associated documentation (the "Software") to deal in the
+ Data Files or Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, and/or sell
+ copies of the Data Files or Software, and to permit persons to whom the
+ Data Files or Software are furnished to do so, provided that either (a)
+ this copyright and permission notice appear with all copies of the Data
+ Files or Software, or (b) this copyright and permission notice appear in
+ associated Documentation.
+
+ THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ THIRD PARTY RIGHTS.
+
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
+ BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
+ OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
+ FILES OR SOFTWARE.
+
+ Except as contained in this notice, the name of a copyright holder shall
+ not be used in advertising or otherwise to promote the sale, use or other
+ dealings in these Data Files or Software without prior written
+ authorization of the copyright holder.
diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py
index 09987b164c66e5..c67a26c9e2986c 100644
--- a/Lib/asyncio/protocols.py
+++ b/Lib/asyncio/protocols.py
@@ -199,6 +199,7 @@ def process_exited(self):
def _feed_data_to_buffered_proto(proto, data):
data_len = len(data)
+ start = 0
while data_len:
buf = proto.get_buffer(data_len)
buf_len = len(buf)
@@ -206,11 +207,11 @@ def _feed_data_to_buffered_proto(proto, data):
raise RuntimeError('get_buffer() returned an empty buffer')
if buf_len >= data_len:
- buf[:data_len] = data
+ buf[:data_len] = data[start:] if start else data
proto.buffer_updated(data_len)
return
else:
- buf[:buf_len] = data[:buf_len]
+ buf[:buf_len] = data[start:start + buf_len]
proto.buffer_updated(buf_len)
- data = data[buf_len:]
- data_len = len(data)
+ start += buf_len
+ data_len -= buf_len
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 52c1dbf9cd8cee..c0a578c86549ec 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -13,56 +13,19 @@
# 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"""
- 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)
diff --git a/Lib/test/test_asyncio/test_protocols.py b/Lib/test/test_asyncio/test_protocols.py
index 643199962b8af0..38f1e3fba90cfd 100644
--- a/Lib/test/test_asyncio/test_protocols.py
+++ b/Lib/test/test_asyncio/test_protocols.py
@@ -2,6 +2,7 @@
from unittest import mock
import asyncio
+from asyncio import protocols
def tearDownModule():
@@ -63,5 +64,32 @@ def test_subprocess_protocol(self):
self.assertNotHasAttr(sp, '__dict__')
-if __name__ == '__main__':
+class FeedDataToBufferedProtoTests(unittest.TestCase):
+ def _make_proto(self, bufsize):
+ received = bytearray()
+ buf = bytearray(bufsize)
+
+ class P(asyncio.BufferedProtocol):
+ def get_buffer(self, sizehint):
+ return buf
+
+ def buffer_updated(self, nbytes):
+ received.extend(buf[:nbytes])
+
+ return P(), received
+
+ def test_large_multi_iteration(self):
+ proto, received = self._make_proto(64)
+ data = bytes(range(256)) * 16
+ protocols._feed_data_to_buffered_proto(proto, data)
+ self.assertEqual(bytes(received), data)
+
+ def test_memoryview_input(self):
+ proto, received = self._make_proto(64)
+ payload = b"y" * 200
+ protocols._feed_data_to_buffered_proto(proto, memoryview(payload))
+ self.assertEqual(bytes(received), payload)
+
+
+if __name__ == "__main__":
unittest.main()
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 00000000000000..37463944a5de51
--- /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.
diff --git a/Modules/mathintegermodule.c b/Modules/mathintegermodule.c
index 0f660d461e349f..6d35c825349e45 100644
--- a/Modules/mathintegermodule.c
+++ b/Modules/mathintegermodule.c
@@ -180,10 +180,9 @@ that the bound `(a - 1)**2 < (n >> s) < (a + 1)**2` is maintained from one
iteration to the next. A sketch of the proof of this is given below.
In addition to the proof sketch, a formal, computer-verified proof
-of correctness (using Lean) of an equivalent recursive algorithm can be found
-here:
+of correctness (using Lean) of the algorithm can be found here:
- https://github.com/mdickinson/snippets/blob/master/proofs/isqrt/src/isqrt.lean
+ https://github.com/mdickinson/snippets/tree/41ce2d256fef06fb32f24fe7014cfa95173ac5e0/proofs/isqrt
Here's Python code equivalent to the C implementation below: