55import logging
66import signal
77from typing import Any , ClassVar , Type
8+ import warnings
89
910from rich .control import Control
1011from rich .repr import rich_repr , RichReprResult
2324log = logging .getLogger ("rich" )
2425
2526
27+ # asyncio will warn against resources not being cleared
28+ warnings .simplefilter ("always" , ResourceWarning )
29+ # https://github.com/boto/boto3/issues/454
30+ warnings .filterwarnings (
31+ "ignore" , category = ResourceWarning , message = "unclosed.*<ssl.SSLSocket.*>"
32+ )
33+
34+
2635LayoutDefinition = "dict[str, Any]"
2736
2837try :
@@ -76,28 +85,36 @@ def on_keyboard_interupt(self) -> None:
7685 asyncio .run_coroutine_threadsafe (self .post_message (event ), loop = loop )
7786
7887 async def process_messages (self ) -> None :
88+ try :
89+ await self ._process_messages ()
90+ except Exception :
91+ self .console .print_exception (show_locals = True )
92+
93+ async def _process_messages (self ) -> None :
7994 log .debug ("driver=%r" , self .driver )
8095 loop = asyncio .get_event_loop ()
8196
8297 loop .add_signal_handler (signal .SIGINT , self .on_keyboard_interupt )
8398 driver = self .driver (self .console , self )
84- try :
85- driver .start_application_mode ()
86- except Exception :
87- log .exception ("error starting application mode" )
88- raise
8999
90100 active_app .set (self )
91101
92102 await self .add (self .view )
93103
94104 await self .post_message (events .Startup (sender = self ))
95- self .refresh ()
96105 try :
106+ driver .start_application_mode ()
107+ except Exception :
108+ log .exception ("error starting application mode" )
109+ raise
110+ try :
111+ self .refresh ()
97112 await super ().process_messages ()
98113 finally :
99- loop .remove_signal_handler (signal .SIGINT )
100- driver .stop_application_mode ()
114+ try :
115+ driver .stop_application_mode ()
116+ finally :
117+ loop .remove_signal_handler (signal .SIGINT )
101118
102119 await asyncio .gather (* (child .close_messages () for child in self .children ))
103120 self .children .clear ()
@@ -116,7 +133,6 @@ async def on_event(self, event: events.Event, priority: int) -> None:
116133 if isinstance (event , events .Key ):
117134 key_action = self .KEYS .get (event .key , None )
118135 if key_action is not None :
119- log .debug ("action %r" , key_action )
120136 await self .action (key_action )
121137 return
122138
@@ -149,18 +165,11 @@ async def dispatch_action(
149165 self , destination : str , action_name : str , params : Any
150166 ) -> None :
151167 action_target = self ._action_targets .get (destination , None )
152- log .debug ("ACTION TARGET %r" , action_target )
153168 if action_target is not None :
154169 method_name = f"action_{ action_name } "
155170 method = getattr (action_target , method_name , None )
156- log .debug ("ACTION METHOD %r" , method )
157171 if method is not None :
158- try :
159- await method (* params )
160- except Exception :
161- log .exception (
162- f"error in action { destination } .{ action_name } { params !r} "
163- )
172+ await method (* params )
164173
165174 async def on_shutdown_request (self , event : events .ShutdownRequest ) -> None :
166175 log .debug ("shutdown request" )
@@ -187,6 +196,9 @@ async def on_mouse_scroll_down(self, event: events.MouseScrollUp) -> None:
187196 async def action_quit (self ) -> None :
188197 await self .close_messages ()
189198
199+ async def action_bang (self ) -> None :
200+ 1 / 0
201+
190202
191203if __name__ == "__main__" :
192204 import asyncio
@@ -212,7 +224,7 @@ async def action_quit(self) -> None:
212224
213225 class MyApp (App ):
214226
215- KEYS = {"q" : "quit" , "ctrl+c" : "quit" , "b" : "view.toggle('left')" }
227+ KEYS = {"q" : "quit" , "x" : "bang" , " ctrl+c" : "quit" , "b" : "view.toggle('left')" }
216228
217229 async def on_startup (self , event : events .Startup ) -> None :
218230 await self .view .mount_all (
0 commit comments