grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a BjŒj©Åã@säddlmZmZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl mZz ddlZWney‚Yn0ddlmZmZddlmZmZddlmZmZdd lmZdd lmZdd lmZd Z Gd d„de!ƒZ"Gdd„de!ƒZ#Gdd„de$ƒZ%Gdd„de$ƒZ&Gdd„de&ƒZ'Gdd„de&ƒZ(Gdd„de&ƒZ)zddl*m+Z+Wne�yte$Z+Yn0Gdd„de+ƒZ,Gdd„de&ƒZ-Gd d!„d!e&ƒZ.ej/d"k�r¾d#d$l0m1Z1d+d&d'„Z2d(d)„Z3e4d*k�ràe3ƒdS),é)ÚdivisionÚprint_functionN©Úwraps)Úcount)ÚWeakKeyDictionary)ÚStoppingContextÚis_mouse_event)ÚPYTHON3Úreraise)Ú command_mapÚ REDRAW_SCREEN)Ú PopUpTarget)Úsignals)ÚINPUT_DESCRIPTORS_CHANGEDic@seZdZdZdS)Ú ExitMainLoopz_ When this exception is raised within a main loop the main loop will exit cleanly. N)Ú__name__Ú __module__Ú __qualname__Ú__doc__©rrú5/usr/lib64/python3.9/site-packages/urwid/main_loop.pyr1src@s eZdZdS)ÚCantUseExternalLoopN)rrrrrrrr8src@sþeZdZdZd=dd„Zdd „Zed d „ed d �Zdd„Zedd „eƒZ d>dd„Z d?dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„ZdS)@ÚMainLoopaÁ This is the standard main loop implementation for a single interactive session. :param widget: the topmost widget used for painting the screen, stored as :attr:`widget` and may be modified. Must be a box widget. :type widget: widget instance :param palette: initial palette for screen :type palette: iterable of palette entries :param screen: screen to use, default is a new :class:`raw_display.Screen` instance; stored as :attr:`screen` :type screen: display module screen instance :param handle_mouse: ``True`` to ask :attr:`.screen` to process mouse events :type handle_mouse: bool :param input_filter: a function to filter input before sending it to :attr:`.widget`, called from :meth:`.input_filter` :type input_filter: callable :param unhandled_input: a function called when input is not handled by :attr:`.widget`, called from :meth:`.unhandled_input` :type unhandled_input: callable :param event_loop: if :attr:`.screen` supports external an event loop it may be given here, default is a new :class:`SelectEventLoop` instance; stored as :attr:`.event_loop` :type event_loop: event loop instance :param pop_ups: `True` to wrap :attr:`.widget` with a :class:`PopUpTarget` instance to allow any widget to open a pop-up anywhere on the screen :type pop_ups: boolean .. attribute:: screen The screen object this main loop uses for screen updates and reading input .. attribute:: event_loop The event loop object this main loop uses for waiting on alarms and IO rNTFc Cs¦||_||_||_|s*ddlm} |  ¡}|r8| |¡||_d|_||_ ||_ t |dƒsp|durpt d|fƒ‚|dur~t ƒ}||_t |jdƒrœ|jj|j_i|_dS)Nr)Ú raw_displayÚhook_event_loopz=screen object passed %r does not support external event loopsÚsignal_handler_setter)Ú_widgetÚ handle_mouseÚpop_upsÚurwidrZScreenZregister_paletteÚscreenÚ screen_sizeÚ_unhandled_inputÚ _input_filterÚhasattrÚNotImplementedErrorÚSelectEventLoopÚ event_loopÚset_signal_handlerrÚ _watch_pipes) ÚselfÚwidgetZpaletter!rÚ input_filterÚunhandled_inputr(rrrrrÚ__init__is0   ÿÿ  zMainLoop.__init__cCs$||_|jr|j|j_n|j|_dS©N)rrÚ_topmost_widgetZoriginal_widget)r+r,rrrÚ _set_widgetŒs zMainLoop._set_widgetcCs|jSr0)r©r+rrrÚ’ózMainLoop.zj Property for the topmost widget used to draw the screen. This must be a box widget. )ÚdoccCs$||_|rt|jƒ|_n|j|_dSr0)Ú_pop_upsrrr1)r+rrrrÚ _set_pop_ups˜szMainLoop._set_pop_upscCs|jSr0)r7r3rrrr4žr5cs‡‡‡fdd„}ˆj ||¡S)a_ Schedule an alarm in *sec* seconds that will call *callback* from the within the :meth:`run` method. :param sec: seconds until alarm :type sec: float :param callback: function to call with two parameters: this main loop object and *user_data* :type callback: callable csˆˆˆƒdSr0rr©Úcallbackr+Ú user_datarrÚcb«sz!MainLoop.set_alarm_in..cb)r(Úalarm)r+Úsecr:r;r<rr9rÚ set_alarm_in s zMainLoop.set_alarm_incs&‡‡‡fdd„}ˆj |t ¡|¡S)a» Schedule an alarm at *tm* time that will call *callback* from the within the :meth:`run` function. Returns a handle that may be passed to :meth:`remove_alarm`. :param tm: time to call callback e.g. ``time.time() + 5`` :type tm: float :param callback: function to call with two parameters: this main loop object and *user_data* :type callback: callable csˆˆˆƒdSr0rrr9rrr<»sz!MainLoop.set_alarm_at..cb)r(r=Útime)r+Útmr:r;r<rr9rÚ set_alarm_at¯s zMainLoop.set_alarm_atcCs |j |¡S)zf Remove an alarm. Return ``True`` if *handle* was found, ``False`` otherwise. )r(Ú remove_alarm©r+ÚhandlerrrrC¿szMainLoop.remove_alarmcsTt ¡\‰}t ˆtjtj¡d‰‡‡‡‡fdd„}ˆj ˆ|¡‰ˆˆfˆj|<|S)aù Create a pipe for use by a subprocess or thread to trigger a callback in the process/thread running the main loop. :param callback: function taking one parameter to call from within the process/thread running the main loop :type callback: callable This method returns a file descriptor attached to the write end of a pipe. The read end of the pipe is added to the list of files :attr:`event_loop` is watching. When data is written to the pipe the callback function will be called and passed a single value containing data read from the pipe. This method may be used any time you want to update widgets from another thread or subprocess. Data may be written to the returned file descriptor with ``os.write(fd, data)``. Ensure that data is less than 512 bytes (or 4K on Linux) so that the callback will be triggered just once with the complete value of data passed in. If the callback returns ``False`` then the watch will be removed from :attr:`event_loop` and the read end of the pipe will be closed. You are responsible for closing the write end of the pipe with ``os.close(fd)``. Ncs6t ˆt¡}ˆ|ƒ}|dur2ˆj ˆ¡t ˆ¡dS©NF)ÚosÚreadÚPIPE_BUFFER_READ_SIZEr(Úremove_watch_fileÚclose)ÚdataÚrval©r:Úpipe_rdr+Ú watch_handlerrr<æs   zMainLoop.watch_pipe..cb)rGÚpipeÚfcntlZF_SETFLÚ O_NONBLOCKr(Ú watch_filer*)r+r:Zpipe_wrr<rrNrÚ watch_pipeÆs zMainLoop.watch_pipecCsHz|j |¡\}}Wnty(YdS0|j |¡s:dSt |¡dS)z÷ Close the read end of the pipe and remove the watch created by :meth:`watch_pipe`. You are responsible for closing the write end of the pipe. Returns ``True`` if the watch pipe exists, ``False`` otherwise FT)r*ÚpopÚKeyErrorr(rJrGrK)r+Zwrite_fdrPrOrrrÚremove_watch_pipeñs   zMainLoop.remove_watch_pipecCs|j ||¡S)z» Call *callback* when *fd* has some data to read. No parameters are passed to callback. Returns a handle that may be passed to :meth:`remove_watch_file`. )r(rT©r+Úfdr:rrrrTszMainLoop.watch_filecCs |j |¡S)zn Remove a watch file. Returns ``True`` if the watch file exists, ``False`` otherwise. )r(rJrDrrrrJ szMainLoop.remove_watch_filecCs$z | ¡WntyYn0dS)an Start the main loop handling input events and updating the screen. The loop will continue until an :exc:`ExitMainLoop` exception is raised. If you would prefer to manage the event loop yourself, don't use this method. Instead, call :meth:`start` before starting the event loop, and :meth:`stop` once it's finished. N)Ú_runrr3rrrÚruns   z MainLoop.runcCsdS)a- >>> w = _refl("widget") # _refl prints out function calls >>> w.render_rval = "fake canvas" # *_rval is used for return values >>> scr = _refl("screen") >>> scr.get_input_descriptors_rval = [42] >>> scr.get_cols_rows_rval = (20, 10) >>> scr.started = True >>> scr._urwid_signals = {} >>> evl = _refl("event_loop") >>> evl.enter_idle_rval = 1 >>> evl.watch_file_rval = 2 >>> ml = MainLoop(w, [], scr, event_loop=evl) >>> ml.run() # doctest:+ELLIPSIS screen.start() screen.set_mouse_tracking() screen.unhook_event_loop(...) screen.hook_event_loop(...) event_loop.enter_idle() event_loop.run() event_loop.remove_enter_idle(1) screen.unhook_event_loop(...) screen.stop() >>> ml.draw_screen() # doctest:+ELLIPSIS screen.get_cols_rows() widget.render((20, 10), focus=True) screen.draw_screen((20, 10), 'fake canvas') Nrr3rrrÚ _test_run"szMainLoop._test_runcCsx|j ¡|jr|j ¡t|jdƒs.tdƒ‚zt |jt|j ¡Wnt yVYn0|  ¡|j   |j ¡|_t|ƒS)a Sets up the main loop, hooking into the event loop where necessary. Starts the :attr:`screen` if it hasn't already been started. If you want to control starting and stopping the event loop yourself, you should call this method before starting, and call `stop` once the loop has finished. You may also use this method as a context manager, which will stop the loop automatically at the end of the block: with main_loop.start(): ... Note that some event loop implementations don't handle exceptions specially if you manage the event loop yourself. In particular, the Twisted and asyncio loops won't stop automatically when :exc:`ExitMainLoop` (or anything else) is raised. rz1Screen {0!r} doesn't support external event loops)r!ÚstartrZset_mouse_trackingr%rrZconnect_signalrÚ_reset_input_descriptorsÚ NameErrorr(Ú enter_idleÚ entering_idleÚ idle_handlerr3rrrr^?s    ÿ ÿ zMainLoop.startcCs@|j |j¡|`t |jt|j¡|j |j¡|j  ¡dS)z˜ Cleans up any hooks added to the event loop. Only call this if you're managing the event loop yourself, after the loop stops. N) r(Úremove_enter_idlercrZdisconnect_signalr!rr_Úunhook_event_loopÚstopr3rrrrfes ÿz MainLoop.stopcCs$|j |j¡|j |j|j¡dSr0)r!rer(rÚ_updater3rrrr_rsz!MainLoop._reset_input_descriptorsc Cszz | ¡Wn8tyDz| ¡W|j ¡YS|j ¡0Yn0z|j ¡Wn|j ¡‚Yn0| ¡dSr0)r^rÚ_run_screen_event_loopr!rfr(r\r3rrrr[vs   þ z MainLoop._runcCs,| ||¡}|r(| |¡d|vr(d|_dS)aˆ >>> w = _refl("widget") >>> w.selectable_rval = True >>> w.mouse_event_rval = True >>> scr = _refl("screen") >>> scr.get_cols_rows_rval = (15, 5) >>> evl = _refl("event_loop") >>> ml = MainLoop(w, [], scr, event_loop=evl) >>> ml._input_timeout = "old timeout" >>> ml._update(['y'], [121]) # doctest:+ELLIPSIS screen.get_cols_rows() widget.selectable() widget.keypress((15, 5), 'y') >>> ml._update([("mouse press", 1, 5, 4)], []) widget.mouse_event((15, 5), 'mouse press', 1, 5, 4, focus=True) >>> ml._update([], []) ú window resizeN)r-Ú process_inputr"©r+ÚkeysÚrawrrrrg†s   zMainLoop._updatecCsd}| ¡|s&|jjr&t |jj¡}d}|s–|rVtd|dt ¡ƒ}|j |¡n |j d¡|j  d¡\}}|s*|r*|dt ¡}|dkr*q–q*|  ||¡}|r°|  |¡|rü|dt ¡}|dkrÎqü|\}}}|ƒ|jjröt |jj¡}q°d}q°d|vrd|_ qdS)z× This method is used when the screen does not support using external event loops. The alarms stored in the SelectEventLoop in :attr:`event_loop` are modified by this method. NrTri) Ú draw_screenr(Ú_alarmsÚheapqÚheappopÚmaxr@r!Zset_input_timeoutsZ get_inputr-rjr")r+Z next_alarmrlr>rmrAÚ tie_breakr:rrrrhŸs:     zMainLoop._run_screen_event_loopcCsdS)aq >>> w = _refl("widget") >>> scr = _refl("screen") >>> scr.get_cols_rows_rval = (10, 5) >>> scr.get_input_rval = [], [] >>> ml = MainLoop(w, screen=scr) >>> def stop_now(loop, data): ... raise ExitMainLoop() >>> handle = ml.set_alarm_in(0, stop_now) >>> try: ... ml._run_screen_event_loop() ... except ExitMainLoop: ... pass screen.get_cols_rows() widget.render((10, 5), focus=True) screen.draw_screen((10, 5), None) screen.set_input_timeouts(0) screen.get_input(True) Nrr3rrrÚ_test_run_screen_event_loopÐsz$MainLoop._test_run_screen_event_loopc CsÀ|js|j ¡|_d}|D] }|dkr(qt|ƒrh|\}}}}t|jdƒr‚|jj|j||||dd�r‚d}n|j ¡r‚|j |j|¡}|r¶t |t kr¢|j  ¡d}qº|t |  |¡ƒO}qd}q|S)aÝ This method will pass keyboard input and mouse events to :attr:`widget`. This method is called automatically from the :meth:`run` method when there is input, but may also be called to simulate input from the user. *keys* is a list of input returned from :attr:`screen`'s get_input() or get_input_nonblocking() methods. Returns ``True`` if any key was handled by a widget or the :meth:`unhandled_input` method. FriÚ mouse_eventT©ZfocusN)r"r!Ú get_cols_rowsr r%r1ruZ selectableZkeypressr r ÚclearÚboolr.)r+rlZsomething_handledÚkZeventZbuttonÚcolÚrowrrrrjås,      ÿ   zMainLoop.process_inputcCsdS)aÁ >>> w = _refl("widget") >>> w.selectable_rval = True >>> scr = _refl("screen") >>> scr.get_cols_rows_rval = (10, 5) >>> ml = MainLoop(w, [], scr) >>> ml.process_input(['enter', ('mouse drag', 1, 14, 20)]) screen.get_cols_rows() widget.selectable() widget.keypress((10, 5), 'enter') widget.mouse_event((10, 5), 'mouse drag', 1, 14, 20, focus=True) True Nrr3rrrÚ_test_process_input szMainLoop._test_process_inputcCs|jr| ||¡S|S)av This function is passed each all the input events and raw keystroke values. These values are passed to the *input_filter* function passed to the constructor. That function must return a list of keys to be passed to the widgets to handle. If no *input_filter* was defined this implementation will return all the input events. )r$rkrrrr-s zMainLoop.input_filtercCs|jr| |¡SdS)aŽ This function is called with any input that was not handled by the widgets, and calls the *unhandled_input* function passed to the constructor. If no *unhandled_input* was defined then the input will be ignored. *input* is the keyboard or mouse input. The *unhandled_input* function should return ``True`` if it handled the input. N)r#)r+Úinputrrrr.'s zMainLoop.unhandled_inputcCs|jjr| ¡dS)zÄ This method is called whenever the event loop is about to enter the idle state. :meth:`draw_screen` is called here to update the screen when anything has changed. N)r!Ústartedrnr3rrrrb6szMainLoop.entering_idlecCs8|js|j ¡|_|jj|jdd�}|j |j|¡dS)a5 Render the widgets and paint the screen. This method is called automatically from :meth:`entering_idle`. If you modify the widgets displayed outside of handling input or responding to an alarm you will need to call this method yourself to repaint the screen. TrvN)r"r!rwr1Zrenderrn)r+Zcanvasrrrrn?s  zMainLoop.draw_screen)rNTNNNF)N)N) rrrrr/r2Úpropertyr,r8rr?rBrCrUrXrTrJr\r]r^rfr_r[rgrhrtrjr}r-r.rbrnrrrrr;sB-þ # ÿ  + & 1'  rc@sPeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dS)Ú EventLoopzT Abstract class representing an event loop to be used by :class:`MainLoop`. cCs tƒ‚dS)aW Call callback() a given time from now. No parameters are passed to callback. This method has no default implementation. Returns a handle that may be passed to remove_alarm() seconds -- floating point time to wait before calling callback callback -- function to call from event loop N©r&©r+Úsecondsr:rrrr=Ts zEventLoop.alarmcCs tƒ‚dS)z¥ Add a callback for entering idle. This method has no default implementation. Returns a handle that may be passed to remove_idle() Nr‚©r+r:rrrrabszEventLoop.enter_idlecCs tƒ‚dS)z‘ Remove an alarm. This method has no default implementation. Returns True if the alarm exists, False otherwise Nr‚rDrrrrClszEventLoop.remove_alarmcCs tƒ‚dS)z� Remove an idle callback. This method has no default implementation. Returns True if the handle was removed. Nr‚rDrrrrdvszEventLoop.remove_enter_idlecCs tƒ‚dS)z› Remove an input file. This method has no default implementation. Returns True if the input file exists, False otherwise Nr‚rDrrrrJ€szEventLoop.remove_watch_filecCs tƒ‚dS)zà Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly. This method has no default implementation. Nr‚r3rrrr\Šsz EventLoop.runcCs tƒ‚dS)aV Call callback() when fd has some data to read. No parameters are passed to callback. This method has no default implementation. Returns a handle that may be passed to remove_watch_file() fd -- file descriptor to watch for input callback -- function to call when input is available Nr‚rYrrrrT“s zEventLoop.watch_filecCs t ||¡S)aƒ Sets the signal handler for signal signum. The default implementation of :meth:`set_signal_handler` is simply a proxy function that calls :func:`signal.signal()` and returns the resulting value. signum -- signal number handler -- function (taking signum as its single argument), or `signal.SIG_IGN`, or `signal.SIG_DFL` )Úsignal)r+ÚsignumÚhandlerrrrr)¡s zEventLoop.set_signal_handlerN) rrrrr=rarCrdrJr\rTr)rrrrr�Os     r�c@s`eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dS)r'z3 Event loop based on :func:`select.select` cCs$g|_i|_d|_i|_tƒ|_dS©Nr)roÚ _watch_filesÚ _idle_handleÚ_idle_callbacksrÚ _tie_breakr3rrrr/´s zSelectEventLoop.__init__cCs.t ¡|}|t|jƒ|f}t |j|¡|S©á# Call callback() a given time from now. No parameters are passed to callback. Returns a handle that may be passed to remove_alarm() seconds -- floating point time to wait before calling callback callback -- function to call from event loop )r@Únextr�rpÚheappushro)r+r„r:rArErrrr=»s zSelectEventLoop.alarmcCs8z|j |¡t |j¡WdSty2YdS0dS)ú] Remove an alarm. Returns True if the alarm exists, False otherwise TFN)roÚremoverpÚheapifyÚ ValueErrorrDrrrrCÊs    zSelectEventLoop.remove_alarmcCs||j|<|S©á" Call callback() when fd has some data to read. No parameters are passed to callback. Returns a handle that may be passed to remove_watch_file() fd -- file descriptor to watch for input callback -- function to call when input is available ©rŠrYrrrrT×s zSelectEventLoop.watch_filecCs||jvr|j|=dSdS©úg Remove an input file. Returns True if the input file exists, False otherwise TFr˜rDrrrrJäs z!SelectEventLoop.remove_watch_filecCs |jd7_||j|j<|jS)úq Add a callback for entering idle. Returns a handle that may be passed to remove_idle() é©r‹rŒr…rrrraïs zSelectEventLoop.enter_idlecCs&z |j|=Wnty YdS0dS©ú[ Remove an idle callback. Returns True if the handle was removed. FT©rŒrWrDrrrrdùs   z!SelectEventLoop.remove_enter_idlecCs|j ¡D] }|ƒq dS)z9 Call all the registered idle callbacks. N)rŒÚvaluesr…rrrÚ_entering_idleszSelectEventLoop._entering_idlec CshzPd|_z | ¡WqtjyJ}z|jddkr6‚WYd}~qd}~00qWntybYn0dS)ú� Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly. TréN)Ú_did_somethingÚ_loopÚselectÚerrorÚargsr)r+Úerrrr\ s  zSelectEventLoop.runc Csôt|j ¡ƒ}|js|jrz|jr@|jdd}td|t ¡ƒ}|jrb|jrZ|jrb|dkrbd}d}t |g||¡\}}}nd}t |g|¡\}}}|sÔ|dkr®| ¡d|_n&|durÔt   |j¡\}}}|ƒd|_|D]} |j| ƒd|_qØdS)z6 A single iteration of the event loop rZidleNFT) ÚlistrŠrlror¥rrr@r§r¢rprq) r+ZfdsrAÚtimeoutZreadyÚwÚerrrsZalarm_callbackrZrrrr¦s4  ÿÿ zSelectEventLoop._loopN)rrrrr/r=rCrTrJrardr¢r\r¦rrrrr'¯s     r'c@speZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„ZdS)Ú GLibEventLoopz+ Event loop based on GLib.MainLoop cCsRddlm}||_g|_i|_d|_d|_i|_| ¡|_d|_ |  ¡i|_ dS)Nr)ÚGLibF) Z gi.repositoryr°rorŠr‹Ú_glib_idle_enabledrŒrr¦Ú _exc_infoÚ_enable_glib_idleÚ_signal_handlers)r+r°rrrr/Cs  zGLibEventLoop.__init__cs>ˆj‡‡fdd„ƒ}ˆj t|dƒ|¡}ˆj |¡|ˆfS)r�csˆƒˆ ¡dSrF©r³r©r:r+rrÚ ret_falseZsz&GLibEventLoop.alarm..ret_falseiè)Ú handle_exitr°Z timeout_addÚintroÚappend)r+r„r:r·rZrr¶rr=Ps  zGLibEventLoop.alarmcs²tjtjtjtjtjg}ˆj ddd¡s4| tj ¡||vr@dS|ˆj vr^ˆj  ˆj   |¡¡ˆtj krrdd„‰nˆtjkr€dS‡‡fdd„}ˆj ˆjj|||¡}|ˆj |<dS) a‰ Sets the signal handler for signal signum. .. WARNING:: Because this method uses the `GLib`-specific `unix_signal_add` function, its behaviour is different than `signal.signal().` If `signum` is not `SIGHUP`, `SIGINT`, `SIGTERM`, `SIGUSR1`, `SIGUSR2` or `SIGWINCH`, this method performs no actions and immediately returns None. Returns None in all cases (unlike :func:`signal.signal()`). .. signum -- signal number handler -- function (taking signum as its single argument), or `signal.SIG_IGN`, or `signal.SIG_DFL` éé6rNcSsdSr0r)Úxrrrr4Šr5z2GLibEventLoop.set_signal_handler..csˆ|ƒˆjjSr0)r°ZSOURCE_CONTINUE)Z signal_number©rˆr+rrÚ final_handlerŽsz7GLibEventLoop.set_signal_handler..final_handler)r†ÚSIGHUPÚSIGINTÚSIGTERMÚSIGUSR1ÚSIGUSR2r°Z check_versionrºÚSIGWINCHr´Ú source_removerVÚSIG_IGNÚSIG_DFLZunix_signal_addZPRIORITY_DEFAULT)r+r‡rˆZ glib_signalsr¿Úsourcerr¾rr)cs&û      z GLibEventLoop.set_signal_handlercCs@z&|j |d¡|j |d¡WdSty:YdS0dS)r’rTFN)ror“r°rÆr•rDrrrrC•s  zGLibEventLoop.remove_alarmcs2ˆj‡‡fdd„ƒ}ˆj |ˆjj|¡ˆj|<|S)r—csˆƒˆ ¡dS©NTrµ)rÉZ cb_conditionr¶rrÚ io_callback¬sz-GLibEventLoop.watch_file..io_callback)r¸r°Z io_add_watchZIO_INrŠ)r+rZr:rËrr¶rrT¢s ÿzGLibEventLoop.watch_filecCs,||jvr(|j |j|¡|j|=dSdSr™)rŠr°rÆrDrrrrJµs  zGLibEventLoop.remove_watch_filecCs |jd7_||j|j<|jS©zw Add a callback for entering idle. Returns a handle that may be passed to remove_enter_idle() rœr�r…rrrraÁs zGLibEventLoop.enter_idlecCs"|jr dS|j |j¡d|_dSrÊ)r±r°Zidle_addÚ_glib_idle_callbackr3rrrr³ËszGLibEventLoop._enable_glib_idlecCs |j ¡D] }|ƒq d|_dSrF)rŒr¡r±r…rrrrÍÑsz!GLibEventLoop._glib_idle_callbackcCs&z |j|=Wnty YdS0dSržr rDrrrrd×s   zGLibEventLoop.remove_enter_idlecCsXz"|j ¡W|j ¡r:|j ¡n|j ¡r8|j ¡0|jrT|j}d|_t|ŽdS©r£N)r¦r\Ú is_runningÚquitr²r ©r+Úexc_inforrrr\ãs   ÿ  zGLibEventLoop.runcs‡‡fdd„}|S)a, Decorator that cleanly exits the :class:`GLibEventLoop` if :exc:`ExitMainLoop` is thrown inside of the wrapped function. Store the exception info if some other exception occurs, it will be reraised after the loop quits. *f* -- function to be wrapped csbzˆ|i|¤ŽWSty,ˆj ¡Yn2ddl}| ¡ˆ_ˆj ¡rXˆj ¡Yn0dS)NrF)rr¦rÐÚsysrÒr²rÏ)r©ÚkargsrÓ©Úfr+rrÚwrapperüs   z*GLibEventLoop.handle_exit..wrapperr)r+rÖr×rrÕrr¸ós  zGLibEventLoop.handle_exitN)rrrrr/r=r)rCrTrJrar³rÍrdr\r¸rrrrr¯>s 2    r¯c@s€eZdZdZeƒZdZGdd„deƒZe dd„ƒZ ddd „Z d d „Z d d „Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS)ÚTornadoEventLoopa^ This is an Urwid-specific event loop to plug into its MainLoop. It acts as an adaptor for Tornado's IOLoop which does all heavy lifting except idle-callbacks. Notice, since Tornado has no concept of idle callbacks we monkey patch ioloop._impl.poll() function to be able to detect potential idle periods. rc@s(eZdZdZdd„Zdd„Zdd„ZdS) zTornadoEventLoop.PollProxyz– A simple proxy for a Python's poll object that wraps the .poll() method in order to detect idle periods and call Urwid callbacks cCs||_||_d|_d|_dS)NFr)Ú_PollProxy__poll_objÚ_PollProxy__idle_mapÚ _idle_doneÚ _prev_timeout)r+Zpoll_objÚidle_maprrrr/sz#TornadoEventLoop.PollProxy.__init__cCs t|j|ƒSr0)ÚgetattrrÙ)r+ÚnamerrrÚ __getattr__ sz&TornadoEventLoop.PollProxy.__getattr__cCs�||jkrd|_||_t ¡}|j d¡}|r8d|_|S|jsZ|j ¡D] }|ƒqHd|_tdt|||t ¡ƒƒ}|j |¡}|rŒd|_|S)NFrT) rÜrÛr@rÙÚpollrÚr¡rrÚmin)r+r¬r^Úeventsr:rrrrá#s"   zTornadoEventLoop.PollProxy.pollN)rrrrr/ràrárrrrÚ PollProxysräcCs0||jvrdSi|j|<}| |j|¡|_dS)z@ Wraps original poll object in the IOLoop's poll object N)Ú_ioloop_registryräZ_impl)ÚclsÚiolooprÝrrrÚ_patch_poll_impl=s z!TornadoEventLoop._patch_poll_implNcCsD|sddlm}| ¡}||_| |¡i|_i|_d|_d|_dS)Nr©ÚIOLoop) Útornado.iolooprêÚinstanceÚ_iolooprèÚ_pending_alarmsÚ_watch_handlesÚ_max_watch_handleÚ _exception)r+rçrêrrrr/Hs  zTornadoEventLoop.__init__cs8ˆj}‡‡‡fdd„}| | ¡||¡‰dˆjˆ<ˆS)Ncs0z ˆjˆ=WntyYn0ˆ ˆ¡ƒdSr0)rîrWr¸r©r:rEr+rrÚwrappedUs   z'TornadoEventLoop.alarm..wrappedrœ)ríZ add_timeoutr@rî)r+Zsecsr:rçrórròrr=Ss  zTornadoEventLoop.alarmcCs6|j |¡z |j|=Wnty,YdS0dSdS©NFT)ríZremove_timeoutrîrWrDrrrrC_s    zTornadoEventLoop.remove_alarmcsNddlm}‡‡fdd„}ˆj |||j¡ˆjd7_ˆj}|ˆj|<|S)Nrrécs ˆ ˆ¡ƒSr0)r¸)rZrãr¶rrr4jr5z-TornadoEventLoop.watch_file..rœ)rërêríZ add_handlerZREADrðrï)r+rZr:rêrˆrErr¶rrThs  zTornadoEventLoop.watch_filecCs.|j |d¡}|durdS|j |¡dSdSrô)rïrVríZremove_handler)r+rErZrrrrJqs  z"TornadoEventLoop.remove_watch_filecCs,|jd7_|j}|j|j}|||<|S)Nrœ)Ú_max_idle_handlerårí)r+r:rErÝrrrrays  zTornadoEventLoop.enter_idlecCs |j|j}| |d¡}|duSr0)rårírV)r+rErÝr<rrrrd€s  z"TornadoEventLoop.remove_enter_idlecstˆƒ‡‡fdd„ƒ}|S)Nc sdzˆ|i|¤ŽWSty,ˆj ¡Yn4ty^}z|ˆ_ˆj ¡WYd}~n d}~00dSrF)rrírfÚ Exceptionrñ)r©ÚkwÚexc©Úfuncr+rrr׆s  z-TornadoEventLoop.handle_exit..wrapperr)r+rúr×rrùrr¸…s zTornadoEventLoop.handle_exitcCs&|j ¡|jr"|jd}|_|‚dSr0)rír^rñ)r+rørrrr\’s zTornadoEventLoop.run)N)rrrrrrårõÚobjecträÚ classmethodrèr/r=rCrTrJrardr¸r\rrrrrØ s'     rØ)ÚFileDescriptorc@s$eZdZdd„Zdd„Zdd„ZdS)ÚTwistedInputDescriptorcCs||_||_t ||¡dSr0)Ú_filenor<rýr/)r+ÚreactorrZr<rrrr/ŸszTwistedInputDescriptor.__init__cCs|jSr0)rÿr3rrrÚfileno¤szTwistedInputDescriptor.filenocCs| ¡Sr0)r<r3rrrÚdoRead§szTwistedInputDescriptor.doReadN)rrrr/rrrrrrrþžsrþc@speZdZdZdZddd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zddd„ZdS)ÚTwistedEventLoopz& Event loop based on Twisted_ gp?NTcCsT|durddl}|jj}||_g|_i|_d|_d|_i|_d|_||_ |  ¡dS)a- :param reactor: reactor to use :type reactor: :class:`twisted.internet.reactor`. :param: manage_reactor: `True` if you want this event loop to run and stop the reactor. :type manage_reactor: boolean .. WARNING:: Twisted's reactor doesn't like to be stopped and run again. If you need to stop and run your :class:`MainLoop`, consider setting ``manage_reactor=False`` and take care of running/stopping the reactor at the beginning/ending of your program yourself. You can also forego using :class:`MainLoop`'s run() entirely, and instead call start() and stop() before and after starting the reactor. .. _Twisted: http://twistedmatrix.com/trac/ NrF) Ztwisted.internet.reactorZinternetrrorŠr‹Ú_twisted_idle_enabledrŒr²Úmanage_reactorÚ_enable_twisted_idle)r+rrZtwistedrrrr/±szTwistedEventLoop.__init__cCs|j || |¡¡}|SrŽ)rÚ callLaterr¸)r+r„r:rErrrr=Òs zTwistedEventLoop.alarmcCsJddlm}m}z| ¡WdS|y2YdS|yDYdS0dS)r’r)ÚAlreadyCancelledÚ AlreadyCalledTFN)Ztwisted.internet.errorrr Úcancel)r+rErr rrrrCßs  zTwistedEventLoop.remove_alarmcCs.t|j|| |¡ƒ}||j|<|j |¡|Sr–)rþrr¸rŠZ addReader)r+rZr:ZindrrrrTîs ÿ  zTwistedEventLoop.watch_filecCs,||jvr(|j |j|¡|j|=dSdSr™)rŠrZ removeReaderrDrrrrJþs  z"TwistedEventLoop.remove_watch_filecCs |jd7_||j|j<|jSrÌr�r…rrrra s zTwistedEventLoop.enter_idlecCs0|jr dS|j |j|j|jdd�¡d|_dS)aU Twisted's reactors don't have an idle or enter-idle callback so the best we can do for now is to set a timer event in a very short time to approximate an enter-idle callback. .. WARNING:: This will perform worse than the other event loops until we can find a fix or workaround NF)Ú enable_idleT)rrrÚ_idle_emulation_delayr¸Ú_twisted_idle_callbackr3rrrrs  ÿz%TwistedEventLoop._enable_twisted_idlecCs |j ¡D] }|ƒq d|_dSrF)rŒr¡rr…rrrr $sz'TwistedEventLoop._twisted_idle_callbackcCs&z |j|=Wnty YdS0dSržr rDrrrrd)s   z"TwistedEventLoop.remove_enter_idlecCs2|js dS|j ¡|jr.|j}d|_t|ŽdSrÎ)rrr\r²r rÑrrrr\5s zTwistedEventLoop.runcs‡‡‡fdd„}|S)a1 Decorator that cleanly exits the :class:`TwistedEventLoop` if :class:`ExitMainLoop` is thrown inside of the wrapped function. Store the exception info if some other exception occurs, it will be reraised after the loop quits. *f* -- function to be wrapped cs‚d}zˆ|i|¤Ž}WnZty8ˆjr4ˆj ¡Yn:ddl}t| ¡ƒ| ¡ˆ_ˆjrlˆj ¡Yn0ˆr~ˆ  ¡|Sr‰) rrrrfrÓÚprintrÒr²Zcrashr)r©rÔrMrÓ©r rÖr+rrr×Ls   z-TwistedEventLoop.handle_exit..wrapperr)r+rÖr r×rrrr¸Cs zTwistedEventLoop.handle_exit)NT)T)rrrrr r/r=rCrTrJrarr rdr\r¸rrrrr«s !    rc@sdeZdZdZdZdZdd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dZ dd„Zdd„ZdS)ÚAsyncioEventLoopa# Event loop based on the standard library ``asyncio`` module. ``asyncio`` is new in Python 3.4, but also exists as a backport on PyPI for Python 3.3. The ``trollius`` package is available for older Pythons with slightly different syntax, but also works with this loop. Fg¡?cKs,d|vr| d¡|_nddl}| ¡|_dS)NÚloopr)rVr¦ÚasyncioZget_event_loop)r+Úkwargsrrrrr/kszAsyncioEventLoop.__init__cCs|j ||¡S)a Call callback() a given time from now. No parameters are passed to callback. Returns a handle that may be passed to remove_alarm() seconds -- time in seconds to wait before calling callback callback -- function to call from event loop )r¦Ú call_laterrƒrrrr=rs zAsyncioEventLoop.alarmcCs,t|ddƒr| ¡n|j}| }| ¡|S)r’Ú cancelledN)rÞrZ _cancelledr )r+rErZexistedrrrrC~s ÿ ýzAsyncioEventLoop.remove_alarmcCs|j ||¡|Sr–)r¦Z add_readerrYrrrrT�s zAsyncioEventLoop.watch_filecCs |j |¡S)rš)r¦Z remove_readerrDrrrrJšsz"AsyncioEventLoop.remove_watch_filecs0dg‰‡‡‡‡fdd„‰ˆj ˆjˆ¡ˆd<ˆS)r›Ncsˆƒˆj ˆjˆ¡ˆd<dSr‰©r¦rr r©r:Úfaux_idle_callbackZmutable_handler+rrr¬sÿz7AsyncioEventLoop.enter_idle..faux_idle_callbackrrr…rrrra¢s ÿzAsyncioEventLoop.enter_idlecCs| |d¡S)rŸr)rCrDrrrrd¶sz"AsyncioEventLoop.remove_enter_idleNcCsB| d¡}|r4| ¡t|tƒs>t|ƒ||jf|_n | |¡dS)NÚ exception)ÚgetrfÚ isinstancerÚtypeÚ __traceback__r²Zdefault_exception_handler)r+rÚcontextrørrrÚ_exception_handlerÁs   z#AsyncioEventLoop._exception_handlercCs6|j |j¡|j ¡|jr2|j}d|_t|ŽdSrÎ)r¦Zset_exception_handlerrZ run_foreverr²r rÑrrrr\Ës  zAsyncioEventLoop.run)rrrrZ_we_started_event_loopr r/r=rCrTrJrardr²rr\rrrrr_s    r)éérœ)Ú TrioEventLoopFcsG‡‡fdd„dtƒ‰ˆ|ƒS)aO This function is used to test the main loop classes. >>> scr = _refl("screen") >>> scr.function("argument") screen.function('argument') >>> scr.callme(when="now") screen.callme(when='now') >>> scr.want_something_rval = 42 >>> x = scr.want_something() screen.want_something() >>> x 42 cs.eZdZddd„Z‡fdd„Z‡fdd„ZdS) z_refl..ReflectNcSs||_||_dSr0)Ú_nameÚ_rval)r+rßrMrrrr/ïsz_refl..Reflect.__init__csfd dd„|Dƒ¡}|r$|r$|d}|d dd„| ¡Dƒ¡}t|jd|dƒˆr`tƒ‚|jS)Nz, cSsg|] }t|ƒ‘qSr©Úrepr)Ú.0ÚarrrÚ ór5z3_refl..Reflect.__call__..cSs g|]\}}|dt|ƒ‘qS)ú=r%)r'rzÚvrrrr)ör5ú(ú))ÚjoinÚitemsrr#rr$)r+ZarglZargdr©)ÚexitrrÚ__call__òsz_refl..Reflect.__call__csN| d¡rtƒ‚t||dƒr<ˆ|jd|t||dƒƒSˆ|jd|ƒS)Nr$Ú.)ÚendswithÚAttributeErrorr%r#rÞ)r+Úattr)ÚReflectrrràûs  z"_refl..Reflect.__getattr__)N)rrrr/r1ràr©r6r0rrr6îs  r6)rû)rßrMr0rr7rÚ_reflÞsr8cCsddl}| ¡dSr‰)ÚdoctestZtestmod)r9rrrÚ_testsr:Ú__main__)NF)5Z __future__rrr@rpr§rGr†rÓÚ functoolsrÚ itertoolsrÚweakrefrrRÚ ImportErrorZ urwid.utilrr Z urwid.compatr r Zurwid.command_mapr r Z urwid.wimprr rZurwid.display_commonrrIrörrrûrr�r'r¯rØZtwisted.internet.abstractrýrþrrÚ version_infoZ_async_kw_event_loopr"r8r:rrrrrÚs`        `M  5{   &