Skip to content

Commit b2ff361

Browse files
committed
update to python 3.14.10
1 parent bdee348 commit b2ff361

115 files changed

Lines changed: 604 additions & 305 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/CI_build.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ jobs:
4444
if: matrix.build_configuration == 'Release'
4545
working-directory: installer
4646
run: |
47-
$env:PYTHONBUILDDIR_ARM64='${{ github.workspace }}\packages\pythonarm64.3.14.9\tools'
48-
$env:PYTHONBUILDDIR_X64='${{ github.workspace }}\packages\python.3.14.9\tools'
49-
$env:PYTHONBUILDDIR='${{ github.workspace }}\packages\pythonx86.3.14.9\tools'
47+
$env:PYTHONBUILDDIR_ARM64='${{ github.workspace }}\packages\pythonarm64.3.14.10\tools'
48+
$env:PYTHONBUILDDIR_X64='${{ github.workspace }}\packages\python.3.14.10\tools'
49+
$env:PYTHONBUILDDIR='${{ github.workspace }}\packages\pythonx86.3.14.10\tools'
5050
Rename-Item -Path ".\buildPaths.bat.orig" -NewName "buildPaths.bat"
5151
dotnet tool install --global wix --version 7.0.0
5252
.\buildAll.bat ${{ matrix.build_platform }}

‎PythonLib/full/_pydecimal.py‎

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,95 @@ def IEEEContext(bits, /):
444444

445445
##### Decimal class #######################################################
446446

447+
# Observation: For all q >= 0 and a >= 1, q < 10**a iff len(str(q)) <= a.
448+
#
449+
# The constants below are used to speed-up "q < 10 ** a" checks to avoid
450+
# computing len(str(q)) as much as possible. Those speed-ups are based on
451+
# the following claims.
452+
#
453+
# See https://github.com/python/cpython/issues/140036 for details.
454+
455+
_LOG_10_BASE_2_LO = float.fromhex('0x1.a934f0979a371p+1')
456+
assert pow(2, _LOG_10_BASE_2_LO) < 10
457+
458+
_LOG_10_BASE_2_HI = float.fromhex('0x1.a934f0979a372p+1')
459+
assert pow(2, _LOG_10_BASE_2_HI) > 10
460+
461+
462+
def _tento(n):
463+
"""Compute 10 ** n with 1 base-5 exponentiation and 1 bit-shift."""
464+
return (5 ** n) << n
465+
466+
467+
def _is_less_than_pow10a_use_str(q, a):
468+
"""Try to efficiently check len(str(q)) <= a, or equivalently q < 10**a.
469+
470+
If the comparison cannot be obtained from q.bit_length(),
471+
then str(q) is explicitly computed and may raise ValueError.
472+
473+
Return (len(str(q)) <= a, None) or (len(str(q)) <= a, str(q)).
474+
"""
475+
if q.bit_length() < a * _LOG_10_BASE_2_LO:
476+
# Claim: If 0 < z <= log2(10) and q.bit_length() < a*z, then q < 10**a.
477+
# Proof: By contradiction, q >= 10**a. By definition,
478+
# log2(q) >= a*log2(10) >= a*z > q.bit_length().
479+
# In particular, q > 2**q.bit_length(), which is impossible.
480+
481+
# assert q < 10 ** a
482+
return True, None
483+
elif q.bit_length() >= 1 + a * _LOG_10_BASE_2_HI:
484+
# Claim: If z > log2(10) and q.bit_length() >= 1 + a*z, then q > 10**a.
485+
# Proof: Since q >= 2**(q.bit_length()-1), we have
486+
# q >= 2**(q.bit_length()-1) >= 2**(a*z) > 2**(a*log2(10)) = 10**a.
487+
488+
# assert q > 10 ** a
489+
return False, None
490+
# Handle cases that fail due to floating point precision loss
491+
# when computing _LOG_10_BASE_2_LO and _LOG_10_BASE_2_HI, or
492+
# that cannot be distinguished with (q.bit_length(), a) only.
493+
#
494+
# For instance, (q1, a) = (95, 2) and (q2, a) = (105, 2) produce
495+
# different results but q1.bit_length() == q2.bit_length() == 7.
496+
str_q = str(q) # can raise a ValueError
497+
is_valid = len(str_q) <= a
498+
return is_valid, str_q
499+
500+
501+
def _is_less_than_pow10a(q, a, *, exact=True, ulp_order=20):
502+
"""Check that len(str(q)) <= a without computing str(q).
503+
504+
When *exact* is false, computing len(str(q)) is replaced by f(q):
505+
506+
f(q) = floor(log10(q) + ulp(log10(q)) * ulp_order + 1.0)
507+
508+
Most of the time, f(q) = len(str(q)) but in some cases, it may
509+
happen that f(q) > len(str(q)).
510+
511+
When *exact* is true, computing len(str(q)) requires one bigint
512+
exponentiation that only depends on q.
513+
"""
514+
if q < 10:
515+
return a >= 1
516+
517+
z = _math.log10(q)
518+
t = _math.ulp(z) * ulp_order
519+
520+
if exact:
521+
intlo = int(z - t)
522+
inthi = int(z + t)
523+
diff = inthi - intlo
524+
assert diff in (0, 1)
525+
if diff == 1:
526+
lo = _tento(inthi) # may be slow
527+
if q < lo:
528+
inthi -= 1
529+
assert q >= (lo // 10)
530+
ndigits = inthi + 1
531+
else:
532+
ndigits = int(z + t + 1.0)
533+
return ndigits <= a
534+
535+
447536
# Do not subclass Decimal from numbers.Real and do not register it as such
448537
# (because Decimals are not interoperable with floats). See the notes in
449538
# numbers.py for more detail.
@@ -1357,8 +1446,13 @@ def _divide(self, other, context):
13571446
else:
13581447
op2.int *= 10**(op2.exp - op1.exp)
13591448
q, r = divmod(op1.int, op2.int)
1360-
if q < 10**context.prec:
1361-
return (_dec_from_triple(sign, str(q), 0),
1449+
is_valid, str_q = _is_less_than_pow10a_use_str(q, context.prec)
1450+
if is_valid:
1451+
if str_q is None:
1452+
str_q = str(q)
1453+
# assert q < 10 ** context.prec
1454+
# assert len(str(q)) <= context.prec
1455+
return (_dec_from_triple(sign, str_q, 0),
13621456
_dec_from_triple(self._sign, str(r), ideal_exp))
13631457

13641458
# Here the quotient is too large to be representable
@@ -1513,7 +1607,9 @@ def remainder_near(self, other, context=None):
15131607
r -= op2.int
15141608
q += 1
15151609

1516-
if q >= 10**context.prec:
1610+
if not _is_less_than_pow10a(q, context.prec):
1611+
# assert q >= 10 ** context.prec
1612+
# assert len(str(q)) > context.prec
15171613
return context._raise_error(DivisionImpossible)
15181614

15191615
# result has same sign as self unless r is negative

‎PythonLib/full/_pyio.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ def nreadahead():
528528
return 1
529529
n = (readahead.find(b"\n") + 1) or len(readahead)
530530
if size >= 0:
531-
n = min(n, size)
531+
n = min(n, size - len(res))
532532
return n
533533
else:
534534
def nreadahead():

‎PythonLib/full/_pyrepl/simple_interact.py‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,14 @@ def maybe_run_command(statement: str) -> bool:
136136
sys.stdout.flush()
137137
except Exception:
138138
pass
139-
140-
ps1 = getattr(sys, "ps1", ">>> ")
141-
ps2 = getattr(sys, "ps2", "... ")
139+
try:
140+
ps1 = str(getattr(sys, "ps1", ">>> "))
141+
except Exception:
142+
ps1 = ">>> "
143+
try:
144+
ps2 = str(getattr(sys, "ps2", "... "))
145+
except Exception:
146+
ps2 = "... "
142147
try:
143148
statement = multiline_input(more_lines, ps1, ps2)
144149
except EOFError:

‎PythonLib/full/asyncio/sslproto.py‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -659,13 +659,21 @@ def _do_shutdown(self):
659659
self._on_shutdown_complete(None)
660660

661661
def _on_shutdown_complete(self, shutdown_exc):
662-
if self._shutdown_timeout_handle is not None:
663-
self._shutdown_timeout_handle.cancel()
664-
self._shutdown_timeout_handle = None
665-
666662
if shutdown_exc:
663+
if self._shutdown_timeout_handle is not None:
664+
self._shutdown_timeout_handle.cancel()
665+
self._shutdown_timeout_handle = None
667666
self._fatal_error(shutdown_exc)
668667
else:
668+
# transport.close() flushes its write buffer first, which a peer
669+
# that does not read can delay forever. Keep the timeout (or
670+
# start it, if the peer initiated the shutdown) until
671+
# connection_lost().
672+
if self._shutdown_timeout_handle is None:
673+
self._shutdown_timeout_handle = self._loop.call_later(
674+
self._ssl_shutdown_timeout,
675+
self._check_shutdown_timeout
676+
)
669677
self._loop.call_soon(self._transport.close)
670678

671679
def _abort(self, exc):

‎PythonLib/full/asyncio/unix_events.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,15 @@ def _do_waitpid(self, loop, expected_pid, callback, args):
948948
# This makes the reaping of the child and notification of the return code
949949
# atomic with respect to the event loop thread.
950950
try:
951-
os.waitid(os.P_PID, expected_pid, os.WEXITED | os.WNOWAIT)
951+
while True:
952+
res = os.waitid(os.P_PID, expected_pid, os.WEXITED | os.WNOWAIT)
953+
# On macOS, waitid() with WEXITED incorrectly returns stopped
954+
# child processes (si_code == CLD_STOPPED). Consume the stop
955+
# notification so we wait for actual process termination.
956+
if res.si_code == os.CLD_STOPPED:
957+
os.waitid(os.P_PID, expected_pid, os.WSTOPPED | os.WNOHANG)
958+
continue
959+
break
952960
except ChildProcessError:
953961
# The child process is already reaped
954962
pass

‎PythonLib/full/hmac.py‎

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@ def digest_wrapper(d=b''):
3939
return digest_wrapper
4040

4141

42+
def _select_blocksize(obj, default, stacklevel=3):
43+
if hasattr(obj, 'block_size'):
44+
blocksize = obj.block_size
45+
if blocksize < 16:
46+
import warnings
47+
48+
warnings.warn(f"block_size of {blocksize} seems too small; "
49+
f"using our default of {default}.",
50+
RuntimeWarning, stacklevel=stacklevel)
51+
blocksize = default
52+
else:
53+
import warnings
54+
55+
warnings.warn("No block_size attribute on given digest object; "
56+
f"Assuming {default}.",
57+
RuntimeWarning, stacklevel=stacklevel)
58+
blocksize = default
59+
return blocksize
60+
61+
62+
4263
class HMAC:
4364
"""RFC 2104 HMAC class. Also complies with RFC 4231.
4465
@@ -106,28 +127,14 @@ def _init_builtin_hmac(self, key, msg, digestmod):
106127
self.block_size = self._hmac.block_size
107128

108129
def _init_old(self, key, msg, digestmod):
109-
import warnings
110-
111130
digest_cons = _get_digest_constructor(digestmod)
112131

113132
self._hmac = None
114133
self._outer = digest_cons()
115134
self._inner = digest_cons()
116135
self.digest_size = self._inner.digest_size
117136

118-
if hasattr(self._inner, 'block_size'):
119-
blocksize = self._inner.block_size
120-
if blocksize < 16:
121-
warnings.warn(f"block_size of {blocksize} seems too small; "
122-
f"using our default of {self.blocksize}.",
123-
RuntimeWarning, 2)
124-
blocksize = self.blocksize # pragma: no cover
125-
else:
126-
warnings.warn("No block_size attribute on given digest object; "
127-
f"Assuming {self.blocksize}.",
128-
RuntimeWarning, 2)
129-
blocksize = self.blocksize # pragma: no cover
130-
137+
blocksize = _select_blocksize(self._inner, self.blocksize)
131138
if len(key) > blocksize:
132139
key = digest_cons(key).digest()
133140

@@ -261,7 +268,7 @@ def _compute_digest_fallback(key, msg, digest):
261268
digest_cons = _get_digest_constructor(digest)
262269
inner = digest_cons()
263270
outer = digest_cons()
264-
blocksize = getattr(inner, 'block_size', 64)
271+
blocksize = _select_blocksize(inner, HMAC.blocksize)
265272
if len(key) > blocksize:
266273
key = digest_cons(key).digest()
267274
key = key.ljust(blocksize, b'\0')

‎PythonLib/full/http/cookiejar.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,12 @@ def set_ok_version(self, cookie, request):
974974
_debug(" Set-Cookie2 without version attribute (%s=%s)",
975975
cookie.name, cookie.value)
976976
return False
977+
if cookie.version < 0:
978+
# Neither the Netscape (version 0) nor the RFC 2965 (version > 0)
979+
# rules would apply, so the domain checks would all be skipped.
980+
_debug(" negative version attribute (%s=%s)",
981+
cookie.name, cookie.value)
982+
return False
977983
if cookie.version > 0 and not self.rfc2965:
978984
_debug(" RFC 2965 cookies are switched off")
979985
return False
@@ -1114,6 +1120,9 @@ def return_ok(self, cookie, request):
11141120
return True
11151121

11161122
def return_ok_version(self, cookie, request):
1123+
if cookie.version < 0:
1124+
_debug(" negative version attribute")
1125+
return False
11171126
if cookie.version > 0 and not self.rfc2965:
11181127
_debug(" RFC 2965 cookies are switched off")
11191128
return False
@@ -1502,6 +1511,8 @@ def _cookie_from_cookie_tuple(self, tup, request):
15021511
version = int(version)
15031512
except ValueError:
15041513
return None # invalid version, ignore cookie
1514+
if version < 0:
1515+
return None # invalid version, ignore cookie
15051516
secure = standard.get("secure", False)
15061517
# (discard is also set if expires is Absent)
15071518
discard = standard.get("discard", False)

‎PythonLib/full/logging/handlers.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ def doRollover(self):
446446
timeTuple = time.localtime(t + addend)
447447
dfn = self.rotation_filename(self.baseFilename + "." +
448448
time.strftime(self.suffix, timeTuple))
449+
self.rolloverAt = self.computeRollover(currentTime)
449450
if os.path.exists(dfn):
450451
# Already rolled over.
451452
return
@@ -459,7 +460,6 @@ def doRollover(self):
459460
os.remove(s)
460461
if not self.delay:
461462
self.stream = self._open()
462-
self.rolloverAt = self.computeRollover(currentTime)
463463

464464
class WatchedFileHandler(logging.FileHandler):
465465
"""

‎PythonLib/full/mailbox.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,7 @@ def _install_message(self, message):
14881488
vis_buffer = io.BytesIO()
14891489
vis_generator = email.generator.BytesGenerator(vis_buffer, False, 0)
14901490
vis_generator.flatten(message.get_visible())
1491+
vis_buffer.seek(0)
14911492
while True:
14921493
line = vis_buffer.readline()
14931494
self._file.write(line.replace(b'\n', linesep))

0 commit comments

Comments
 (0)