
[[\-                 @   s   d  Z  d d l Z d d l m Z d d l m Z d d d d d	 d
 g Z Gd d   d e  Z Gd d   d e  Z	 d d   Z
 Gd d   d e  Z Gd d	   d	  Z Gd d
   d
  Z Gd d   d e  Z d S)z4Utilities for with-statement contexts.  See PEP 343.    N)deque)wrapscontextmanagerclosingContextDecorator	ExitStackredirect_stdoutsuppressc               @   s.   e  Z d  Z d Z d d   Z d d   Z d S)r   zJA base class or mixin that enables context managers to work as decorators.c             C   s   |  S)a6  Return 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
    /usr/lib/python3.4/contextlib.py_recreate_cm   s    
zContextDecorator._recreate_cmc                s%   t        f d d    } | S)Nc           
      s$    j       |  |   SWd  QXd  S)N)r   )argskwds)funcr   r
   r   inner   s    z(ContextDecorator.__call__.<locals>.inner)r   )r   r   r   r
   )r   r   r   __call__   s    !zContextDecorator.__call__N)__name__
__module____qualname____doc__r   r   r
   r
   r
   r   r      s   c               @   sF   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 S)_GeneratorContextManagerz%Helper for @contextmanager decorator.c             O   sl   | | |   |  _  | | | |  _ |  _ |  _ t | d d   } | d  k r_ t |   j } n  | |  _ d  S)Nr   )genr   r   r   getattrtyper   )r   r   r   r   docr
   r
   r   __init__%   s    z!_GeneratorContextManager.__init__c             C   s   |  j  |  j |  j |  j  S)N)	__class__r   r   r   )r   r
   r
   r   r   3   s    z%_GeneratorContextManager._recreate_cmc             C   s9   y t  |  j  SWn! t k
 r4 t d  d   Yn Xd  S)Nzgenerator didn't yield)nextr   StopIterationRuntimeError)r   r
   r
   r   	__enter__9   s    z"_GeneratorContextManager.__enter__c             C   s   | d  k rE y t  |  j  Wn t k
 r5 d  SYq Xt d   n | d  k r] |   } n  y& |  j j | | |  t d   WnR t k
 r } z | | k	 SWYd  d  } ~ Xn$ t j   d | k	 r   n  Yn Xd  S)Nzgenerator didn't stopz#generator didn't stop after throw()   )r   r   r   r    throwsysexc_info)r   r   value	tracebackexcr
   r
   r   __exit__?   s     	z!_GeneratorContextManager.__exit__N)r   r   r   r   r   r   r!   r)   r
   r
   r
   r   r   "   s
   r   c                s"   t       f d d    } | S)a  @contextmanager decorator.

    Typical usage:

        @contextmanager
        def some_generator(<arguments>):
            <setup>
            try:
                yield <value>
            finally:
                <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    c                 s   t    |  |  S)N)r   )r   r   )r   r
   r   helper|   s    zcontextmanager.<locals>.helper)r   )r   r*   r
   )r   r   r   `   s    c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	r   a2  Context to automatically close something at the end of a block.

    Code like this:

        with closing(<module>.open(<arguments>)) as f:
            <block>

    is equivalent to this:

        f = <module>.open(<arguments>)
        try:
            <block>
        finally:
            f.close()

    c             C   s   | |  _  d  S)N)thing)r   r+   r
   r
   r   r      s    zclosing.__init__c             C   s   |  j  S)N)r+   )r   r
   r
   r   r!      s    zclosing.__enter__c             G   s   |  j  j   d  S)N)r+   close)r   r%   r
   r
   r   r)      s    zclosing.__exit__N)r   r   r   r   r   r!   r)   r
   r
   r
   r   r      s   c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	r   a@  Context 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)
    c             C   s   | |  _  g  |  _ d  S)N)_new_target_old_targets)r   
new_targetr
   r
   r   r      s    	zredirect_stdout.__init__c             C   s&   |  j  j t j  |  j t _ |  j S)N)r.   appendr$   stdoutr-   )r   r
   r
   r   r!      s    zredirect_stdout.__enter__c             C   s   |  j  j   t _ d  S)N)r.   popr$   r1   )r   exctypeexcinstexctbr
   r
   r   r)      s    zredirect_stdout.__exit__N)r   r   r   r   r   r!   r)   r
   r
   r
   r   r      s   c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	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
    c             G   s   | |  _  d  S)N)_exceptions)r   
exceptionsr
   r
   r   r      s    zsuppress.__init__c             C   s   d  S)Nr
   )r   r
   r
   r   r!      s    zsuppress.__enter__c             C   s   | d  k	 o t  | |  j  S)N)
issubclassr6   )r   r3   r4   r5   r
   r
   r   r)      s    
zsuppress.__exit__N)r   r   r   r   r   r!   r)   r
   r
   r
   r   r	      s   	c               @   s   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z d d   Z	 d d   Z
 d d   Z d d   Z d S)r   a  Context 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

    c             C   s   t    |  _ d  S)N)r   _exit_callbacks)r   r
   r
   r   r      s    zExitStack.__init__c             C   s+   t  |     } |  j | _ t   |  _ | S)z?Preserve the context stack by transferring it to a new instance)r   r9   r   )r   	new_stackr
   r
   r   pop_all   s    zExitStack.pop_allc                s/      f d d   }   | _  |  j |  d S)z:Helper to correctly register callbacks to __exit__ methodsc                 s      |   S)Nr
   )exc_details)cmcm_exitr
   r   _exit_wrapper   s    z.ExitStack._push_cm_exit.<locals>._exit_wrapperN)__self__push)r   r=   r>   r?   r
   )r=   r>   r   _push_cm_exit   s    	zExitStack._push_cm_exitc             C   sR   t  |  } y | j } Wn" t k
 r= |  j j |  Yn X|  j | |  | S)a  Registers 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)
        )r   r)   AttributeErrorr9   r0   rB   )r   exit_cb_typeexit_methodr
   r
   r   rA      s    
zExitStack.pushc                s2       f d d   }  | _  |  j |   S)z\Registers an arbitrary callback and arguments.

        Cannot suppress exceptions.
        c                s         d  S)Nr
   )exc_typer(   tb)r   callbackr   r
   r   r?   
  s    z)ExitStack.callback.<locals>._exit_wrapper)__wrapped__rA   )r   rI   r   r   r?   r
   )r   rI   r   r   rI     s    	zExitStack.callbackc             C   s8   t  |  } | 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.
        )r   r)   r!   rB   )r   r=   _cm_type_exitresultr
   r
   r   enter_context  s
    	zExitStack.enter_contextc             C   s   |  j  d d d  d S)z$Immediately unwind the context stackN)r)   )r   r
   r
   r   r,     s    zExitStack.closec             C   s   |  S)Nr
   )r   r
   r
   r   r!   #  s    zExitStack.__enter__c       	         s  | d d  k	 } t  j   d     f d d   } d } d } xy |  j r |  j j   } y% | |   r} d } d } d } n  WqA t  j   } | | d | d  d } | } YqA XqA W| ry | d j } | d  Wqt k
 r | | d _   YqXn  | o| S)Nr   r"   c                sN   x> |  j  } | | k r d  S| d  k s4 |   k r8 Pn  | }  q | |  _  d  S)N)__context__)new_excold_excexc_context)	frame_excr
   r   _fix_exception_context,  s    		z2ExitStack.__exit__.<locals>._fix_exception_contextFT)NNN)r$   r%   r9   r2   rO   BaseException)	r   r<   received_excrT   suppressed_excpending_raisecbnew_exc_details	fixed_ctxr
   )rS   r   r)   &  s2    zExitStack.__exit__N)r   r   r   r   r   r;   rB   rA   rI   rN   r,   r!   r)   r
   r
   r
   r   r      s   )r   r$   collectionsr   	functoolsr   __all__objectr   r   r   r   r   r	   r   r
   r
   r
   r   <module>   s   >"