Skip to content

Commit 29ef895

Browse files
authored
Merge branch 'main' into frameobj
2 parents 734e8d2 + adebb68 commit 29ef895

32 files changed

Lines changed: 1304 additions & 1008 deletions

Doc/library/asyncio-task.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,9 @@ Waiting primitives
924924
Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the
925925
futures when a timeout occurs.
926926

927+
If ``wait()`` is cancelled, the futures in *aws* are not cancelled
928+
and continue to run.
929+
927930
.. versionchanged:: 3.10
928931
Removed the *loop* parameter.
929932

@@ -981,6 +984,10 @@ Waiting primitives
981984
are done. This is raised by the ``async for`` loop during asynchronous
982985
iteration or by the coroutines yielded during plain iteration.
983986

987+
``as_completed()`` does not cancel the tasks running the supplied
988+
awaitables: if a timeout occurs or the iteration is cancelled, the
989+
remaining tasks continue to run.
990+
984991
.. versionchanged:: 3.10
985992
Removed the *loop* parameter.
986993

Doc/library/urllib.request.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,8 @@ some point in the future.
14861486
.. function:: urlcleanup()
14871487

14881488
Cleans up temporary files that may have been left behind by previous
1489-
calls to :func:`urlretrieve`.
1489+
calls to :func:`urlretrieve`. It also resets the default global opener
1490+
installed by :func:`install_opener`.
14901491

14911492

14921493
:mod:`!urllib.request` Restrictions

Doc/tutorial/introduction.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,10 +532,13 @@ This example introduces several new features.
532532
and ``!=`` (not equal to).
533533

534534
* The *body* of the loop is *indented*: indentation is Python's way of grouping
535-
statements. At the interactive prompt, you have to type a tab or space(s) for
536-
each indented line. In practice you will prepare more complicated input
537-
for Python with a text editor; all decent text editors have an auto-indent
538-
facility. When a compound statement is entered interactively, it must be
535+
statements. At the interactive prompt, the default REPL automatically
536+
indents continuation lines after compound statement headers like ``if`` or
537+
``while``. In the basic REPL (invoked with :envvar:`PYTHON_BASIC_REPL`)
538+
or in older Python versions, you have to type a tab or space(s) for each
539+
indented line manually. In practice you will prepare more complicated
540+
input for Python with a text editor; all decent text editors have an
541+
auto-indent facility. When a compound statement is entered interactively, it must be
539542
followed by a blank line to indicate completion (since the parser cannot
540543
guess when you have typed the last line). Note that each line within a basic
541544
block must be indented by the same amount.

Lib/_pyrepl/base_eventqueue.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,6 @@ def empty(self) -> bool:
5454
"""
5555
return not self.events
5656

57-
def flush_buf(self) -> bytearray:
58-
"""
59-
Flushes the buffer and returns its contents.
60-
"""
61-
old = self.buf
62-
self.buf = bytearray()
63-
return old
64-
6557
def insert(self, event: Event) -> None:
6658
"""
6759
Inserts an event into the queue.
@@ -87,7 +79,7 @@ def push(self, char: int | bytes) -> None:
8779
if isinstance(k, dict):
8880
self.keymap = k
8981
else:
90-
self.insert(Event('key', k, bytes(self.flush_buf())))
82+
self.insert(Event('key', k, self.buf.take_bytes())) # type: ignore[attr-defined]
9183
self.keymap = self.compiled_keymap
9284

9385
elif self.buf and self.buf[0] == 27: # escape
@@ -97,14 +89,14 @@ def push(self, char: int | bytes) -> None:
9789
trace('unrecognized escape sequence, propagating...')
9890
self.keymap = self.compiled_keymap
9991
self.insert(Event('key', '\033', b'\033'))
100-
for _c in self.flush_buf()[1:]:
92+
for _c in self.buf.take_bytes()[1:]: # type: ignore[attr-defined]
10193
self.push(_c)
10294

10395
else:
10496
try:
105-
decoded = bytes(self.buf).decode(self.encoding)
97+
decoded = self.buf.decode(self.encoding)
10698
except UnicodeError:
10799
return
108100
else:
109-
self.insert(Event('key', decoded, bytes(self.flush_buf())))
101+
self.insert(Event('key', decoded, self.buf.take_bytes())) # type: ignore[attr-defined]
110102
self.keymap = self.compiled_keymap

Lib/asyncio/selector_events.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ def _accept_connection(
206206
protocol_factory, sock, sslcontext, server,
207207
backlog, ssl_handshake_timeout,
208208
ssl_shutdown_timeout, context)
209+
return
209210
else:
210211
raise # The event loop will catch, log and ignore it.
211212
else:

Lib/compression/zstd/_zstdfile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def peek(self, size=-1):
246246
return self._buffer.peek(size)
247247

248248
def __next__(self):
249+
self._check_can_read()
249250
if ret := self._buffer.readline():
250251
return ret
251252
raise StopIteration

Lib/profiling/sampling/live_collector/collector.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ def build_stats_list(self):
702702
def reset_stats(self):
703703
"""Reset all collected statistics."""
704704
self.result.clear()
705+
self.opcode_stats.clear()
705706
self.per_thread_data.clear()
706707
self.thread_ids.clear()
707708
self.view_mode = "ALL"

Lib/test/test_asyncio/test_selector_events.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for selector_events.py"""
22

33
import collections
4+
import errno
45
import selectors
56
import socket
67
import sys
@@ -402,6 +403,24 @@ def mock_sock_accept():
402403
self.loop.run_until_complete(asyncio.sleep(0))
403404
self.assertEqual(sock.accept.call_count, backlog + 1)
404405

406+
def test_accept_connection_reschedules_once_on_resource_error(self):
407+
# When accept() fails with a resource error (EMFILE), _accept_connection
408+
# re-runs the error branch backlog+1 times, logging and rescheduling
409+
# _start_serving once per iteration. With early return after first
410+
# exception we avoid this behaviour
411+
sock = mock.Mock()
412+
sock.accept.side_effect = OSError(errno.EMFILE, 'too many open files')
413+
414+
self.loop.call_exception_handler = mock.Mock()
415+
self.loop._remove_reader = mock.Mock()
416+
self.loop.call_later = mock.Mock()
417+
418+
self.loop._accept_connection(mock.Mock(), sock, backlog=100)
419+
420+
self.assertEqual(sock.accept.call_count, 1)
421+
self.assertEqual(self.loop.call_exception_handler.call_count, 1)
422+
self.assertEqual(self.loop.call_later.call_count, 1)
423+
405424
class SelectorTransportTests(test_utils.TestCase):
406425

407426
def setUp(self):

Lib/test/test_capi/test_run.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,15 @@ def check_run_interactive(self, run, encode_filename, use_loop=False):
310310
# supported". In this case, run the test without redirecting
311311
# stderr to a temporary file.
312312
self._check_run_interactive(run, encode_filename, use_loop)
313-
else:
314-
with tempfile.TemporaryFile() as tmp:
315-
try:
316-
os.dup2(tmp.fileno(), STDERR_FD)
317-
self._check_run_interactive(run, encode_filename, use_loop)
318-
finally:
319-
os.dup2(stderr_copy, STDERR_FD)
313+
return
314+
315+
with tempfile.TemporaryFile() as tmp:
316+
try:
317+
os.dup2(tmp.fileno(), STDERR_FD)
318+
self._check_run_interactive(run, encode_filename, use_loop)
319+
finally:
320+
os.dup2(stderr_copy, STDERR_FD)
321+
os.close(stderr_copy)
320322

321323
def test_run_interactiveone(self):
322324
# Test PyRun_InteractiveOne()

Lib/test/test_fstring.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,16 @@ def test_double_braces(self):
709709
["f'{ {{}} }'", # dict in a set
710710
])
711711

712+
def test_double_brace_ast_location_covers_both_source_braces(self):
713+
value = ast.parse('f"a{{"').body[0].value.values[0]
714+
self.assertIsInstance(value, ast.Constant)
715+
self.assertEqual(value.value, "a{")
716+
self.assertEqual(
717+
(value.lineno, value.col_offset, value.end_lineno,
718+
value.end_col_offset),
719+
(1, 2, 1, 5),
720+
)
721+
712722
def test_compile_time_concat(self):
713723
x = 'def'
714724
self.assertEqual('abc' f'## {x}ghi', 'abc## defghi')

0 commit comments

Comments
 (0)