Skip to content

Commit 0f78d2c

Browse files
committed
update to python 3.14.5
1 parent b2aad95 commit 0f78d2c

138 files changed

Lines changed: 849 additions & 545 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.4\tools'
48-
$env:PYTHONBUILDDIR_X64='${{ github.workspace }}\packages\python.3.14.4\tools'
49-
$env:PYTHONBUILDDIR='${{ github.workspace }}\packages\pythonx86.3.14.4\tools'
47+
$env:PYTHONBUILDDIR_ARM64='${{ github.workspace }}\packages\pythonarm64.3.14.5\tools'
48+
$env:PYTHONBUILDDIR_X64='${{ github.workspace }}\packages\python.3.14.5\tools'
49+
$env:PYTHONBUILDDIR='${{ github.workspace }}\packages\pythonx86.3.14.5\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/_pyrepl/reader.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ def update_screen(self) -> None:
644644

645645
def refresh(self) -> None:
646646
"""Recalculate and refresh the screen."""
647+
self.console.height, self.console.width = self.console.getheightwidth()
647648
# this call sets up self.cxy, so call it first.
648649
self.screen = self.calc_screen()
649650
self.console.refresh(self.screen, self.cxy)

PythonLib/full/_pyrepl/unix_console.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,6 @@ def __move_tall(self, x, y):
776776
self.__write_code(self._cup, y - self.__offset, x)
777777

778778
def __sigwinch(self, signum, frame):
779-
self.height, self.width = self.getheightwidth()
780779
self.event_queue.insert(Event("resize", None))
781780

782781
def __hide_cursor(self):

PythonLib/full/annotationlib.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Format(enum.IntEnum):
4747
"__cell__",
4848
"__owner__",
4949
"__stringifier_dict__",
50+
"__resolved_str_cache__",
5051
)
5152

5253

@@ -94,6 +95,7 @@ def __init__(
9495
# value later.
9596
self.__code__ = None
9697
self.__ast_node__ = None
98+
self.__resolved_str_cache__ = None
9799

98100
def __init_subclass__(cls, /, *args, **kwds):
99101
raise TypeError("Cannot subclass ForwardRef")
@@ -113,7 +115,7 @@ def evaluate(
113115
"""
114116
match format:
115117
case Format.STRING:
116-
return self.__forward_arg__
118+
return self.__resolved_str__
117119
case Format.VALUE:
118120
is_forwardref_format = False
119121
case Format.FORWARDREF:
@@ -258,6 +260,24 @@ def __forward_arg__(self):
258260
"Attempted to access '__forward_arg__' on an uninitialized ForwardRef"
259261
)
260262

263+
@property
264+
def __resolved_str__(self):
265+
# __forward_arg__ with any names from __extra_names__ replaced
266+
# with the type_repr of the value they represent
267+
if self.__resolved_str_cache__ is None:
268+
resolved_str = self.__forward_arg__
269+
names = self.__extra_names__
270+
271+
if names:
272+
visitor = _ExtraNameFixer(names)
273+
ast_expr = ast.parse(resolved_str, mode="eval").body
274+
node = visitor.visit(ast_expr)
275+
resolved_str = ast.unparse(node)
276+
277+
self.__resolved_str_cache__ = resolved_str
278+
279+
return self.__resolved_str_cache__
280+
261281
@property
262282
def __forward_code__(self):
263283
if self.__code__ is not None:
@@ -321,7 +341,7 @@ def __repr__(self):
321341
extra.append(", is_class=True")
322342
if self.__owner__ is not None:
323343
extra.append(f", owner={self.__owner__!r}")
324-
return f"ForwardRef({self.__forward_arg__!r}{''.join(extra)})"
344+
return f"ForwardRef({self.__resolved_str__!r}{''.join(extra)})"
325345

326346

327347
_Template = type(t"")
@@ -357,6 +377,7 @@ def __init__(
357377
self.__cell__ = cell
358378
self.__owner__ = owner
359379
self.__stringifier_dict__ = stringifier_dict
380+
self.__resolved_str_cache__ = None # Needed for ForwardRef
360381

361382
def __convert_to_ast(self, other):
362383
if isinstance(other, _Stringifier):
@@ -1163,3 +1184,14 @@ def _get_dunder_annotations(obj):
11631184
if not isinstance(ann, dict):
11641185
raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
11651186
return ann
1187+
1188+
1189+
class _ExtraNameFixer(ast.NodeTransformer):
1190+
"""Fixer for __extra_names__ items in ForwardRef __repr__ and string evaluation"""
1191+
def __init__(self, extra_names):
1192+
self.extra_names = extra_names
1193+
1194+
def visit_Name(self, node: ast.Name):
1195+
if (new_name := self.extra_names.get(node.id, _sentinel)) is not _sentinel:
1196+
node = ast.Name(id=type_repr(new_name))
1197+
return node

PythonLib/full/argparse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2678,7 +2678,7 @@ def _check_value(self, action, value):
26782678

26792679
if value not in choices:
26802680
args = {'value': str(value),
2681-
'choices': ', '.join(map(str, action.choices))}
2681+
'choices': ', '.join(repr(str(choice)) for choice in action.choices)}
26822682
msg = _('invalid choice: %(value)r (choose from %(choices)s)')
26832683

26842684
if self.suggest_on_error and isinstance(value, str):

PythonLib/full/asyncio/__main__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,15 @@ def run(self):
9898

9999
if not sys.flags.isolated and (startup_path := os.getenv("PYTHONSTARTUP")):
100100
sys.audit("cpython.run_startup", startup_path)
101-
102-
import tokenize
103-
with tokenize.open(startup_path) as f:
104-
startup_code = compile(f.read(), startup_path, "exec")
101+
try:
102+
import tokenize
103+
with tokenize.open(startup_path) as f:
104+
startup_code = compile(f.read(), startup_path, "exec")
105105
exec(startup_code, console.locals)
106+
except SystemExit:
107+
raise
108+
except BaseException:
109+
console.showtraceback()
106110

107111
ps1 = getattr(sys, "ps1", ">>> ")
108112
if CAN_USE_PYREPL:

PythonLib/full/asyncio/windows_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ def fileno(self):
111111

112112
def close(self, *, CloseHandle=_winapi.CloseHandle):
113113
if self._handle is not None:
114-
CloseHandle(self._handle)
114+
handle = self._handle
115115
self._handle = None
116+
CloseHandle(handle)
116117

117118
def __del__(self, _warn=warnings.warn):
118119
if self._handle is not None:

PythonLib/full/configparser.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,15 @@ def __init__(self, source, *args):
315315

316316
def append(self, lineno, line):
317317
self.errors.append((lineno, line))
318-
self.message += '\n\t[line %2d]: %s' % (lineno, repr(line))
318+
self.message += f'\n\t[line {lineno:2d}]: {line!r}'
319319

320320
def combine(self, others):
321+
messages = [self.message]
321322
for other in others:
322-
for error in other.errors:
323-
self.append(*error)
323+
for lineno, line in other.errors:
324+
self.errors.append((lineno, line))
325+
messages.append(f'\n\t[line {lineno:2d}]: {line!r}')
326+
self.message = "".join(messages)
324327
return self
325328

326329
@staticmethod
@@ -613,15 +616,19 @@ class RawConfigParser(MutableMapping):
613616
\] # ]
614617
"""
615618
_OPT_TMPL = r"""
616-
(?P<option>.*?) # very permissive!
619+
(?P<option> # very permissive!
620+
(?:(?!{delim})\S)* # non-delimiter non-whitespace
621+
(?:\s+(?:(?!{delim})\S)+)*) # optionally more words
617622
\s*(?P<vi>{delim})\s* # any number of space/tab,
618623
# followed by any of the
619624
# allowed delimiters,
620625
# followed by any space/tab
621626
(?P<value>.*)$ # everything up to eol
622627
"""
623628
_OPT_NV_TMPL = r"""
624-
(?P<option>.*?) # very permissive!
629+
(?P<option> # very permissive!
630+
(?:(?!{delim})\S)* # non-delimiter non-whitespace
631+
(?:\s+(?:(?!{delim})\S)+)*) # optionally more words
625632
\s*(?: # any number of space/tab,
626633
(?P<vi>{delim})\s* # optionally followed by
627634
# any of the allowed

PythonLib/full/dataclasses.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -725,25 +725,25 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,
725725
annotation_fields=annotation_fields)
726726

727727

728-
def _frozen_get_del_attr(cls, fields, func_builder):
729-
locals = {'cls': cls,
728+
def _frozen_set_del_attr(cls, fields, func_builder):
729+
locals = {'__class__': cls,
730730
'FrozenInstanceError': FrozenInstanceError}
731-
condition = 'type(self) is cls'
731+
condition = 'type(self) is __class__'
732732
if fields:
733733
condition += ' or name in {' + ', '.join(repr(f.name) for f in fields) + '}'
734734

735735
func_builder.add_fn('__setattr__',
736736
('self', 'name', 'value'),
737737
(f' if {condition}:',
738738
' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
739-
f' super(cls, self).__setattr__(name, value)'),
739+
f' super(__class__, self).__setattr__(name, value)'),
740740
locals=locals,
741741
overwrite_error=True)
742742
func_builder.add_fn('__delattr__',
743743
('self', 'name'),
744744
(f' if {condition}:',
745745
' raise FrozenInstanceError(f"cannot delete field {name!r}")',
746-
f' super(cls, self).__delattr__(name)'),
746+
f' super(__class__, self).__delattr__(name)'),
747747
locals=locals,
748748
overwrite_error=True)
749749

@@ -1199,7 +1199,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
11991199
overwrite_error='Consider using functools.total_ordering')
12001200

12011201
if frozen:
1202-
_frozen_get_del_attr(cls, field_list, func_builder)
1202+
_frozen_set_del_attr(cls, field_list, func_builder)
12031203

12041204
# Decide if/how we're going to create a hash function.
12051205
hash_action = _hash_action[bool(unsafe_hash),
@@ -1292,10 +1292,18 @@ def _update_func_cell_for__class__(f, oldcls, newcls):
12921292
# This function doesn't reference __class__, so nothing to do.
12931293
return False
12941294
# Fix the cell to point to the new class, if it's already pointing
1295-
# at the old class. I'm not convinced that the "is oldcls" test
1296-
# is needed, but other than performance can't hurt.
1295+
# at the old class.
12971296
closure = f.__closure__[idx]
1298-
if closure.cell_contents is oldcls:
1297+
1298+
try:
1299+
contents = closure.cell_contents
1300+
except ValueError:
1301+
# Cell is empty
1302+
return False
1303+
1304+
# This check makes it so we avoid updating an incorrect cell if the
1305+
# class body contains a function that was defined in a different class.
1306+
if contents is oldcls:
12991307
closure.cell_contents = newcls
13001308
return True
13011309
return False

PythonLib/full/email/_header_value_parser.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -639,11 +639,11 @@ def local_part(self):
639639
for tok in self[0] + [DOT]:
640640
if tok.token_type == 'cfws':
641641
continue
642-
if (last_is_tl and tok.token_type == 'dot' and
642+
if (last_is_tl and tok.token_type == 'dot' and last and
643643
last[-1].token_type == 'cfws'):
644644
res[-1] = TokenList(last[:-1])
645645
is_tl = isinstance(tok, TokenList)
646-
if (is_tl and last.token_type == 'dot' and
646+
if (is_tl and last.token_type == 'dot' and tok and
647647
tok[0].token_type == 'cfws'):
648648
res.append(TokenList(tok[1:]))
649649
else:
@@ -1245,8 +1245,7 @@ def get_bare_quoted_string(value):
12451245
bare_quoted_string = BareQuotedString()
12461246
value = value[1:]
12471247
if value and value[0] == '"':
1248-
token, value = get_qcontent(value)
1249-
bare_quoted_string.append(token)
1248+
return bare_quoted_string, value[1:]
12501249
while value and value[0] != '"':
12511250
if value[0] in WSP:
12521251
token, value = get_fws(value)
@@ -2059,12 +2058,10 @@ def get_address_list(value):
20592058
address_list.defects.append(errors.InvalidHeaderDefect(
20602059
"invalid address in address-list"))
20612060
if value and value[0] != ',':
2062-
# Crap after address; treat it as an invalid mailbox.
2063-
# The mailbox info will still be available.
2064-
mailbox = address_list[-1][0]
2065-
mailbox.token_type = 'invalid-mailbox'
2061+
# Crap after address: add it to the address list
2062+
# as an invalid mailbox
20662063
token, value = get_invalid_mailbox(value, ',')
2067-
mailbox.extend(token)
2064+
address_list.append(Address([token]))
20682065
address_list.defects.append(errors.InvalidHeaderDefect(
20692066
"invalid address in address-list"))
20702067
if value: # Must be a , at this point.

0 commit comments

Comments
 (0)