Skip to content

Commit a775996

Browse files
Drop Python 3.6.
Use `asyncio.get_running_loop()` and `asyncio.run()`. Stop using `asyncio.get_event_loop()` and `asyncio.set_event_loop()`.
1 parent 7776bf9 commit a775996

File tree

22 files changed

+93
-129
lines changed

22 files changed

+93
-129
lines changed

examples/ssh/asyncssh-server.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"""
55
import asyncio
66
import logging
7+
from asyncio import run
78

89
import asyncssh
910
from pygments.lexers.html import HtmlLexer
1011

1112
from prompt_toolkit.completion import WordCompleter
1213
from prompt_toolkit.contrib.ssh import PromptToolkitSSHServer, PromptToolkitSSHSession
13-
from prompt_toolkit.eventloop import get_event_loop
1414
from prompt_toolkit.lexers import PygmentsLexer
1515
from prompt_toolkit.shortcuts import ProgressBar, print_formatted_text
1616
from prompt_toolkit.shortcuts.dialogs import input_dialog, yes_no_dialog
@@ -101,22 +101,21 @@ async def interact(ssh_session: PromptToolkitSSHSession) -> None:
101101
await input_dialog("Input dialog", "Running over asyncssh").run_async()
102102

103103

104-
def main(port=8222):
104+
async def main(port=8222):
105105
# Set up logging.
106106
logging.basicConfig()
107107
logging.getLogger().setLevel(logging.DEBUG)
108108

109-
loop = get_event_loop()
110-
loop.run_until_complete(
111-
asyncssh.create_server(
112-
lambda: PromptToolkitSSHServer(interact),
113-
"",
114-
port,
115-
server_host_keys=["/etc/ssh/ssh_host_ecdsa_key"],
116-
)
109+
await asyncssh.create_server(
110+
lambda: PromptToolkitSSHServer(interact),
111+
"",
112+
port,
113+
server_host_keys=["/etc/ssh/ssh_host_ecdsa_key"],
117114
)
118-
loop.run_forever()
115+
116+
# Run forever.
117+
await asyncio.Future()
119118

120119

121120
if __name__ == "__main__":
122-
main()
121+
asyncio.run(main())

examples/telnet/chat-app.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"""
77
import logging
88
import random
9+
from asyncio import Future, run
910

1011
from prompt_toolkit.contrib.telnet.server import TelnetServer
11-
from prompt_toolkit.eventloop import get_event_loop
1212
from prompt_toolkit.formatted_text import HTML
1313
from prompt_toolkit.shortcuts import PromptSession, clear
1414

@@ -91,11 +91,13 @@ def _send_to_everyone(sender_connection, name, message, color):
9191
)
9292

9393

94-
def main():
94+
async def main():
9595
server = TelnetServer(interact=interact, port=2323)
9696
server.start()
97-
get_event_loop().run_forever()
97+
98+
# Run forever.
99+
await Future()
98100

99101

100102
if __name__ == "__main__":
101-
main()
103+
run(main())

examples/telnet/dialog.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
Example of a telnet application that displays a dialog window.
44
"""
55
import logging
6+
from asyncio import Future, run
67

78
from prompt_toolkit.contrib.telnet.server import TelnetServer
8-
from prompt_toolkit.eventloop import get_event_loop
99
from prompt_toolkit.shortcuts.dialogs import yes_no_dialog
1010

1111
# Set up logging
@@ -22,11 +22,13 @@ async def interact(connection):
2222
connection.send("Bye.\n")
2323

2424

25-
def main():
25+
async def main():
2626
server = TelnetServer(interact=interact, port=2323)
2727
server.start()
28-
get_event_loop().run_forever()
28+
29+
# Run forever.
30+
await Future()
2931

3032

3133
if __name__ == "__main__":
32-
main()
34+
run(main())

examples/telnet/hello-world.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
That is probably the preferred way if you only need Python 3 support.
88
"""
99
import logging
10+
from asyncio import Future, run
1011

1112
from prompt_toolkit.contrib.telnet.server import TelnetServer
12-
from prompt_toolkit.eventloop import get_event_loop
1313
from prompt_toolkit.shortcuts import PromptSession, clear
1414

1515
# Set up logging
@@ -30,11 +30,13 @@ async def interact(connection):
3030
connection.send("Bye.\n")
3131

3232

33-
def main():
33+
async def main():
3434
server = TelnetServer(interact=interact, port=2323)
3535
server.start()
36-
get_event_loop().run_forever()
36+
37+
# Run forever.
38+
await Future()
3739

3840

3941
if __name__ == "__main__":
40-
main()
42+
run(main())

examples/telnet/toolbar.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
in the prompt.
55
"""
66
import logging
7+
from asyncio import Future, run
78

89
from prompt_toolkit.completion import WordCompleter
910
from prompt_toolkit.contrib.telnet.server import TelnetServer
10-
from prompt_toolkit.eventloop import get_event_loop
1111
from prompt_toolkit.shortcuts import PromptSession
1212

1313
# Set up logging
@@ -35,11 +35,13 @@ def get_toolbar():
3535
connection.send("Bye.\n")
3636

3737

38-
def main():
38+
async def main():
3939
server = TelnetServer(interact=interact, port=2323)
4040
server.start()
41-
get_event_loop().run_forever()
41+
42+
# Run forever.
43+
await Future()
4244

4345

4446
if __name__ == "__main__":
45-
main()
47+
run(main())

setup.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,16 @@ def get_version(package):
3030
package_dir={"": "src"},
3131
package_data={"prompt_toolkit": ["py.typed"]},
3232
install_requires=["wcwidth"],
33-
# We require Python 3.6.2 for three reasons:
34-
# - Syntax for variable annotations - PEP 526.
35-
# - Asynchronous generators - PEP 525.
36-
# - New type annotations in 3.6.2 (i.e. NoReturn)
37-
# Also, 3.6.0 doesn't have `typing.AsyncGenerator` yet. 3.6.1 does.
38-
# Python 3.7 is suggested, because:
33+
# We require Python 3.7, because we need:
3934
# - Context variables - PEP 567
40-
# (The current application is derived from a context variable.)
41-
# There is no intension to support Python 3.5, because prompt_toolkit 2.0
42-
# does run fine on any older Python version starting from Python 2.6, and
43-
# it is possible to write code that runs both against prompt_toolkit
44-
# version 2 and 3.
45-
python_requires=">=3.6.2",
35+
# - `asyncio.run()`
36+
python_requires=">=3.7.0",
4637
classifiers=[
4738
"Development Status :: 5 - Production/Stable",
4839
"Intended Audience :: Developers",
4940
"License :: OSI Approved :: BSD License",
5041
"Operating System :: OS Independent",
5142
"Programming Language :: Python :: 3",
52-
"Programming Language :: Python :: 3.6",
5343
"Programming Language :: Python :: 3.7",
5444
"Programming Language :: Python :: 3.8",
5545
"Programming Language :: Python :: 3.9",

src/prompt_toolkit/application/application.py

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
Future,
1111
Task,
1212
ensure_future,
13-
new_event_loop,
14-
set_event_loop,
13+
get_running_loop,
1514
sleep,
1615
)
1716
from contextlib import ExitStack, contextmanager
@@ -49,7 +48,7 @@
4948
get_traceback_from_context,
5049
run_in_executor_with_context,
5150
)
52-
from prompt_toolkit.eventloop.utils import call_soon_threadsafe, get_event_loop
51+
from prompt_toolkit.eventloop.utils import call_soon_threadsafe
5352
from prompt_toolkit.filters import Condition, Filter, FilterOrBool, to_filter
5453
from prompt_toolkit.formatted_text import AnyFormattedText
5554
from prompt_toolkit.input.base import Input
@@ -458,7 +457,7 @@ def invalidate(self) -> None:
458457
"""
459458
if not self._is_running:
460459
# Don't schedule a redraw if we're not running.
461-
# Otherwise, `get_event_loop()` in `call_soon_threadsafe` can fail.
460+
# Otherwise, `get_running_loop()` in `call_soon_threadsafe` can fail.
462461
# See: https://github.com/dbcli/mycli/issues/797
463462
return
464463

@@ -787,7 +786,7 @@ def flush_input() -> None:
787786

788787
@contextmanager
789788
def get_loop() -> Iterator[AbstractEventLoop]:
790-
loop = get_event_loop()
789+
loop = get_running_loop()
791790
self.loop = loop
792791

793792
try:
@@ -941,14 +940,6 @@ def run_in_thread() -> None:
941940
)
942941
except BaseException as e:
943942
exception = e
944-
finally:
945-
# Make sure to close the event loop in this thread. Running
946-
# the application creates a new loop (because we're in
947-
# another thread), but it doesn't get closed automatically
948-
# (also not by the garbage collector).
949-
loop = get_event_loop()
950-
loop.run_until_complete(loop.shutdown_asyncgens())
951-
loop.close()
952943

953944
thread = threading.Thread(target=run_in_thread)
954945
thread.start()
@@ -958,21 +949,7 @@ def run_in_thread() -> None:
958949
raise exception
959950
return result
960951

961-
# We don't create a new event loop by default, because we want to be
962-
# sure that when this is called multiple times, each call of `run()`
963-
# goes through the same event loop. This way, users can schedule
964-
# background-tasks that keep running across multiple prompts.
965-
try:
966-
loop = get_event_loop()
967-
except RuntimeError:
968-
# Possibly we are not running in the main thread, where no event
969-
# loop is set by default. Or somebody called `asyncio.run()`
970-
# before, which closes the existing event loop. We can create a new
971-
# loop.
972-
loop = new_event_loop()
973-
set_event_loop(loop)
974-
975-
return loop.run_until_complete(
952+
return asyncio.run(
976953
self.run_async(
977954
pre_run=pre_run,
978955
set_exception_handler=set_exception_handler,
@@ -1074,7 +1051,7 @@ def create_background_task(
10741051
10751052
This is not threadsafe.
10761053
"""
1077-
loop = self.loop or get_event_loop()
1054+
loop = self.loop or get_running_loop()
10781055
task: asyncio.Task[None] = loop.create_task(coroutine)
10791056
self._background_tasks.add(task)
10801057

@@ -1093,7 +1070,7 @@ def _on_background_task_done(self, task: "asyncio.Task[None]") -> None:
10931070

10941071
exc = task.exception()
10951072
if exc is not None:
1096-
get_event_loop().call_exception_handler(
1073+
get_running_loop().call_exception_handler(
10971074
{
10981075
"message": f"prompt_toolkit.Application background task {task!r} "
10991076
"raised an unexpected exception.",
@@ -1501,7 +1478,7 @@ def attach_winch_signal_handler(
15011478

15021479
# Keep track of the previous handler.
15031480
# (Only UnixSelectorEventloop has `_signal_handlers`.)
1504-
loop = get_event_loop()
1481+
loop = get_running_loop()
15051482
previous_winch_handler = getattr(loop, "_signal_handlers", {}).get(sigwinch)
15061483

15071484
try:

src/prompt_toolkit/completion/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ async def get_completions_async(
267267
# def get_all_in_thread() -> List[Completion]:
268268
# return list(self.get_completions(document, complete_event))
269269

270-
# completions = await get_event_loop().run_in_executor(None, get_all_in_thread)
270+
# completions = await get_running_loop().run_in_executor(None, get_all_in_thread)
271271
# for completion in completions:
272272
# yield completion
273273

src/prompt_toolkit/contrib/ssh/server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
"""
44
import asyncio
55
import traceback
6+
from asyncio import get_running_loop
67
from typing import Any, Awaitable, Callable, Optional, TextIO, cast
78

89
import asyncssh
910

1011
from prompt_toolkit.application.current import AppSession, create_app_session
1112
from prompt_toolkit.data_structures import Size
12-
from prompt_toolkit.eventloop import get_event_loop
1313
from prompt_toolkit.input import PipeInput, create_pipe_input
1414
from prompt_toolkit.output.vt100 import Vt100_Output
1515

@@ -75,7 +75,7 @@ def shell_requested(self) -> bool:
7575
return True
7676

7777
def session_started(self) -> None:
78-
self.interact_task = get_event_loop().create_task(self._interact())
78+
self.interact_task = get_running_loop().create_task(self._interact())
7979

8080
async def _interact(self) -> None:
8181
if self._chan is None:
@@ -141,7 +141,7 @@ async def interact(ssh_session: PromptToolkitSSHSession) -> None:
141141
print_formatted_text('You said: ', text)
142142
143143
server = PromptToolkitSSHServer(interact=interact)
144-
loop = get_event_loop()
144+
loop = get_running_loop()
145145
loop.run_until_complete(
146146
asyncssh.create_server(
147147
lambda: MySSHServer(interact),

src/prompt_toolkit/contrib/telnet/server.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
import asyncio
55
import socket
66
import sys
7+
from asyncio import get_running_loop
78
from typing import Any, Awaitable, Callable, List, Optional, Set, TextIO, Tuple, cast
89

910
from prompt_toolkit.application.current import create_app_session, get_app
1011
from prompt_toolkit.application.run_in_terminal import run_in_terminal
1112
from prompt_toolkit.data_structures import Size
12-
from prompt_toolkit.eventloop import get_event_loop
1313
from prompt_toolkit.formatted_text import AnyFormattedText, to_formatted_text
1414
from prompt_toolkit.input import PipeInput, create_pipe_input
1515
from prompt_toolkit.output.vt100 import Vt100_Output
@@ -193,7 +193,7 @@ def handle_incoming_data() -> None:
193193
self.close()
194194

195195
# Add reader.
196-
loop = get_event_loop()
196+
loop = get_running_loop()
197197
loop.add_reader(self.conn, handle_incoming_data)
198198

199199
try:
@@ -219,7 +219,7 @@ def close(self) -> None:
219219
self._closed = True
220220

221221
self.vt100_input.close()
222-
get_event_loop().remove_reader(self.conn)
222+
get_running_loop().remove_reader(self.conn)
223223
self.conn.close()
224224
self.stdout.close()
225225

@@ -310,11 +310,11 @@ def start(self) -> None:
310310
"Listening for telnet connections on %s port %r", self.host, self.port
311311
)
312312

313-
get_event_loop().add_reader(self._listen_socket, self._accept)
313+
get_running_loop().add_reader(self._listen_socket, self._accept)
314314

315315
async def stop(self) -> None:
316316
if self._listen_socket:
317-
get_event_loop().remove_reader(self._listen_socket)
317+
get_running_loop().remove_reader(self._listen_socket)
318318
self._listen_socket.close()
319319

320320
# Wait for all applications to finish.
@@ -379,5 +379,5 @@ async def run() -> None:
379379
finally:
380380
self._application_tasks.remove(task)
381381

382-
task = get_event_loop().create_task(run())
382+
task = get_running_loop().create_task(run())
383383
self._application_tasks.append(task)

0 commit comments

Comments
 (0)