a ‚oeã@sdZddlZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z ddlm Z dd lm Z dd lmZdd lmZdd lmZe e¡Zejd krîejgZejejejejfD]Ze e¡ejkrÌe  e¡qÌngZGdd„dƒZ!Gdd„de!ƒZ"dS)zBRegisters functions to be called if an exception or signal occurs.éN)Ú TracebackType)ÚAny)ÚCallable)ÚDict)ÚList)ÚOptional)ÚType)ÚUnion)Úerrors)ÚosÚntc@sÄeZdZdZedefeeddœdd„Zddœdd „Zee e ee ee e d œd d „Z edefeeddœd d„Zddœdd„Zddœdd„Zddœdd„Zeeddœdd„Zddœdd„ZdS)Ú ErrorHandleraGContext manager for running code that must be cleaned up on failure. The context manager allows you to register functions that will be called when an exception (excluding SystemExit) or signal is encountered. Usage:: handler = ErrorHandler(cleanup1_func, *cleanup1_args, **cleanup1_kwargs) handler.register(cleanup2_func, *cleanup2_args, **cleanup2_kwargs) with handler: do_something() Or for one cleanup function:: with ErrorHandler(func, args, kwargs): do_something() If an exception is raised out of do_something, the cleanup functions will be called in last in first out order. Then the exception is raised. Similarly, if a signal is encountered, the cleanup functions are called followed by the previously received signal handler. Each registered cleanup function is called exactly once. If a registered function raises an exception, it is logged and the next function is called. Signals received while the registered functions are executing are deferred until they finish. .N©ÚfuncÚargsÚkwargsÚreturncOsBd|_d|_g|_i|_g|_|dur>|j|g|¢Ri|¤ŽdS©NF)Úcall_on_regular_exitÚ body_executedÚfuncsÚ prev_handlersÚreceived_signalsÚregister©Úselfrrr©rú@C:\Program Files\Certbot\pkgs\certbot\_internal\error_handler.pyÚ__init__PszErrorHandler.__init__)rcCsd|_| ¡dSr)rÚ_set_signal_handlers)rrrrÚ __enter__YszErrorHandler.__enter__)Ú exec_typeÚ exec_valueÚtracerc Cs€d|_d}|tur|S|dur*|jsd|Sn:|tjurHt d|j¡d}nt dd t   |||¡¡¡|  ¡|  ¡|  ¡|S)NTFzEncountered signals: %szEncountered exception: %sÚ)rÚ SystemExitrr Ú SignalExitÚloggerÚdebugrÚjoinÚ tracebackÚformat_exceptionÚ_call_registeredÚ_reset_signal_handlersÚ _call_signals)rr!r"r#ZretvalrrrÚ__exit__]s"   ÿzErrorHandler.__exit__cOs$|j tj|g|¢Ri|¤Ž¡dS)z�Sets func to be run with the given arguments during cleanup. :param function func: function to be called in case of an error N)rÚappendÚ functoolsÚpartialrrrrrtszErrorHandler.registerc Cs|t d¡|jrxz|jdƒWnJtyj}z2t t|ƒ|¡}t dd |¡  ¡¡WYd}~n d}~00|j  ¡q dS)zCalls all registered functionszCalling registered functionséÿÿÿÿz)Encountered exception during recovery: %sr$N) r'r(rÚ Exceptionr*Úformat_exception_onlyÚtypeÚerrorr)ÚrstripÚpop)rÚexcÚoutputrrrr,|s  ÿzErrorHandler._call_registeredcCs8tD].}t |¡}|dur||j|<t ||j¡qdS)z-Sets signal handlers for signals in _SIGNALS.N)Ú_SIGNALSÚsignalÚ getsignalrÚ_signal_handler)rÚsignumZ prev_handlerrrrrˆs   z!ErrorHandler._set_signal_handlerscCs.|j ¡D]\}}t ||¡q |j ¡dS)z/Resets signal handlers for signals in _SIGNALS.N)rÚitemsr=Úclear)rr@Zhandlerrrrr-‘sz#ErrorHandler._reset_signal_handlers)r@Ú unused_framercCs|j |¡|jstj‚dS)aReplacement function for handling received signals. Store the received signal. If we are executing the code block in the body of the context manager, stop by raising signal exit. :param int signum: number of current signal N)rr0rr r&)rr@rCrrrr?—s zErrorHandler._signal_handlercCs,|jD] }t d|¡t t ¡|¡qdS)z"Finally call the deferred signals.zCalling signal %sN)rr'r(r ÚkillÚgetpid)rr@rrrr.¤s  zErrorHandler._call_signals)Ú__name__Ú __module__Ú __qualname__Ú__doc__rrrr rrÚ BaseExceptionrÚboolr/rr,rr-Úintr?r.rrrrr 3s  þ    r cs4eZdZdZedefeeddœ‡fdd„ Z‡ZS)Ú ExitHandlerzÔContext manager for running code that must be cleaned up. Subclass of ErrorHandler, with the same usage and parameters. In addition to cleaning up on all signals, also cleans up on regular exit. .Nrcs$tƒj|g|¢Ri|¤Žd|_dS)NT)Úsuperrrr©Ú __class__rrr²szExitHandler.__init__)rFrGrHrIrrrÚ __classcell__rrrOrrM«srM)#rIr1Zloggingr=r*ÚtypesrÚtypingrrrrrrr Zcertbotr Zcertbot.compatr Z getLoggerrFr'ÚnameÚSIGTERMr<ZSIGHUPZSIGQUITZSIGXCPUZSIGXFSZZ signal_coder>ÚSIG_IGNr0r rMrrrrÚs2            ÿx