ó
u~Mc           @   s?  d  Z  d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m	 Z	 d a
 d Z d e f d	     YZ d
 d  Z d Z d e f d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d f  d     YZ e Z e e e e j j d  Z d   Z d d l Z d S(   s9   
Asynchronous-friendly error mechanism.

See L{Failure}.
i˙˙˙˙N(   t   StringIO(   t   getmro(   t   reflecti    i   t   DefaultExceptionc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR      s   t   defaultc         C   s  | d k r t  d | f  n  | } | d k rk xY|  D], \ } } } } } | d | | | f  q8 Wn"| d k rŃ x|  D]L \ } } } } } | d | | | f  | d t j | |  j    q~ Wnź | d k rx­ |  D]˘ \ } } } } } | d | | | f  | d	  x. | D]& \ }	 }
 | d
 |	 t |
  f  q!W| d  x. | D]& \ }	 }
 | d
 |	 t |
  f  q\Wqä Wn  d S(   sľ  Format and write frames.

    @param frames: is a list of frames as used by Failure.frames, with
        each frame being a list of
        (funcName, fileName, lineNumber, locals.items(), globals.items())
    @type frames: list
    @param write: this will be called with formatted strings.
    @type write: callable
    @param detail: Three detail levels are available:
        default, brief, and verbose.
    @type detail: string
    R   t   brieft   verboses3   Detail must be default, brief, or verbose. (not %r)s	   %s:%s:%s
s     File "%s", line %s, in %s
s       %s
s   %s:%d: %s(...)
s    [ Locals ]
s
     %s : %s
s    ( Globals )
N(   s   defaultR   s   verbose(   t
   ValueErrort	   linecachet   getlinet   stript   repr(   t   framest   writet   detailt   wt   methodt   filenamet   linenot	   localVarst
   globalVarst   namet   val(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   format_frames   s&    '

s   --- <exception caught here> ---t   NoCurrentExceptionErrorc           B   s   e  Z d  Z RS(   s   
    Raised when trying to create a Failure from the current interpreter
    exception state and there is no current exception state.
    (   R   R   t   __doc__(    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR   F   s   t
   _Tracebackc           B   s   e  Z d  Z d   Z RS(   sq   
    Fake traceback object which can be passed to functions in the standard
    library L{traceback} module.
    c         C   s   t  |  d k s t d  | d | d } } | \ } } } } } t | |  |  _ | |  _ t  |  d k r~ d |  _ n t |  |  _ d S(   s]  
        Construct a fake traceback object using a list of frames. Note that
        although frames generally include locals and globals, this information
        is not kept by this object, since locals and globals are not used in
        standard tracebacks.

        @param frames: [(methodname, filename, lineno, locals, globals), ...]
        i    s   Must pass some framesi   N(   t   lent   AssertionErrort   _Framet   tb_framet	   tb_linenot   Nonet   tb_nextR   (   t   selfR   t   headR   R   R   t   localzt   globalz(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   __init__S   s    		(   R   R   R   R(   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR   M   s   R   c           B   s   e  Z d  Z d   Z RS(   sč   
    A fake frame object, used by L{_Traceback}.

    @ivar f_code: fake L{code<types.CodeType>} object
    @ivar f_globals: fake f_globals dictionary (usually empty)
    @ivar f_locals: fake f_locals dictionary (usually empty)
    c         C   s(   t  | |  |  _ i  |  _ i  |  _ d S(   sŤ   
        @param name: method/function name for this frame.
        @type name: C{str}
        @param filename: filename for this frame.
        @type name: C{str}
        N(   t   _Codet   f_codet	   f_globalst   f_locals(   R$   R   R   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR(   p   s    	(   R   R   R   R(   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR   g   s   R)   c           B   s   e  Z d  Z d   Z RS(   sB   
    A fake code object, used by L{_Traceback} via L{_Frame}.
    c         C   s   | |  _  | |  _ d  S(   N(   t   co_namet   co_filename(   R$   R   R   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR(      s    	(   R   R   R   R(   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR)   |   s   t   Failurec           B   sö   e  Z d  Z d Z d Z e e j d  Z	 d d d d  Z
 d   Z d   Z d   Z d   Z d   Z e e  Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d d d  Z d e d d  Z d d d  Z d d d  Z RS(   s"  
    A basic abstraction for an error that has occurred.

    This is necessary because Python's built-in error mechanisms are
    inconvenient for asynchronous communication.

    @ivar value: The exception instance responsible for this failure.
    @ivar type: The exception's class.
    i    t   YIELD_VALUEc      	   C   ső  t  d a  t  |  _  d |  _ |  _ } t | t t f  r} | d k r} d d l } | j d | t	 d d t
 |  } n  d } | d k r |  j   } n  | d k ré t j   \ |  _ |  _ } |  j d k rŕ t    n  d } nW | d k r.t | t  r| j |  _ n t |  |  _ | |  _ n | |  _ | |  _ t |  j t  re|  j j |  _ d S| d k r| r| } qn  g  } |  _ g  } |  _ | |  _ | r¸| j }	 n t |  j t  s×d }	 } n  x# | rü|	 rü|	 j }	 | d 8} qÚWxś |	 rľ|	 j j   }
 |	 j |	 j k r0i  } n |	 j j   } x- | |
 f D] } | j d  rL| d =qLqLW| j d |	 j j |	 j j |	 j  |
 j!   | j!   g  |	 j }	 q WxÂ | d k	 rz| j }	 |	 j j   }
 |	 j |	 j k rři  } n |	 j j   } x- | |
 f D] } | j d  r| d =qqW| j" |	 j j |	 j j | j# |
 j!   | j!   g  | j$ } qšWt% j& |  j  rât' |  j t  rât( |  j  } t) t* j+ |  |  _, |  j, j" t* j+ |  j   n |  j g |  _, d S(	   s_  
        Initialize me with an explanation of the error.

        By default, this will use the current C{exception}
        (L{sys.exc_info}()).  However, if you want to specify a
        particular kind of failure, you can pass an exception as an
        argument.

        If no C{exc_value} is passed, then an "original" C{Failure} will
        be searched for. If the current exception handler that this
        C{Failure} is being constructed in is handling an exception
        raised by L{raiseException}, then this C{Failure} will act like
        the original C{Failure}.

        For C{exc_tb} only L{traceback} instances or C{None} are allowed.
        If C{None} is supplied for C{exc_value}, the value of C{exc_tb} is
        ignored, otherwise if C{exc_tb} is C{None}, it will be found from
        execution context (ie, L{sys.exc_info}).
        i   i˙˙˙˙NsT   Don't pass strings (like %r) to failure.Failure (replacing with a DefaultException).t
   stackleveli   i    t   __builtins__(-   t   countR"   t   typet   valuet
   isinstancet   strt   unicodet   warningst   warnt   DeprecationWarningR   t   _findFailuret   syst   exc_infoR   t	   Exceptiont	   __class__R/   t   __dict__R   t   stackt   tbR    t   f_backR,   t   copyR+   t   has_keyt   insertR*   R-   R.   t   f_linenot   itemst   appendR!   R#   t   inspectt   isclasst
   issubclassR   t   mapR   t   qualt   parents(   R$   t	   exc_valuet   exc_typet   exc_tbRC   R9   t   stackOffsetR   RB   t   fR&   R'   t   dt   parentCs(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR(      s    
	!					
											$c         G   s"   |  j  |   } | s |   n  | S(   s  Trap this failure if its type is in a predetermined list.

        This allows you to trap a Failure in an error callback.  It will be
        automatically re-raised if it is not a type that you expect.

        The reason for having this particular API is because it's very useful
        in Deferred errback chains::

            def _ebFoo(self, failure):
                r = failure.trap(Spam, Eggs)
                print 'The Failure is due to either Spam or Eggs!'
                if r == Spam:
                    print 'Spam did it!'
                elif r == Eggs:
                    print 'Eggs did it!'

        If the failure is not a Spam or an Eggs, then the Failure
        will be 'passed on' to the next errback.

        @type errorTypes: L{Exception}
        (   t   check(   R$   t
   errorTypest   error(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   trap"  s    	c         G   s^   xW | D]O } | } t  j |  rC t | t  rC t j |  } n  | |  j k r | Sq Wd S(   sú   Check if this failure's type is in a predetermined list.

        @type errorTypes: list of L{Exception} classes or
                          fully-qualified class names.
        @returns: the matching L{Exception} type, or None if no match.
        N(   RK   RL   RM   R?   R   RO   RP   R"   (   R$   RY   RZ   t   err(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyRX   =  s    c         C   s   |  j  |  j |  j  d S(   sf   
        raise the original exception, preserving traceback
        information if available.
        N(   R4   R5   RC   (   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   raiseExceptionM  s    c         C   s   | j  |  j |  j |  j  S(   sJ  
        Throw the original exception into the given generator,
        preserving traceback information if available.

        @return: The next value yielded from the generator.
        @raise StopIteration: If there are no more values in the generator.
        @raise anything else: Anything that the generator raises.
        (   t   throwR4   R5   RC   (   R$   t   g(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   throwExceptionIntoGeneratorU  s    	c         C   s  t  j   d } | s d Sd } | } x | j rD | } | j } q) W| j } | j |  j j k rs | j j	 d  S| j j
 s | j j
 | j |  j k r  d S| r× | j } | j |  j j k r× | j j	 d  Sn  | j j } | r| j |  j j k r| j j	 d  Sd S(   sV   
        Find the failure that represents the exception currently in context.
        i˙˙˙˙NR$   (   R=   R>   R"   R#   R    R*   R]   t	   func_codeR,   t   gett   co_codet   tb_lastit   _yieldOpcodeR`   RD   (   t   clsRC   t   secondLastTbt   lastTbt	   lastFramet   frame(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR<   a  s*    			c         C   s   d |  j  |  j f S(   Ns   <%s %s>(   R@   R4   (   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   __repr__  s    c         C   s   d |  j    S(   Ns   [Failure instance: %s](   t   getBriefTraceback(   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   __str__  s    c         C   sw  |  j  r |  j S|  j j   } g  |  j D] } | d | d | d g  | d D]# } | d t j | d  f ^ qO g  | d D]# } | d t j | d  f ^ q g ^ q) | d <d
 | d <|  j d
 k	 rig  |  j D] } | d | d | d g  | d D]# } | d t j | d  f ^ q˙ g  | d D]# } | d t j | d  f ^ q0g ^ qŮ | d <n  d | d	 <| S(   s1   Avoid pickling objects in the traceback.
        i    i   i   i   i   R   RC   RB   t   pickledN(   Rn   RA   RE   R   R   t	   safe_reprR"   RB   (   R$   t   ct   vt   j(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   __getstate__Ą  s    	

c         C   s   |  j    |  _ d S(   sI   Remove references to other objects, replacing them with strings.
        N(   Rs   RA   (   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   cleanFailureÁ  s    c         C   s@   |  j  d k	 r |  j  St |  j  d k r8 t |  j  Sd Sd S(   s  
        Get an object that represents this Failure's stack that can be passed
        to traceback.extract_tb.

        If the original traceback object is still present, return that. If this
        traceback object has been lost but we still have the information,
        return a fake traceback object (see L{_Traceback}). If there is no
        traceback information at all, return None.
        i    N(   RC   R"   R   R   R   (   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   getTracebackObjectĆ  s
    
c         C   s/   t  |  j t  r |  j j   St j |  j  S(   s8   Get a string of the exception which caused this Failure.(   R6   R5   R/   t   getErrorMessageR   t   safe_str(   R$   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyRv   ×  s    c         C   s#   t    } |  j d |  | j   S(   Nt   file(   R    t   printBriefTracebackt   getvalue(   R$   t   io(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyRl   Ý  s    	R   c         C   s/   t    } |  j d | d | d |  | j   S(   NRx   t   elideFrameworkCodeR   (   R    t   printTracebackRz   (   R$   R|   R   R{   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   getTracebackâ  s    	c         C   să  | d k r t j } n  | j } | d k rV | d |  j |  j rH d pK d f  n` | d k rŹ |  j rt d } n d } | d | t j |  j	  t j |  j
  f  n
 | d	  |  j r| sń t |  j t | |  | d
 t f  n  t |  j | |  n | d k s | d  n  | d k st |  j	 t t f  rX| |  j	 d  q| d t j |  j	  t j |  j
  f  n  t |  j
 t  rż| j d  |  j
 j | | |  n  | d k rß| d |  j  n  d S(   s  
        Emulate Python's standard error reporting mechanism.

        @param file: If specified, a file-like object to which to write the
            traceback.

        @param elideFrameworkCode: A flag indicating whether to attempt to
            remove uninteresting frames from within Twisted itself from the
            output.

        @param detail: A string indicating how much information to include
            in the traceback.  Must be one of C{'brief'}, C{'default'}, or
            C{'verbose'}.
        R   s   *--- Failure #%d%s---
s    (pickled) t    R   t	   Tracebacks"   Traceback (failure with no frames)s   %s: %s: %s
s#   Traceback (most recent call last):
s   %s
s	   Failure: s   
s   %s: %s
s    (chained Failure)
s   *--- End of Failure #%d ---
N(   R"   t   logt   logerrR   R3   Rn   R   R   Rw   R4   R5   R   RB   t   traceupLengtht   EXCEPTION_CAUGHT_HERER6   R7   R8   RO   R/   R}   (   R$   Rx   R|   R   R   t	   hasFrames(    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR}   č  sB    			
	c         C   s   |  j  | | d d d S(   s2   Print a traceback as densely as possible.
        R   R   N(   R}   (   R$   Rx   R|   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyRy   +  s    c         C   s   |  j  | | d d d S(   sH   Print a traceback with detailed locals and globals information.
        R   R   N(   R}   (   R$   Rx   R|   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   printDetailedTraceback0  s    N(   R   R   R   Rn   R"   RB   t   chrt   opcodet   opmapRe   R(   R[   RX   R]   R`   R<   t   classmethodRk   Rm   Rs   Rt   Ru   Rv   Rl   R~   t   FalseR}   Ry   R   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyR/      s,   						8			 				Cc         C   sĽ   | | | f d k r t j   } | d |  j k r t r y t | d  } Wn d } n Xd | f GHd d l } | j | d  q n  | |  | | |  d S(	   s;   
    Initialize failure object, possibly spawning pdb.
    i    i   s
   broken strs8   Jumping into debugger for post-mortem of exception '%s':i˙˙˙˙Ni   (   NNN(   R"   R=   R>   R@   t   DO_POST_MORTEMR7   t   pdbt   post_mortem(   R$   RQ   RR   RS   t   Failure__init__t   exct   strreprR   (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt
   _debuginit9  s    
c           C   s   t  t _ d S(   s    Enable debug hooks for Failures.N(   R   R/   R(   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   startDebugModeJ  s    (   R   R=   R
   RK   R   t	   cStringIOR    R   t   twisted.pythonR   R3   R   R?   R   R   R   R   t   objectR   R   R)   R/   t   TrueR   R"   R(   t   im_funcR   R   R   (    (    (    s:   /usr/lib/python2.7/dist-packages/twisted/python/failure.pyt   <module>   s.   $	˙ ł		