18
18
import threading
19
19
import uuid
20
20
import warnings
21
- from asyncio import Task , create_task
21
+ from asyncio import AbstractEventLoop , Task , create_task
22
22
from concurrent .futures import Future
23
23
from contextlib import (
24
24
asynccontextmanager ,
150
150
if constants .DEBUG :
151
151
warnings .simplefilter ("always" , ResourceWarning )
152
152
153
- # `asyncio.get_event_loop()` is deprecated since Python 3.10:
154
- _ASYNCIO_GET_EVENT_LOOP_IS_DEPRECATED = sys .version_info >= (3 , 10 , 0 )
155
-
156
153
ComposeResult = Iterable [Widget ]
157
154
RenderResult : TypeAlias = "RenderableType | Visual | SupportsVisual"
158
155
"""Result of Widget.render()"""
@@ -2059,7 +2056,6 @@ async def run_async(
2059
2056
from textual .pilot import Pilot
2060
2057
2061
2058
app = self
2062
-
2063
2059
auto_pilot_task : Task | None = None
2064
2060
2065
2061
if auto_pilot is None and constants .PRESS :
@@ -2092,27 +2088,29 @@ async def run_auto_pilot(
2092
2088
run_auto_pilot (auto_pilot , pilot ), name = repr (pilot )
2093
2089
)
2094
2090
2095
- try :
2096
- app ._loop = asyncio .get_running_loop ()
2097
- app ._thread_id = threading .get_ident ()
2098
-
2099
- await app ._process_messages (
2100
- ready_callback = None if auto_pilot is None else app_ready ,
2101
- headless = headless ,
2102
- inline = inline ,
2103
- inline_no_clear = inline_no_clear ,
2104
- mouse = mouse ,
2105
- terminal_size = size ,
2106
- )
2107
- finally :
2091
+ app ._loop = asyncio .get_running_loop ()
2092
+ app ._thread_id = threading .get_ident ()
2093
+ with app ._context ():
2108
2094
try :
2109
- if auto_pilot_task is not None :
2110
- await auto_pilot_task
2095
+ await app ._process_messages (
2096
+ ready_callback = None if auto_pilot is None else app_ready ,
2097
+ headless = headless ,
2098
+ inline = inline ,
2099
+ inline_no_clear = inline_no_clear ,
2100
+ mouse = mouse ,
2101
+ terminal_size = size ,
2102
+ )
2111
2103
finally :
2112
2104
try :
2113
- await asyncio .shield (app ._shutdown ())
2114
- except asyncio .CancelledError :
2115
- pass
2105
+ if auto_pilot_task is not None :
2106
+ await auto_pilot_task
2107
+ finally :
2108
+ try :
2109
+ await asyncio .shield (app ._shutdown ())
2110
+ except asyncio .CancelledError :
2111
+ pass
2112
+ app ._loop = None
2113
+ app ._thread_id = 0
2116
2114
2117
2115
return app .return_value
2118
2116
@@ -2125,6 +2123,7 @@ def run(
2125
2123
mouse : bool = True ,
2126
2124
size : tuple [int , int ] | None = None ,
2127
2125
auto_pilot : AutopilotCallbackType | None = None ,
2126
+ loop : AbstractEventLoop | None = None ,
2128
2127
) -> ReturnType | None :
2129
2128
"""Run the app.
2130
2129
@@ -2136,36 +2135,24 @@ def run(
2136
2135
size: Force terminal size to `(WIDTH, HEIGHT)`,
2137
2136
or None to auto-detect.
2138
2137
auto_pilot: An auto pilot coroutine.
2139
-
2138
+ loop: Asyncio loop instance, or `None` to use default.
2140
2139
Returns:
2141
2140
App return value.
2142
2141
"""
2143
2142
2144
2143
async def run_app () -> None :
2145
2144
"""Run the app."""
2146
- self ._loop = asyncio .get_running_loop ()
2147
- self ._thread_id = threading .get_ident ()
2148
- with self ._context ():
2149
- try :
2150
- await self .run_async (
2151
- headless = headless ,
2152
- inline = inline ,
2153
- inline_no_clear = inline_no_clear ,
2154
- mouse = mouse ,
2155
- size = size ,
2156
- auto_pilot = auto_pilot ,
2157
- )
2158
- finally :
2159
- self ._loop = None
2160
- self ._thread_id = 0
2145
+ await self .run_async (
2146
+ headless = headless ,
2147
+ inline = inline ,
2148
+ inline_no_clear = inline_no_clear ,
2149
+ mouse = mouse ,
2150
+ size = size ,
2151
+ auto_pilot = auto_pilot ,
2152
+ )
2161
2153
2162
- if _ASYNCIO_GET_EVENT_LOOP_IS_DEPRECATED :
2163
- # N.B. This doesn't work with Python<3.10, as we end up with 2 event loops:
2164
- asyncio .run (run_app ())
2165
- else :
2166
- # However, this works with Python<3.10:
2167
- event_loop = asyncio .get_event_loop ()
2168
- event_loop .run_until_complete (run_app ())
2154
+ event_loop = asyncio .get_event_loop () if loop is None else loop
2155
+ event_loop .run_until_complete (run_app ())
2169
2156
return self .return_value
2170
2157
2171
2158
async def _on_css_change (self ) -> None :
0 commit comments