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: