Skip to content

Commit f9dec43

Browse files
committed
Merge branch 'master' into better-lit-errors/149277
2 parents 80b5134 + 23180c5 commit f9dec43

78 files changed

Lines changed: 1513 additions & 406 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.

Doc/library/argparse.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,9 @@ how the command-line arguments should be handled. The supplied actions are:
835835
>>> parser.parse_args(['-vvv'])
836836
Namespace(verbose=3)
837837

838-
Note, the *default* will be ``None`` unless explicitly set to *0*.
838+
Unless explicitly set, the *default* will be ``None``. If the default
839+
value is a non-zero number, the count starts from that number rather
840+
than from zero.
839841

840842
* ``'help'`` - This prints a complete help message for all the options in the
841843
current parser and then exits. By default a help action is automatically

Include/internal/pycore_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ enum _PyCompile_FBlockType {
110110
COMPILE_FBLOCK_EXCEPTION_HANDLER,
111111
COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER,
112112
COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR,
113+
COMPILE_FBLOCK_INLINED_COMPREHENSION,
113114
COMPILE_FBLOCK_STOP_ITERATION,
114115
};
115116

Lib/_pydatetime.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,10 +1570,11 @@ def _cmp(self, other, allow_mixed=False):
15701570
return 2 # arbitrary non-zero value
15711571
else:
15721572
raise TypeError("cannot compare naive and aware times")
1573-
myhhmm = self._hour * 60 + self._minute - myoff//timedelta(minutes=1)
1574-
othhmm = other._hour * 60 + other._minute - otoff//timedelta(minutes=1)
1575-
return _cmp((myhhmm, self._second, self._microsecond),
1576-
(othhmm, other._second, other._microsecond))
1573+
myus = (((self._hour * 60 + self._minute) * 60 + self._second) * 1000000
1574+
+ self._microsecond - myoff._to_microseconds())
1575+
otus = (((other._hour * 60 + other._minute) * 60 + other._second) * 1000000
1576+
+ other._microsecond - otoff._to_microseconds())
1577+
return _cmp(myus, otus)
15771578

15781579
def __hash__(self):
15791580
"""Hash."""
@@ -1583,17 +1584,13 @@ def __hash__(self):
15831584
else:
15841585
t = self
15851586
tzoff = t.utcoffset()
1586-
if not tzoff: # zero or None
1587+
if tzoff is None:
15871588
self._hashcode = hash(t._getstate()[0])
15881589
else:
1589-
h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff,
1590-
timedelta(hours=1))
1591-
assert not m % timedelta(minutes=1), "whole minute"
1592-
m //= timedelta(minutes=1)
1593-
if 0 <= h < 24:
1594-
self._hashcode = hash(time(h, m, self.second, self.microsecond))
1595-
else:
1596-
self._hashcode = hash((h, m, self.second, self.microsecond))
1590+
self._hashcode = hash(timedelta(hours=t.hour,
1591+
minutes=t.minute,
1592+
seconds=t.second,
1593+
microseconds=t.microsecond) - tzoff)
15971594
return self._hashcode
15981595

15991596
# Conversion to string

Lib/asyncio/base_events.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,12 @@ async def create_datagram_endpoint(self, protocol_factory,
14971497
else:
14981498
raise exceptions[0]
14991499

1500-
protocol = protocol_factory()
1500+
try:
1501+
protocol = protocol_factory()
1502+
except:
1503+
# gh-156400: no transport owns the socket yet, so close it.
1504+
sock.close()
1505+
raise
15011506
waiter = self.create_future()
15021507
transport = self._make_datagram_transport(
15031508
sock, protocol, r_addr, waiter)
@@ -1714,7 +1719,12 @@ async def connect_accepted_socket(
17141719
return transport, protocol
17151720

17161721
async def connect_read_pipe(self, protocol_factory, pipe):
1717-
protocol = protocol_factory()
1722+
try:
1723+
protocol = protocol_factory()
1724+
except:
1725+
# gh-156400: no transport owns the pipe yet, so close it.
1726+
pipe.close()
1727+
raise
17181728
waiter = self.create_future()
17191729
transport = self._make_read_pipe_transport(pipe, protocol, waiter)
17201730

@@ -1730,7 +1740,12 @@ async def connect_read_pipe(self, protocol_factory, pipe):
17301740
return transport, protocol
17311741

17321742
async def connect_write_pipe(self, protocol_factory, pipe):
1733-
protocol = protocol_factory()
1743+
try:
1744+
protocol = protocol_factory()
1745+
except:
1746+
# gh-156400: no transport owns the pipe yet, so close it.
1747+
pipe.close()
1748+
raise
17341749
waiter = self.create_future()
17351750
transport = self._make_write_pipe_transport(pipe, protocol, waiter)
17361751

Lib/asyncio/graph.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ def capture_call_graph(
155155
f = sys._getframe(depth) if limit != 0 else None
156156
try:
157157
while f is not None:
158-
is_async = f.f_generator is not None
158+
# gh-156988: sync gen should not clear the call chain
159+
is_async = isinstance(
160+
f.f_generator, (types.CoroutineType, types.AsyncGeneratorType))
159161
call_stack.append(FrameCallGraphEntry(f))
160162

161163
if is_async:

Lib/asyncio/proactor_events.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,15 @@ def _loop_reading(self, fut=None):
571571
else:
572572
self._read_fut = self._loop._proactor.recvfrom(self._sock,
573573
self.max_size)
574+
except ConnectionResetError as exc:
575+
# WSARecvFrom() reports a stale ICMP port unreachable
576+
# notification as a synchronous ConnectionResetError when the
577+
# same socket was used to send to an address that is not
578+
# listening. This is transient, so reschedule the read loop
579+
# instead of leaving it dead.
580+
self._protocol.error_received(exc)
581+
if not self._closing:
582+
self._loop.call_soon(self._loop_reading)
574583
except OSError as exc:
575584
self._protocol.error_received(exc)
576585
except exceptions.CancelledError:
@@ -757,8 +766,8 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
757766
async def _sendfile_native(self, transp, file, offset, count):
758767
resume_reading = transp.is_reading()
759768
transp.pause_reading()
760-
await transp._make_empty_waiter()
761769
try:
770+
await transp._make_empty_waiter()
762771
return await self.sock_sendfile(transp._sock, file, offset, count,
763772
fallback=False)
764773
finally:

Lib/asyncio/selector_events.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,8 +739,8 @@ async def _sendfile_native(self, transp, file, offset, count):
739739
del self._transports[transp._sock_fd]
740740
resume_reading = transp.is_reading()
741741
transp.pause_reading()
742-
await transp._make_empty_waiter()
743742
try:
743+
await transp._make_empty_waiter()
744744
return await self.sock_sendfile(transp._sock, file, offset, count,
745745
fallback=False)
746746
finally:
@@ -1127,7 +1127,9 @@ def _write_sendmsg(self):
11271127
self._loop._remove_writer(self._sock_fd)
11281128
if self._empty_waiter is not None:
11291129
self._empty_waiter.set_result(None)
1130-
if self._closing:
1130+
# gh-156512: don't let _call_connection_lost be called twice
1131+
if self._closing and not self._conn_lost:
1132+
self._conn_lost += 1
11311133
self._call_connection_lost(None)
11321134
elif self._eof:
11331135
self._sock.shutdown(socket.SHUT_WR)
@@ -1173,7 +1175,9 @@ def _write_send(self):
11731175
self._loop._remove_writer(self._sock_fd)
11741176
if self._empty_waiter is not None:
11751177
self._empty_waiter.set_result(None)
1176-
if self._closing:
1178+
# gh-156512: don't let _call_connection_lost be called twice
1179+
if self._closing and not self._conn_lost:
1180+
self._conn_lost += 1
11771181
self._call_connection_lost(None)
11781182
elif self._eof:
11791183
self._sock.shutdown(socket.SHUT_WR)

Lib/difflib.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'unified_diff', 'diff_bytes', 'HtmlDiff', 'Match']
3232

3333
from heapq import nlargest as _nlargest
34-
from collections import namedtuple as _namedtuple
34+
from collections import deque as _deque, namedtuple as _namedtuple
3535
from types import GenericAlias
3636
lazy from _colorize import can_colorize, get_theme
3737

@@ -1571,7 +1571,7 @@ def _line_pair_iterator():
15711571
is defined) does not need to be of module scope.
15721572
"""
15731573
line_iterator = _line_iterator()
1574-
fromlines,tolines=[],[]
1574+
fromlines, tolines = _deque(), _deque()
15751575
while True:
15761576
# Collecting lines of text until we have a from/to pair
15771577
while (len(fromlines)==0 or len(tolines)==0):
@@ -1584,8 +1584,8 @@ def _line_pair_iterator():
15841584
if to_line is not None:
15851585
tolines.append((to_line,found_diff))
15861586
# Once we have a pair, remove them from the collection and yield it
1587-
from_line, fromDiff = fromlines.pop(0)
1588-
to_line, to_diff = tolines.pop(0)
1587+
from_line, fromDiff = fromlines.popleft()
1588+
to_line, to_diff = tolines.popleft()
15891589
yield (from_line,to_line,fromDiff or to_diff)
15901590

15911591
# Handle case where user does not want context differencing, just yield

Lib/idlelib/editor.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
from idlelib import query
2727
from idlelib import replace
2828
from idlelib import search
29-
from idlelib.tree import wheel_event
30-
from idlelib.util import py_extensions
29+
from idlelib.util import bind_wheel, py_extensions, wheel_event
3130
from idlelib import window
3231
from idlelib.help import _get_dochome
3332

@@ -115,10 +114,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
115114
# Elsewhere, use right-click for popup menus.
116115
text.bind("<3>",self.right_menu_event)
117116

118-
text.bind('<MouseWheel>', wheel_event)
119-
if text._windowingsystem == 'x11':
120-
text.bind('<Button-4>', wheel_event)
121-
text.bind('<Button-5>', wheel_event)
117+
bind_wheel(text, wheel_event)
122118
text.bind('<Configure>', self.handle_winconfig)
123119
text.bind("<<cut>>", self.cut)
124120
text.bind("<<copy>>", self.copy)

Lib/idlelib/idle_test/test_configdialog.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ def test_fontlist_key(self):
150150
font = d.fontlist.get('active')
151151

152152
# Test Down key.
153-
fontlist.focus_force()
154153
fontlist.update()
154+
fontlist.focus_force()
155155
fontlist.event_generate('<Key-Down>')
156156
fontlist.event_generate('<KeyRelease-Down>')
157157

@@ -160,8 +160,8 @@ def test_fontlist_key(self):
160160
self.assertIn(d.font_name.get(), down_font.lower())
161161

162162
# Test Up key.
163-
fontlist.focus_force()
164163
fontlist.update()
164+
fontlist.focus_force()
165165
fontlist.event_generate('<Key-Up>')
166166
fontlist.event_generate('<KeyRelease-Up>')
167167

0 commit comments

Comments
 (0)