Yf0@sdZddlZddlmZddlmZddddd d d gZGd ddeZGd ddeZ ddZ GdddeZ GdddZ Gdd d e Z Gdd d e ZGdd d ZGdddeZdS)z4Utilities for with-statement contexts. See PEP 343.N)deque)wrapscontextmanagerclosingContextDecorator ExitStackredirect_stdoutredirect_stderrsuppressc@s.eZdZdZddZddZdS)rzJA base class or mixin that enables context managers to work as decorators.cCs|S)a6Return a recreated instance of self. Allows an otherwise one-shot context manager like _GeneratorContextManager to support use as a decorator via implicit recreation. This is a private interface just for _GeneratorContextManager. See issue #11647 for details. )selfr r //opt/alt/python35/lib64/python3.5/contextlib.py _recreate_cms zContextDecorator._recreate_cmcs%tfdd}|S)Nc s%j||SWdQRXdS)N)r)argskwds)funcr r r inners z(ContextDecorator.__call__..inner)r)r rrr )rr r __call__s!zContextDecorator.__call__N)__name__ __module__ __qualname____doc__rrr r r r r s  c@sFeZdZdZddZddZddZdd Zd S) _GeneratorContextManagerz%Helper for @contextmanager decorator.cCsi||||_||||_|_|_t|dd}|dkr\t|j}||_dS)Nr)genrrrgetattrtyper)r rrrdocr r r __init__%s  z!_GeneratorContextManager.__init__cCs|j|j|j|jS)N) __class__rrr)r r r r r3sz%_GeneratorContextManager._recreate_cmc Cs9yt|jSWn!tk r4tddYnXdS)Nzgenerator didn't yield)nextr StopIteration RuntimeError)r r r r __enter__9s z"_GeneratorContextManager.__enter__cCs0|dkrEyt|jWntk r5dSYq,Xtdn|dkrZ|}y|jj|||Wntk r}z||k SWYdd}~Xn{tk r}z7||krdS|tkr|j|krdSWYdd}~Xn%tjd|krdSYnXtddS)NFzgenerator didn't stopz#generator didn't stop after throw())rrr r!throw __cause__sysexc_info)r rvalue tracebackexcr r r __exit__?s.      z!_GeneratorContextManager.__exit__N)rrrrrrr"r+r r r r r"s    rcs"tfdd}|S)a@contextmanager decorator. Typical usage: @contextmanager def some_generator(): try: yield finally: This makes this: with some_generator() as : equivalent to this: try: = finally: cst||S)N)r)rr)rr r helperszcontextmanager..helper)r)rr,r )rr rksc@s:eZdZdZddZddZddZdS) ra2Context to automatically close something at the end of a block. Code like this: with closing(.open()) as f: is equivalent to this: f = .open() try: finally: f.close() cCs ||_dS)N)thing)r r-r r r rszclosing.__init__cCs|jS)N)r-)r r r r r"szclosing.__enter__cGs|jjdS)N)r-close)r r'r r r r+szclosing.__exit__N)rrrrrr"r+r r r r rs   c@s:eZdZdZddZddZddZdS)_RedirectStreamNcCs||_g|_dS)N) _new_target _old_targets)r new_targetr r r rs z_RedirectStream.__init__cCs9|jjtt|jtt|j|j|jS)N)r1appendrr&_streamsetattrr0)r r r r r"sz_RedirectStream.__enter__cCs tt|j|jjdS)N)r5r&r4r1pop)r exctypeexcinstexctbr r r r+sz_RedirectStream.__exit__)rrrr4rr"r+r r r r r/s   r/c@seZdZdZdZdS)raAContext manager for temporarily redirecting stdout to another file. # How to send help() to stderr with redirect_stdout(sys.stderr): help(dir) # How to write help() to a file with open('help.txt', 'w') as f: with redirect_stdout(f): help(pow) stdoutN)rrrrr4r r r r rs c@seZdZdZdZdS)r zCContext manager for temporarily redirecting stderr to another file.stderrN)rrrrr4r r r r r s c@s:eZdZdZddZddZddZdS) r a?Context manager to suppress specified exceptions After the exception is suppressed, execution proceeds with the next statement following the with statement. with suppress(FileNotFoundError): os.remove(somefile) # Execution still resumes here if the file was already removed cGs ||_dS)N) _exceptions)r exceptionsr r r rszsuppress.__init__cCsdS)Nr )r r r r r"szsuppress.__enter__cCs|dk ot||jS)N) issubclassr<)r r7r8r9r r r r+s zsuppress.__exit__N)rrrrrr"r+r r r r r s   c@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS)raContext manager for dynamic management of a stack of exit callbacks For example: with ExitStack() as stack: files = [stack.enter_context(open(fname)) for fname in filenames] # All opened files will automatically be closed at the end of # the with statement, even if attempts to open files later # in the list raise an exception cCst|_dS)N)r_exit_callbacks)r r r r rszExitStack.__init__cCs+t|}|j|_t|_|S)z?Preserve the context stack by transferring it to a new instance)rr?r)r new_stackr r r pop_alls  zExitStack.pop_allcs/fdd}|_|j|dS)z:Helper to correctly register callbacks to __exit__ methodscs |S)Nr ) exc_details)cmcm_exitr r _exit_wrappersz.ExitStack._push_cm_exit.._exit_wrapperN)__self__push)r rCrDrEr )rCrDr _push_cm_exits zExitStack._push_cm_exitc CsRt|}y |j}Wn"tk r=|jj|YnX|j|||S)aRegisters a callback with the standard __exit__ method signature Can suppress exceptions the same way __exit__ methods can. Also accepts any object with an __exit__ method (registering a call to the method instead of the object itself) )rr+AttributeErrorr?r3rH)r exit_cb_type exit_methodr r r rG s   zExitStack.pushcs2fdd}|_|j|S)z\Registers an arbitrary callback and arguments. Cannot suppress exceptions. csdS)Nr )exc_typer*tb)rcallbackrr r rE#sz)ExitStack.callback.._exit_wrapper) __wrapped__rG)r rOrrrEr )rrOrr rOs  zExitStack.callbackcCs8t|}|j}|j|}|j|||S)zEnters the supplied context manager If successful, also pushes its __exit__ method as a callback and returns the result of the __enter__ method. )rr+r"rH)r rC_cm_type_exitresultr r r enter_context+s   zExitStack.enter_contextcCs|jddddS)z$Immediately unwind the context stackN)r+)r r r r r.8szExitStack.closecCs|S)Nr )r r r r r"<szExitStack.__enter__c s|ddk }tjdfdd}d}d}xv|jr|jj}y"||rzd}d}d}WqAtj}||d|dd}|}YqAXqAW|ry|dj}|dWn"tk r||d_YnX|o|S)Nrr#csLx<|j}||krdS|dks4|kr5P|}qW||_dS)N) __context__)new_excold_exc exc_context) frame_excr r _fix_exception_contextEs   z2ExitStack.__exit__.._fix_exception_contextFT)NNN)r&r'r?r6rU BaseException) r rB received_excrZsuppressed_exc pending_raisecbnew_exc_details fixed_ctxr )rYr r+?s2       zExitStack.__exit__N) rrrrrrArHrGrOrTr.r"r+r r r r rs       )rr& collectionsr functoolsr__all__objectrrrrr/rr r rr r r r s  I "