Skip to content

Commit 6585fdf

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Import CPython 3.14.5+ stable branch (2026-06-06)
Summary: Imported python/cpython `3.14.5+` from upstream rev [`3d45ab2`](https://www.github.com/python/cpython/commit/3d45ab2520dcc1c352d0c2bbb0e1134e5d212645) (committed 2026-06-06 21:12:07+00:00). # Commit Info - Base: (`3.14.5+`) - [`a82a4d4`](https://www.github.com/python/cpython/commit/a82a4d4559ea82e5dd411f989839e59a5a1d357b) (commit date: 2026-06-04 20:44:59+00:00) - Imported: (`3.14.5+`) - [`3d45ab2`](https://www.github.com/python/cpython/commit/3d45ab2520dcc1c352d0c2bbb0e1134e5d212645) (commit date: 2026-06-06 21:12:07+00:00) # Noteworthy file changes - Low-signal files (4 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GH7JtyO74MQl86oEABmbbK0SEpAObr0LAAAz Reviewed By: itamaro Differential Revision: D107800483 fbshipit-source-id: 83ce3bc851bef6e6c000a56ff6f5a868e3bddf07
1 parent 4b32523 commit 6585fdf

18 files changed

Lines changed: 131 additions & 38 deletions

Doc/c-api/long.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
7171
on failure.
7272
7373
74+
.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)
75+
76+
Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
77+
or ``NULL`` on failure.
78+
79+
7480
.. c:function:: PyObject* PyLong_FromInt32(int32_t value)
7581
PyObject* PyLong_FromInt64(int64_t value)
7682
@@ -81,12 +87,6 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
8187
.. versionadded:: 3.14
8288
8389
84-
.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)
85-
86-
Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
87-
or ``NULL`` on failure.
88-
89-
9090
.. c:function:: PyObject* PyLong_FromUInt32(uint32_t value)
9191
PyObject* PyLong_FromUInt64(uint64_t value)
9292

Doc/library/collections.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ variants of :func:`functools.lru_cache`:
12291229
.. testcode::
12301230

12311231
from collections import OrderedDict
1232-
from time import time
1232+
from time import monotonic
12331233

12341234
class TimeBoundedLRU:
12351235
"LRU Cache that invalidates and refreshes old entries."
@@ -1244,10 +1244,10 @@ variants of :func:`functools.lru_cache`:
12441244
if args in self.cache:
12451245
self.cache.move_to_end(args)
12461246
timestamp, result = self.cache[args]
1247-
if time() - timestamp <= self.maxage:
1247+
if monotonic() - timestamp <= self.maxage:
12481248
return result
12491249
result = self.func(*args)
1250-
self.cache[args] = time(), result
1250+
self.cache[args] = monotonic(), result
12511251
if len(self.cache) > self.maxsize:
12521252
self.cache.popitem(last=False)
12531253
return result

Doc/library/importlib.resources.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ For all the following functions:
237237

238238
.. versionchanged:: 3.13
239239
Multiple *path_names* are accepted.
240-
*encoding* and *errors* must be given as keyword arguments.
241240

242241

243242
.. function:: is_resource(anchor, *path_names)

Doc/library/io.rst

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ will raise a :exc:`TypeError`. So will giving a :class:`bytes` object to the
4646
Operations that used to raise :exc:`IOError` now raise :exc:`OSError`, since
4747
:exc:`IOError` is now an alias of :exc:`OSError`.
4848

49+
.. _text-io:
4950

5051
Text I/O
5152
^^^^^^^^
@@ -73,6 +74,7 @@ In-memory text streams are also available as :class:`StringIO` objects::
7374
The text stream API is described in detail in the documentation of
7475
:class:`TextIOBase`.
7576

77+
.. _binary-io:
7678

7779
Binary I/O
7880
^^^^^^^^^^
@@ -111,6 +113,13 @@ stream by opening a file in binary mode with buffering disabled::
111113

112114
The raw stream API is described in detail in the docs of :class:`RawIOBase`.
113115

116+
.. warning::
117+
Raw I/O is a low-level interface and methods generally must have their return
118+
values checked and be explicitly retried to ensure an operation completes.
119+
For instance :meth:`~RawIOBase.write` returns the number of bytes written
120+
which may be less than the number of bytes provided (a partial write).
121+
High-level I/O objects like :ref:`binary-io` and :ref:`text-io` implement
122+
retry behavior.
114123

115124
.. _io-text-encoding:
116125

@@ -486,8 +495,11 @@ I/O Base Classes
486495

487496
Read up to *size* bytes from the object and return them. As a convenience,
488497
if *size* is unspecified or -1, all bytes until EOF are returned.
489-
Otherwise, only one system call is ever made. Fewer than *size* bytes may
490-
be returned if the operating system call returns fewer than *size* bytes.
498+
499+
Attempts to make only one system call but will retry if interrupted and
500+
the signal handler does not raise an exception (see :pep:`475` for the
501+
rationale). This means fewer than *size* bytes may be returned if the
502+
operating system call returns fewer than *size* bytes.
491503

492504
If 0 bytes are returned, and *size* was not 0, this indicates end of file.
493505
If the object is in non-blocking mode and no bytes are available,
@@ -501,13 +513,19 @@ I/O Base Classes
501513
Read and return all the bytes from the stream until EOF, using multiple
502514
calls to the stream if necessary.
503515

516+
If ``0`` bytes are returned this indicates end of file. If the object is in
517+
non-blocking mode and the underlying :meth:`read` returns ``None``
518+
indicating no bytes are available, ``None`` is returned.
519+
504520
.. method:: readinto(b, /)
505521

506522
Read bytes into a pre-allocated, writable
507523
:term:`bytes-like object` *b*, and return the
508524
number of bytes read. For example, *b* might be a :class:`bytearray`.
509-
If the object is in non-blocking mode and no bytes
510-
are available, ``None`` is returned.
525+
526+
If ``0`` is returned and ``len(b)`` is not ``0``, this indicates end of file. If
527+
the object is in non-blocking mode and no bytes are available, ``None`` is
528+
returned.
511529

512530
.. method:: write(b, /)
513531

@@ -521,6 +539,13 @@ I/O Base Classes
521539
this method returns, so the implementation should only access *b*
522540
during the method call.
523541

542+
.. warning::
543+
544+
This function does not ensure all bytes are written or an exception is
545+
thrown. Callers may implement that behavior by checking the return
546+
value and, if it is less than the length of *b*, looping with additional
547+
write calls until all unwritten bytes are written. High-level I/O
548+
objects like :ref:`binary-io` and :ref:`text-io` implement retry behavior.
524549

525550
.. class:: BufferedIOBase
526551

@@ -649,7 +674,11 @@ Raw File I/O
649674
.. class:: FileIO(name, mode='r', closefd=True, opener=None)
650675

651676
A raw binary stream representing an OS-level file containing bytes data. It
652-
inherits from :class:`RawIOBase`.
677+
inherits from :class:`RawIOBase` and implements its low-level access design.
678+
This means :meth:`~RawIOBase.write` does not guarantee all bytes are written
679+
and :meth:`~RawIOBase.read` may read less bytes than requested even when more
680+
bytes may be present in the underlying file. To get "write all" and
681+
"read at least" behavior, use :ref:`binary-io`.
653682

654683
The *name* can be one of two things:
655684

@@ -669,10 +698,6 @@ Raw File I/O
669698
implies writing, so this mode behaves in a similar way to ``'w'``. Add a
670699
``'+'`` to the mode to allow simultaneous reading and writing.
671700

672-
The :meth:`~RawIOBase.read` (when called with a positive argument),
673-
:meth:`~RawIOBase.readinto` and :meth:`~RawIOBase.write` methods on this
674-
class will only make one system call.
675-
676701
A custom opener can be used by passing a callable as *opener*. The underlying
677702
file descriptor for the file object is then obtained by calling *opener* with
678703
(*name*, *flags*). *opener* must return an open file descriptor (passing
@@ -684,6 +709,13 @@ Raw File I/O
684709
See the :func:`open` built-in function for examples on using the *opener*
685710
parameter.
686711

712+
.. warning::
713+
:class:`FileIO` is a low-level I/O object and members, such as
714+
:meth:`~RawIOBase.read` and :meth:`~RawIOBase.write`, need to have their
715+
return values checked explicitly in a retry loop to implement "write all"
716+
and "read at least" behavior. High-level I/O objects :ref:`binary-io` and
717+
:ref:`text-io` implement retry behavior.
718+
687719
.. versionchanged:: 3.3
688720
The *opener* parameter was added.
689721
The ``'x'`` mode was added.

Include/dynamic_annotations.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ int RunningOnValgrind(void);
461461

462462
#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
463463

464+
extern "C++" {
464465
/* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
465466
466467
Instead of doing
@@ -476,6 +477,8 @@ int RunningOnValgrind(void);
476477
_Py_ANNOTATE_IGNORE_READS_END();
477478
return res;
478479
}
480+
}
481+
479482
/* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
480483
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
481484
namespace { \

Lib/http/cookies.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,18 +391,18 @@ def __repr__(self):
391391
return '<%s: %s>' % (self.__class__.__name__, self.OutputString())
392392

393393
def js_output(self, attrs=None):
394-
import base64
394+
import urllib.parse
395395
# Print javascript
396396
output_string = self.OutputString(attrs)
397397
if _has_control_character(output_string):
398398
raise CookieError("Control characters are not allowed in cookies")
399399
# Base64-encode value to avoid template
400400
# injection in cookie values.
401-
output_encoded = base64.b64encode(output_string.encode('utf-8')).decode("ascii")
401+
output_encoded = urllib.parse.quote(output_string, safe='', encoding='utf-8')
402402
return """
403403
<script type="text/javascript">
404404
<!-- begin hiding
405-
document.cookie = atob(\"%s\");
405+
document.cookie = decodeURIComponent(\"%s\");
406406
// end hiding -->
407407
</script>
408408
""" % (output_encoded,)

Lib/idlelib/iomenu.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def set_filename_change_hook(self, hook):
6161
self.filename_change_hook = hook
6262

6363
filename = None
64+
file_timestamp = None
6465
dirname = None
6566

6667
def set_filename(self, filename):
@@ -127,6 +128,7 @@ def loadfile(self, filename):
127128
chars = f.read()
128129
fileencoding = f.encoding
129130
eol_convention = f.newlines
131+
file_timestamp = self.getmtime(filename)
130132
converted = False
131133
except (UnicodeDecodeError, SyntaxError):
132134
# Wait for the editor window to appear
@@ -142,6 +144,7 @@ def loadfile(self, filename):
142144
chars = f.read()
143145
fileencoding = f.encoding
144146
eol_convention = f.newlines
147+
file_timestamp = self.getmtime(filename)
145148
converted = True
146149
except OSError as err:
147150
messagebox.showerror("I/O Error", str(err), parent=self.text)
@@ -170,6 +173,7 @@ def loadfile(self, filename):
170173
self.text.insert("1.0", chars)
171174
self.reset_undo()
172175
self.set_filename(filename)
176+
self.file_timestamp = file_timestamp
173177
if converted:
174178
# We need to save the conversion results first
175179
# before being able to execute the code
@@ -206,7 +210,26 @@ def save(self, event):
206210
if not self.filename:
207211
self.save_as(event)
208212
else:
213+
# Check the time of most recent content modification so the
214+
# user doesn't accidentally overwrite a newer version of the file.
215+
try:
216+
file_timestamp = self.getmtime(self.filename)
217+
except OSError:
218+
pass
219+
else:
220+
if self.file_timestamp != file_timestamp:
221+
confirm = messagebox.askokcancel(
222+
title="File has changed",
223+
message=(
224+
"The file has changed on disk since reading it!\n\n"
225+
"Do you really want to overwrite it?"),
226+
default=messagebox.CANCEL,
227+
parent=self.text)
228+
if not confirm:
229+
return "break"
230+
209231
if self.writefile(self.filename):
232+
self.file_timestamp = self.getmtime(self.filename)
210233
self.set_saved(True)
211234
try:
212235
self.editwin.store_file_breaks()
@@ -219,6 +242,7 @@ def save_as(self, event):
219242
filename = self.asksavefile()
220243
if filename:
221244
if self.writefile(filename):
245+
self.file_timestamp = self.getmtime(filename)
222246
self.set_filename(filename)
223247
self.set_saved(1)
224248
try:
@@ -251,6 +275,9 @@ def writefile(self, filename):
251275
parent=self.text)
252276
return False
253277

278+
def getmtime(self, filename):
279+
return os.stat(filename).st_mtime
280+
254281
def fixnewlines(self):
255282
"""Return text with os eols.
256283

Lib/shutil.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -940,8 +940,8 @@ def move(src, dst, copy_function=copy2):
940940
return real_dst
941941

942942
def _destinsrc(src, dst):
943-
src = os.path.abspath(src)
944-
dst = os.path.abspath(dst)
943+
src = os.path.realpath(src)
944+
dst = os.path.realpath(dst)
945945
if not src.endswith(os.path.sep):
946946
src += os.path.sep
947947
if not dst.endswith(os.path.sep):

Lib/test/test_http_cookies.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Simple test suite for http/cookies.py
2-
import base64
32
import copy
43
import unittest
54
import doctest
65
from http import cookies
76
import pickle
87
from test import support
8+
import urllib.parse
99

1010

1111
class CookieTests(unittest.TestCase):
@@ -152,19 +152,19 @@ def test_load(self):
152152

153153
self.assertEqual(C.output(['path']),
154154
'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
155-
cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii')
155+
cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme; Version=1', safe='', encoding='utf-8')
156156
self.assertEqual(C.js_output(), fr"""
157157
<script type="text/javascript">
158158
<!-- begin hiding
159-
document.cookie = atob("{cookie_encoded}");
159+
document.cookie = decodeURIComponent("{cookie_encoded}");
160160
// end hiding -->
161161
</script>
162162
""")
163-
cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii')
163+
cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme', safe='', encoding='utf-8')
164164
self.assertEqual(C.js_output(['path']), fr"""
165165
<script type="text/javascript">
166166
<!-- begin hiding
167-
document.cookie = atob("{cookie_encoded}");
167+
document.cookie = decodeURIComponent("{cookie_encoded}");
168168
// end hiding -->
169169
</script>
170170
""")
@@ -269,19 +269,19 @@ def test_quoted_meta(self):
269269

270270
self.assertEqual(C.output(['path']),
271271
'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
272-
expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii')
272+
expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1', safe='', encoding='utf-8')
273273
self.assertEqual(C.js_output(), fr"""
274274
<script type="text/javascript">
275275
<!-- begin hiding
276-
document.cookie = atob("{expected_encoded_cookie}");
276+
document.cookie = decodeURIComponent("{expected_encoded_cookie}");
277277
// end hiding -->
278278
</script>
279279
""")
280-
expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii')
280+
expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme', safe='', encoding='utf-8')
281281
self.assertEqual(C.js_output(['path']), fr"""
282282
<script type="text/javascript">
283283
<!-- begin hiding
284-
document.cookie = atob("{expected_encoded_cookie}");
284+
document.cookie = decodeURIComponent("{expected_encoded_cookie}");
285285
// end hiding -->
286286
</script>
287287
""")
@@ -372,13 +372,14 @@ def test_setter(self):
372372
self.assertEqual(
373373
M.output(),
374374
"Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i))
375-
expected_encoded_cookie = base64.b64encode(
376-
("%s=%s; Path=/foo" % (i, "%s_coded_val" % i)).encode("ascii")
377-
).decode('ascii')
375+
expected_encoded_cookie = urllib.parse.quote(
376+
"%s=%s; Path=/foo" % (i, "%s_coded_val" % i),
377+
safe='', encoding='utf-8',
378+
)
378379
expected_js_output = """
379380
<script type="text/javascript">
380381
<!-- begin hiding
381-
document.cookie = atob("%s");
382+
document.cookie = decodeURIComponent("%s");
382383
// end hiding -->
383384
</script>
384385
""" % (expected_encoded_cookie,)

0 commit comments

Comments
 (0)