Skip to content

Commit ce2168b

Browse files
committed
Merge branch 'fix-proactor-error-hang' into fix-proactor-close-flush
# Conflicts: # Lib/asyncio/proactor_events.py
2 parents 4822ab7 + 9fcd45c commit ce2168b

69 files changed

Lines changed: 1325 additions & 373 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/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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,8 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
797797
async def _sendfile_native(self, transp, file, offset, count):
798798
resume_reading = transp.is_reading()
799799
transp.pause_reading()
800-
await transp._make_empty_waiter()
801800
try:
801+
await transp._make_empty_waiter()
802802
return await self.sock_sendfile(transp._sock, file, offset, count,
803803
fallback=False)
804804
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

Lib/idlelib/idle_test/test_sidebar.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from idlelib.percolator import Percolator
1515
import idlelib.pyshell
1616
from idlelib.pyshell import PyShell, PyShellFileList
17-
from idlelib.util import fix_scaling, fix_word_breaks, fix_x11_paste
17+
from idlelib.util import (fix_scaling, fix_word_breaks, fix_x11_paste,
18+
x11_buttons)
1819
import idlelib.sidebar
1920
from idlelib.sidebar import get_end_linenumber, get_lineno
2021

@@ -689,23 +690,21 @@ def test_mousewheel(self):
689690
last_lineno = get_end_linenumber(text)
690691
self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0')))
691692

692-
# Simulate a mouse wheel notch. Tk 8.7 replaced the X11
693-
# <Button-4>/<Button-5> wheel events with <MouseWheel> (whose delta is
694-
# platform-dependent); older Tk on X11 still uses the button events.
695-
x11_buttons = (sidebar.canvas._windowingsystem == 'x11'
696-
and tk.TkVersion < 8.7)
693+
# Simulate a mouse wheel notch with the events that Tk sends for
694+
# one; the delta of a <MouseWheel> event is platform-dependent.
695+
buttons = x11_buttons(sidebar.canvas)
697696
delta = 1 if sidebar.canvas._windowingsystem == 'aqua' else 120
698697

699698
# Scroll up.
700-
if x11_buttons:
699+
if buttons:
701700
sidebar.canvas.event_generate('<Button-4>', x=0, y=0)
702701
else:
703702
sidebar.canvas.event_generate('<MouseWheel>', x=0, y=0, delta=delta)
704703
yield
705704
self.assertIsNone(text.dlineinfo(text.index(f'{last_lineno}.0')))
706705

707706
# Scroll back down.
708-
if x11_buttons:
707+
if buttons:
709708
sidebar.canvas.event_generate('<Button-5>', x=0, y=0)
710709
else:
711710
sidebar.canvas.event_generate('<MouseWheel>', x=0, y=0, delta=-delta)

0 commit comments

Comments
 (0)