
    Ϫfm                     p   d Z ddl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
mZmZ ddlZddlmZ  ede
def   	      Zdad
Z G d de      Zd"dZdZ G d de      Zd Z G d d      Z G d d      Z G d d      Zg ZdedefdZ G d de      Z d Z!dZ"dddde jF                  fd Z$d! Z%y)#z9
Asynchronous-friendly error mechanism.

See L{Failure}.
    N)getmro)StringIO)CallableNoReturnTypeVar)reflect_T_Callable.)bound   c                       e Zd Zy)DefaultExceptionN)__name__
__module____qualname__     8/usr/lib/python3/dist-packages/twisted/python/failure.pyr   r   #   s    r   r   c           
      V   |dvrt        d|d      |}|dk(  r| D ]  \  }}}}} || d| d| d        y|dk(  rM| D ]G  \  }}}}} |d| d	| d
| d        |dt        j                  ||      j                         z         I y|dk(  r$| D ]  \  }}}}} |d|||fz           |d       y|dk(  rp| D ]j  \  }}}}} |d|||fz          |d       |D ]  \  }	}
 |d|	 dt	        |
       d         |d       |D ]  \  }	}
 |d|	 dt	        |
       d        l yy)a  
    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: Four detail levels are available:
        default, brief, verbose, and verbose-vars-not-captured.
        C{Failure.printDetailedTraceback} uses the latter when the caller asks
        for verbose, but no vars were captured, so that an explicit warning
        about the missing data is shown.
    @type detail: string
    )defaultbriefverboseverbose-vars-not-capturedzKDetail must be default, brief, verbose, or verbose-vars-not-captured. (not )r   :
r   z  File "z", line z, in z    %s
r   z%s:%d: %s(...)
zA [Capture of Locals and Globals disabled (use captureVars=True)]
r   z [ Locals ]
z  z : z ( Globals )
N)
ValueError	linecachegetlinestriprepr)frameswritedetailwmethodfilenamelineno	localVars
globalVarsnamevals              r   format_framesr,   '   s   " QQ5;>
 	
 	A?E 	1;FHfi
!F81VHB/0	1	9	?E 	H;FHfi
(6(%xrBCj9,,Xv>DDFFG	H 
.	.?E 	?;FHfi Hff#==>	?	
NO	9	?E 	/;FHfi Hff#==>o& /	cBtfCS	{"-./' /	cBtfCS	{"-./	/ 
r   z--- <exception caught here> ---c                       e Zd ZdZy)NoCurrentExceptionErrorz
    Raised when trying to create a Failure from the current interpreter
    exception state and there is no current exception state.
    N)r   r   r   __doc__r   r   r   r.   r.   Z   s    r   r.   c                     t        |      dkD  sJ d       d}| D ]  }t        ||      } t        |d   |      }t        |      x}}|dd D ]*  }t        ||      }t        |      |_        |j                  }, |S )a5  
    Construct a fake traceback object using a list of frames.

    It should have the same API as stdlib to allow interaction with
    other tools.

    @param stackFrames: [(methodname, filename, lineno, locals, globals), ...]
    @param tbFrames: [(methodname, filename, lineno, locals, globals), ...]
    r   zMust pass some framesN   )len_Frame_TracebackFrametb_next)stackFramestbFramesstacksffirstTbtbs         r   
_Tracebackr<   a   s     x=1555 E "r5!" 8A;&E"5))Gbqrl r5!$U+
ZZ Nr   c                       e Zd ZdZd Zy)r4   zq
    Fake traceback object which can be passed to functions in the standard
    library L{traceback} module.
    c                 d    || _         |j                  | _        |j                  | _        d| _        y)z-
        @param frame: _Frame object
        N)tb_framef_lineno	tb_linenof_lastitb_lastir5   )selfframes     r   __init__z_TracebackFrame.__init__   s(     r   Nr   r   r   r/   rF   r   r   r   r4   r4      s    
r   r4   c                       e Zd ZdZd Zy)r3   aD  
    A fake frame object, used by L{_Traceback}.

    @ivar f_code: fake L{code<types.CodeType>} object
    @ivar f_lineno: line number
    @ivar f_globals: fake f_globals dictionary (usually empty)
    @ivar f_locals: fake f_locals dictionary (usually empty)
    @ivar f_back: previous stack frame (towards the caller)
    c                    |\  }}}}}t        ||      | _        || _        t        |xs i       | _        t        |xs i       | _        || _        d| _        t        t              j                         | _        d| _        y)z
        @param frameinfo: (methodname, filename, lineno, locals, globals)
        @param back: previous (older) stack frame
        @type back: C{frame}
        r   N)_Codef_coder@   dict	f_globalsf_localsf_backrB   varsbuiltinscopy
f_builtinsf_trace)rD   	frameinfobackr*   r&   r'   localzglobalzs           r   rF   z_Frame.__init__   sr     3</hD(+gm,V\r*x.--/r   NrG   r   r   r   r3   r3      s    r   r3   c                       e Zd ZdZd Zd Zy)rJ   z
    A fake code object, used by L{_Traceback} via L{_Frame}.

    It is intended to have the same API as the stdlib code type to allow
    interoperation with other tools based on that interface.
    c                     || _         || _        d| _        d| _        d| _        g | _        d| _        d| _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        y )Nr   r   r   )co_nameco_filename	co_lnotabco_firstlinenoco_argcountco_varnamesco_codeco_cellvars	co_constsco_flagsco_freevarsco_posonlyargcountco_kwonlyargcountco_names
co_nlocalsco_stacksize)rD   r*   r&   s      r   rF   z_Code.__init__   s{    #"#!"r   c                      y)N))NNNNr   rD   s    r   co_positionsz_Code.co_positions   s    *r   N)r   r   r   r/   rF   rm   r   r   r   rJ   rJ      s    $+r   rJ   freturnc                 D    t         j                  | j                         | S )a  
    Mark the given callable as extraneous to inlineCallbacks exception
    reporting; don't show these functions.

    @param f: a function that you NEVER WANT TO SEE AGAIN in ANY TRACEBACK
        reported by Failure.

    @type f: function

    @return: f
    )_inlineCallbacksExtraneousappend__code__)rn   s    r   _extraneousrt      s     %%ajj1Hr   c                       e Zd ZdZdZdZej                  d   ZddZ	d Z
d Zd Zd	efd
Zed        Zed        Zd	efdZd	efdZd Zd Zd Zd	efdZd	efdZddeded	efdZddZddZddZy)Failurea  
    A basic abstraction for an error that has occurred.

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

    The C{stack} and C{frame} attributes contain frames.  Each frame is a tuple
    of (funcName, fileName, lineNumber, localsItems, globalsItems), where
    localsItems and globalsItems are the contents of
    C{locals().items()}/C{globals().items()} for that frame, or an empty tuple
    if those details were not captured.

    @ivar value: The exception instance responsible for this failure.
    @ivar type: The exception's class.
    @ivar stack: list of frames, innermost last, excluding C{Failure.__init__}.
    @ivar frames: list of frames, innermost first.
    r   NYIELD_VALUEc                    t         dz   a t         | _         dx| _        x| _        }|| _        t	        |t
              r|t        d      d}|| j                         }|;t        j                         \  | _        | _        }| j                  
t               d}nJ|:t	        |t              r|j                  | _        nt        |      | _        || _        n|| _        || _        t	        | j                  t              r| j                  | j                         yt        | j                  d      r2| j                  | j                  j                          | j                  `y|2|r|}n-t#        | j                  dd      r| j                  j$                  }g x}| _        g x}| _        || _        |r|j,                  }	nt	        | j                  t              sdx}	}|r	r|	j.                  }	|dz  }|r|	r	r|r|	j0                  j3                         }
|	j0                  |	j4                  u ri }n|	j4                  j3                         }||
fD ]
  }d|v s|d=  |
j7                         }
|j7                         }ndx}
}|j9                  d|	j:                  j<                  |	j:                  j>                  |	j@                  |
|f       |	j.                  }	|	r||j,                  }	|r|	j0                  j3                         }
|	j0                  |	j4                  u ri }n|	j4                  j3                         }||
fD ]
  }d|v s|d=  tC        |
j7                               }
tC        |j7                               }ndx}
}|jE                  |	j:                  j<                  |	j:                  j>                  |jF                  |
|f       |jH                  }|tK        jL                  | j                        rXtO        | j                  t              r>tQ        | j                        }tC        tS        tT        jV                  |            | _,        y| j                  g| _,        y)	a-  
        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 L{None} are allowed.
        If L{None} is supplied for C{exc_value}, the value of C{exc_tb} is
        ignored, otherwise if C{exc_tb} is L{None}, it will be found from
        execution context (ie, L{sys.exc_info}).

        @param captureVars: if set, capture locals and globals of stack
            frames.  This is pretty slow, and makes no difference unless you
            are going to use L{printDetailedTraceback}.
        r1   Nz$Strings are not supported by Failurer   __failure____traceback____builtins__r   )-counttypevaluecaptureVars
isinstancestr	TypeError_findFailuresysexc_infor.   	Exception	__class__rv   _extrapolatehasattrry   getattrrz   r!   r8   r;   r?   rO   rN   rR   rM   itemsinsertrK   r[   r\   r@   listrr   rA   r5   inspectisclass
issubclassr   mapr   qualparents)rD   	exc_valueexc_typeexc_tbr   r;   stackOffsetr!   r8   rn   rW   rX   dparentCss                 r   rF   zFailure.__init__  s   2 	
&**	*DJ&i%(*:BCC))+I(+%DItz2yy -//K)Y/%//	 !O	"DJ DI"DJdjj'*djj)4::}- djj445 

&:_d;ZZ--!!

 ADJJ0 #"Aa A1K	 a *::, Gkk..0G & .A%*n-.  !--/#%%LLHH$$HH((JJ	 A1 4 nA*::, Gkk..0G & .A%*n-. flln-w}}/#%%MMHH$$HH((LL B1 n2 ??499%*TYY	*Jdii(HGLL( ;<DL II;DLr   c                    t        j                   |j                        | _        t        j                         \  }}}g }|u|j                  }|j
                  t        vrH|j                  |j
                  j                  |j
                  j                  |j                  ddf       |j                  }|u|j                  | j                         || _        y)a,  
        Extrapolate from one failure into another, copying its stack frames.

        @param otherFailure: Another L{Failure}, whose traceback information,
            if any, should be preserved as part of the stack presented by this
            one.
        @type otherFailure: L{Failure}
        Nr   )rR   __dict__r   r   r?   rK   rq   rr   r[   r\   rA   r5   extendr!   )rD   otherFailure_r;   r!   rn   s         r   r   zFailure._extrapolate  s     		,"7"78 <<>1bnAxx99XX%%qxx';';R\\2rR B n 	dkk"r   c                 H     | j                   | }|s| j                          |S )a  
        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. In Python 2 the Failure will be
        raised; in Python 3 the underlying exception will be re-raised.

        @type errorTypes: L{Exception}
        )checkraiseException)rD   
errorTypeserrors      r   trapzFailure.trap  s(    0 

J'!r   c                     |D ]P  }|}t        j                  |      r%t        |t              rt	        j
                  |      }|| j                  v sN|c S  y)a  
        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)r   r   r   r   r   r   r   )rD   r   r   errs       r   r   zFailure.check  sQ       	ECu%*UI*Fll5)dll"	 r   ro   c                 L    | j                   j                  | j                        )zf
        raise the original exception, preserving traceback
        information if available.
        )r~   with_tracebackr;   rl   s    r   r   zFailure.raiseException  s    
 jj''00r   c                 j    |j                  | j                  j                  | j                              S )aJ  
        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.
        )throwr~   r   r;   )rD   gs     r   throwExceptionIntoGeneratorz#Failure.throwExceptionIntoGenerator  s&     wwtzz009::r   c                    t        j                         d   }|syd}|}|j                  r|}|j                  }|j                  r|j                  }|j                  | j
                  j                  u r|j                  j                  d      S |j                  j                  r0|j                  j                  |j                     | j                  k7  ry|rI|j                  }|j                  | j                  j                  u r|j                  j                  d      S |j                  j                  }|r>|j                  | j                  j                  u r|j                  j                  d      S yy)zV
        Find the failure that represents the exception currently in context.
        NrD   )r   r   r5   r?   rK   r   rs   rN   getra   rC   _yieldOpcoder   rO   )clsr;   secondLastTblastTb	lastFramerE   s         r   r   zFailure._findFailure	  sC   
 \\^Bnn!L^^F nn OO	 s11:::%%))&11   ((Y-=-=-E-EOO.
. 
  ))E||s>>GGG~~))&11 ""U\\S%D%D%M%MM>>%%f-- N5r   c                     dj                  t        j                  | j                        t        j                  | j                        | j                               S )Nz<{} {}: {}>)formatr   r   r   r}   getErrorMessagerl   s    r   __repr__zFailure.__repr__D  sA    ##LL(LL#  "
 	
r   c                 (    d| j                         z  S )Nz[Failure instance: %s])getBriefTracebackrl   s    r   __str__zFailure.__str__K  s    '$*@*@*BBBr   c                    | j                   r| j                  S | j                  j                         }| j                  D cg c]*  }|d   |d   |d   t	        |d         t	        |d         g, c}|d<   d|d<   | j
                  C| j
                  D cg c]*  }|d   |d   |d   t	        |d         t	        |d         g, c}|d	<   d|d
<   |S c c}w c c}w )z(Avoid pickling objects in the traceback.r   r1         r   r!   Nr;   r8   pickled)r   r   rR   r!   _safeReprVarsr8   )rD   cvs      r   __getstate__zFailure.__getstate__N  s    <<== MM  [[	
  !!!ad#ad#	
( $::! 	  aDaDaD!!A$'!!A$'	AgJ );	
"	s   /C/Cc                     | j                         | _        t        | j                  dd      rd| j                  _        yy)z
        Remove references to other objects, replacing them with strings.

        On Python 3, this will also set the C{__traceback__} attribute of the
        exception instance to L{None}.
        rz   N)r   r   r   r~   rz   rl   s    r   cleanFailurezFailure.cleanFailures  s5     ))+4::5'+DJJ$ 6r   c                     | j                   | j                   S t        | j                        dkD  r t        | j                  | j                        S y)a  
        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.
        Nr   )r;   r2   r!   r<   r8   rl   s    r   getTracebackObjectzFailure.getTracebackObject  s@     7777N!djj$++66r   c                     t        | j                  t              r| j                  j                         S t	        j
                  | j                        S )zJ
        Get a string of the exception which caused this Failure.
        )r   r~   rv   r   r   safe_strrl   s    r   r   zFailure.getErrorMessage  s:     djj'*::--//

++r   c                 Z    t               }| j                  |       |j                         S )N)file)r   printBriefTracebackgetvalue)rD   ios     r   r   zFailure.getBriefTraceback  s&    Z  b ){{}r   elideFrameworkCoder#   c                 ^    t               }| j                  |||       |j                         S )N)r   r   r#   )r   printTracebackr   )rD   r   r#   r   s       r   getTracebackzFailure.getTraceback  s2    Z(:6 	 	
 {{}r   c           	         |ddl m} |j                  }|j                  }|dk(  r| j                  sd}n|}|dk(  r* |d| j
                  | j                  xr dxs dfz         nj|d	k(  r]| j                  rd
}nd} ||dt        j                  | j                        dt        j                  | j                        d       n |d       | j                  rH|s.t        | j                  t         d ||        |t         d       t        | j                  ||       n|d	k(  s |d       |d	k(  sH |t        j                   | j                         dt        j                  | j                         d       t#        | j                  t$              r.|j                  d       | j                  j'                  |||       |dk(  r |d| j
                  z         yy)a  
        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'}.
        Nr   )logr   r   z*--- Failure #%d%s---
z (pickled)  r   	Tracebackz"Traceback (failure with no frames)z: r   z#Traceback (most recent call last):
z	Failure: z (chained Failure)
z*--- End of Failure #%d ---
)twisted.pythonr   logerrr"   r   r|   r   r!   r   r   r}   r~   r,   r8   traceupLengthEXCEPTION_CAUGHT_HEREr   r   rv   r   )rD   r   r   r#   r   r$   formatDetail	hasFramess           r   r   zFailure.printTraceback  s    <*::DJJYt'7'7 7L!L Y):: >F3GH w{{'	@	g..tyy97;K;KDJJ;WY
 45 ;;%djj-91lK*+2./$++q,77"kN  dii()G,<,<TZZ,H+ILM djj'*JJ-.JJ%%d,>GY-

:; r   c                 ,    | j                  ||d       y)z;
        Print a traceback as densely as possible.
        r   r#   Nr   rD   r   r   s      r   r   zFailure.printBriefTraceback  s     	D"4WEr   c                 ,    | j                  ||d       y)zQ
        Print a traceback with detailed locals and globals information.
        r   r   Nr   r   s      r   printDetailedTracebackzFailure.printDetailedTraceback  s     	D"4YGr   )NNNF)r   r   )NFr   )Nr   ) r   r   r   r/   r   r8   opcodeopmapr   rF   r   r   r   r   r   rt   r   classmethodr   r   r   r   r   r   r   r   r   intr   r   r   r   r   r   r   rv   rv      s    $ GE <<.Lc'J:: 1 1 ; ; 8. 8.t
# 
C C#J
,", ,3 
s  TW C<JFHr   rv   c                 b    | D cg c]  \  }}|t        j                  |      f c}}S c c}}w )aq  
    Convert a list of (name, object) pairs into (name, repr) pairs.

    L{twisted.python.reflect.safe_repr} is used to generate the repr, so no
    exceptions will be raised by faulty C{__repr__} methods.

    @param varsDictItems: a sequence of (name, value) pairs as returned by e.g.
        C{locals().items()}.
    @returns: a sequence of (name, repr) pairs.
    )r   	safe_repr)varsDictItemsr*   objs      r   r   r     s-     ?LL{cT7$$S)*LLLs   !+TFc                 (   |||fdk(  rmt        j                         }|d   | j                  k(  sGt        rA	 t	        |d         }t        dj                  |             ddl}|j                  |d           || ||||       y# t
        $ r d}Y Lw xY w)z;
    Initialize failure object, possibly spawning pdb.
    )NNNr   r1   z
broken strz8Jumping into debugger for post-mortem of exception '{}':Nr   )
r   r   r   DO_POST_MORTEMr   BaseExceptionprintr   pdbpost_mortem)	rD   r   r   r   r   Failure__init__excstrreprr   s	            r   
_debuginitr   	  s     	8V$(::lln1v'N'c!f+ JQQ
 OOCF#D)Xv{C ! '&'s   B BBc                  "    t         t        _        y)z*
    Enable debug hooks for Failures.
    N)r   rv   rF   r   r   r   startDebugModer   &  s     "Gr   )r   )&r/   rQ   rR   r   r   r   r   r   r   typingr   r   r   r   r   r   objectr	   r|   r   r   r   r,   r   r.   r<   r4   r3   rJ   rq   rt   r   rv   r   r   rF   r   r   r   r   r   <module>r      s        
   . .  "m8CK+@A		y 	+/` : i #R   8+ +<   ; ;  LHm LH^M  
 $$D:"r   