Skip to content

Commit 7834406

Browse files
authored
Merge branch 'main' into small_int_immortal_v2
2 parents 9894866 + bad3cde commit 7834406

Some content is hidden

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

59 files changed

+247
-91
lines changed

Doc/library/asyncio-policy.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ for the current process:
4646

4747
If *policy* is set to ``None``, the default policy is restored.
4848

49+
.. deprecated:: next
50+
The :func:`set_event_loop_policy` function is deprecated and
51+
will be removed in Python 3.16.
52+
4953

5054
.. _asyncio-policy-objects:
5155

Doc/whatsnew/3.14.rst

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,96 @@ asyncio
780780
It now raises a :exc:`RuntimeError` if there is no current event loop.
781781
(Contributed by Kumar Aditya in :gh:`126353`.)
782782

783+
There's a few patterns that use :func:`asyncio.get_event_loop`, most
784+
of them can be replaced with :func:`asyncio.run`.
785+
786+
If you're running an async function, simply use :func:`asyncio.run`.
787+
788+
Before::
789+
790+
async def main():
791+
...
792+
793+
794+
loop = asyncio.get_event_loop()
795+
try:
796+
loop.run_until_complete(main())
797+
finally:
798+
loop.close()
799+
800+
After::
801+
802+
async def main():
803+
...
804+
805+
asyncio.run(main())
806+
807+
If you need to start something, e.g. a server listening on a socket
808+
and then run forever, use :func:`asyncio.run` and an
809+
:class:`asyncio.Event`.
810+
811+
Before::
812+
813+
def start_server(loop):
814+
...
815+
816+
loop = asyncio.get_event_loop()
817+
try:
818+
start_server(loop)
819+
loop.run_forever()
820+
finally:
821+
loop.close()
822+
823+
After::
824+
825+
def start_server(loop):
826+
...
827+
828+
async def main():
829+
start_server(asyncio.get_running_loop())
830+
await asyncio.Event().wait()
831+
832+
asyncio.run(main())
833+
834+
If you need to run something in an event loop, then run some blocking
835+
code around it, use :class:`asyncio.Runner`.
836+
837+
Before::
838+
839+
async def operation_one():
840+
...
841+
842+
def blocking_code():
843+
...
844+
845+
async def operation_two():
846+
...
847+
848+
loop = asyncio.get_event_loop()
849+
try:
850+
loop.run_until_complete(operation_one())
851+
blocking_code()
852+
loop.run_until_complete(operation_two())
853+
finally:
854+
loop.close()
855+
856+
After::
857+
858+
async def operation_one():
859+
...
860+
861+
def blocking_code():
862+
...
863+
864+
async def operation_two():
865+
...
866+
867+
with asyncio.Runner() as runner:
868+
runner.run(operation_one())
869+
blocking_code()
870+
runner.run(operation_two())
871+
872+
783873

784874
collections.abc
785875
---------------

Lib/asyncio/events.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
'AbstractEventLoopPolicy',
99
'AbstractEventLoop', 'AbstractServer',
1010
'Handle', 'TimerHandle',
11-
'get_event_loop_policy', 'set_event_loop_policy',
11+
'get_event_loop_policy',
12+
'_set_event_loop_policy',
13+
'set_event_loop_policy',
1214
'get_event_loop', 'set_event_loop', 'new_event_loop',
1315
'_set_running_loop', 'get_running_loop',
1416
'_get_running_loop',
@@ -21,6 +23,7 @@
2123
import subprocess
2224
import sys
2325
import threading
26+
import warnings
2427

2528
from . import format_helpers
2629

@@ -765,7 +768,7 @@ def get_event_loop_policy():
765768
return _event_loop_policy
766769

767770

768-
def set_event_loop_policy(policy):
771+
def _set_event_loop_policy(policy):
769772
"""Set the current event loop policy.
770773
771774
If policy is None, the default policy is restored."""
@@ -774,6 +777,9 @@ def set_event_loop_policy(policy):
774777
raise TypeError(f"policy must be an instance of AbstractEventLoopPolicy or None, not '{type(policy).__name__}'")
775778
_event_loop_policy = policy
776779

780+
def set_event_loop_policy(policy):
781+
warnings._deprecated('set_event_loop_policy', remove=(3,16))
782+
_set_event_loop_policy(policy)
777783

778784
def get_event_loop():
779785
"""Return an asyncio event loop.

Lib/idlelib/pyshell.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ def __init__(self, tkconsole):
424424
def spawn_subprocess(self):
425425
if self.subprocess_arglist is None:
426426
self.subprocess_arglist = self.build_subprocess_arglist()
427-
self.rpcsubproc = subprocess.Popen(self.subprocess_arglist)
427+
# gh-127060: Disable traceback colors
428+
env = dict(os.environ, TERM='dumb')
429+
self.rpcsubproc = subprocess.Popen(self.subprocess_arglist, env=env)
428430

429431
def build_subprocess_arglist(self):
430432
assert (self.port!=0), (

Lib/tempfile.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,19 @@ class _TemporaryFileCloser:
437437
cleanup_called = False
438438
close_called = False
439439

440-
def __init__(self, file, name, delete=True, delete_on_close=True):
440+
def __init__(
441+
self,
442+
file,
443+
name,
444+
delete=True,
445+
delete_on_close=True,
446+
warn_message="Implicitly cleaning up unknown file",
447+
):
441448
self.file = file
442449
self.name = name
443450
self.delete = delete
444451
self.delete_on_close = delete_on_close
452+
self.warn_message = warn_message
445453

446454
def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink):
447455
if not self.cleanup_called:
@@ -469,7 +477,10 @@ def close(self):
469477
self.cleanup()
470478

471479
def __del__(self):
480+
close_called = self.close_called
472481
self.cleanup()
482+
if not close_called:
483+
_warnings.warn(self.warn_message, ResourceWarning)
473484

474485

475486
class _TemporaryFileWrapper:
@@ -483,8 +494,17 @@ class _TemporaryFileWrapper:
483494
def __init__(self, file, name, delete=True, delete_on_close=True):
484495
self.file = file
485496
self.name = name
486-
self._closer = _TemporaryFileCloser(file, name, delete,
487-
delete_on_close)
497+
self._closer = _TemporaryFileCloser(
498+
file,
499+
name,
500+
delete,
501+
delete_on_close,
502+
warn_message=f"Implicitly cleaning up {self!r}",
503+
)
504+
505+
def __repr__(self):
506+
file = self.__dict__['file']
507+
return f"<{type(self).__name__} {file=}>"
488508

489509
def __getattr__(self, name):
490510
# Attribute lookups are delegated to the underlying file

Lib/test/libregrtest/save_env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def get_asyncio_events__event_loop_policy(self):
9797
return support.maybe_get_event_loop_policy()
9898
def restore_asyncio_events__event_loop_policy(self, policy):
9999
asyncio = self.get_module('asyncio')
100-
asyncio.set_event_loop_policy(policy)
100+
asyncio._set_event_loop_policy(policy)
101101

102102
def get_sys_argv(self):
103103
return id(sys.argv), sys.argv, sys.argv[:]

Lib/test/test_asyncgen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ def setUp(self):
629629
def tearDown(self):
630630
self.loop.close()
631631
self.loop = None
632-
asyncio.set_event_loop_policy(None)
632+
asyncio._set_event_loop_policy(None)
633633

634634
def check_async_iterator_anext(self, ait_class):
635635
with self.subTest(anext="pure-Python"):

Lib/test/test_asyncio/test_base_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626

2727
def tearDownModule():
28-
asyncio.set_event_loop_policy(None)
28+
asyncio._set_event_loop_policy(None)
2929

3030

3131
def mock_socket_module():

Lib/test/test_asyncio/test_buffered_proto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
def tearDownModule():
8-
asyncio.set_event_loop_policy(None)
8+
asyncio._set_event_loop_policy(None)
99

1010

1111
class ReceiveStuffProto(asyncio.BufferedProtocol):

Lib/test/test_asyncio/test_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55

66
def tearDownModule():
7-
asyncio.set_event_loop_policy(None)
7+
asyncio._set_event_loop_policy(None)
88

99

1010
@unittest.skipUnless(decimal.HAVE_CONTEXTVAR, "decimal is built with a thread-local context")

0 commit comments

Comments
 (0)