o
    ¯bi  ã                   @   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Zddl	m
Z
 dadZG dd„ deƒZd#d
d„ZdZG dd„ deƒZdd„ ZG dd„ dƒZG dd„ dƒZG dd„ dƒZg Zdd„ ZG dd„ deƒZdd„ ZdZddddejfdd „Zd!d"„ ZdS )$z9
Asynchronous-friendly error mechanism.

See L{Failure}.
é    N)Úgetmro)ÚStringIO)Úreflecté   c                   @   s   e Zd ZdS )ÚDefaultExceptionN)Ú__name__Ú
__module__Ú__qualname__© r
   r
   ú8/usr/lib/python3/dist-packages/twisted/python/failure.pyr      s    r   Údefaultc              	   C   sx  |dvrt d|f ƒ‚|}|dkr*| D ]\}}}}}||› d|› d|› d�ƒ qdS |dkrT| D ]!\}}}}}|d|› d|› d	|› d�ƒ |d
t ||¡ ¡  ƒ q0dS |dkrq| D ]\}}}}}|d|||f ƒ qZ|dƒ dS |dkr¸| D ]B\}}}}}|d|||f ƒ |dƒ |D ]\}	}
|d|	› dt|
ƒ› d�ƒ q�|dƒ |D ]\}	}
|d|	› dt|
ƒ› d�ƒ q¥qwdS dS )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
    )r   ÚbriefÚverboseúverbose-vars-not-capturedzNDetail must be default, brief, verbose, or verbose-vars-not-captured. (not %r)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Úvalr
   r
   r   Úformat_frames#   s@   ÿÿÿþÿør"   z--- <exception caught here> ---c                   @   s   e Zd ZdZdS )Ú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#   V   s    r#   c                 C   sv   t |ƒdks
J dƒ‚d}| D ]}t||ƒ}qt|d |ƒ}t|ƒ }}|dd… D ]}t||ƒ}t|ƒ|_|j}q)|S )a–  
    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 method, since locals and globals are not used in
    standard tracebacks.

    @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Útbr
   r
   r   Ú
_Traceback]   s   


r0   c                   @   ó   e Zd ZdZdd„ ZdS )r(   zq
    Fake traceback object which can be passed to functions in the standard
    library L{traceback} module.
    c                 C   s   || _ |j| _d| _dS )z-
        @param frame: _Frame object
        N)Útb_frameÚf_linenoÚ	tb_linenor)   )ÚselfÚframer
   r
   r   Ú__init__‰   s   
z_TracebackFrame.__init__N©r   r   r	   r$   r7   r
   r
   r
   r   r(   ƒ   s    r(   c                   @   r1   )r'   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                 C   s6   |\}}}}}t ||ƒ| _|| _i | _i | _|| _dS )z¢
        @param frameinfo: (methodname, filename, lineno, locals, globals)
        @param back: previous (older) stack frame
        @type back: C{frame}
        N)Ú_CodeÚf_coder3   Ú	f_globalsÚf_localsÚf_back)r5   Ú	frameinfoÚbackr    r   r   ÚlocalzÚglobalzr
   r
   r   r7   �   s   
z_Frame.__init__Nr8   r
   r
   r
   r   r'   ’   s    
r'   c                   @   r1   )r9   zB
    A fake code object, used by L{_Traceback} via L{_Frame}.
    c                 C   s   || _ || _d S )N)Úco_nameÚco_filename)r5   r    r   r
   r
   r   r7   °   s   
z_Code.__init__Nr8   r
   r
   r
   r   r9   «   s    r9   c                 C   s   t  | 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__)Úfr
   r
   r   Ú_extraneous¸   s   rH   c                   @   sê   e Zd ZdZdZdZejd Zd.dd„Z	dd	„ Z
d
d„ Zdd„ Zdd„ Zedd„ ƒZedd„ ƒZdefdd„Zdefdd„Zdd„ Zdd„ Zdd„ Zdefdd „Zdefd!d"„Zd/d$ed%edefd&d'„Zd0d(d)„Zd1d*d+„Zd1d,d-„ZdS )2Ú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_VALUEFc                 C   s  t d a t | _ d | _ | _}|| _t|tƒr|du rtdƒ‚d}|du r)|  ¡ }|du rAt 	¡ \| _| _}| jdu r>t
ƒ ‚d}n|du rXt|tƒrO|j| _nt|ƒ| _|| _n|| _|| _t| jtƒrl|  | j¡ dS t| jdƒr~|  | jj¡ | j`dS |du r’|r‡|}nt| jddƒr’| jj}g  }| _g  }| _|| _|r¥|j}	n
t| jtƒs¯d }	}|r¾|	r¾|	j}	|d8 }|r¾|	s³|	�r|rí|	j ¡ }
|	j|	ju rÑi }n|	j ¡ }||
fD ]	}d|v rã|d= qÚ|
 ¡ }
| ¡ }nd }
}| d|	jj|	jj|	j |
|f¡ |	j}	|	sÁ|du�r]|j}	|�rB|	j ¡ }
|	j|	ju �r i }n|	j ¡ }||
fD ]}d|v �r3|d= �q)t!|
 ¡ ƒ}
t!| ¡ ƒ}nd }
}| "|	jj|	jj|j#|
|f¡ |j$}|du�st% &| j¡�r{t'| jtƒ�r{t(| jƒ}t!t)t*j+|ƒƒ| _,dS | jg| _,dS )	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}.
        r%   Nz$Strings are not supported by Failurer   Ú__failure__Ú__traceback__Ú__builtins__r
   )-ÚcountÚtypeÚvalueÚcaptureVarsÚ
isinstanceÚstrÚ	TypeErrorÚ_findFailureÚsysÚexc_infor#   Ú	ExceptionÚ	__class__rI   Ú_extrapolateÚhasattrrK   ÚgetattrrL   r   r,   r/   r2   r=   r<   Úcopyr;   ÚitemsÚinsertr:   rB   rC   r3   ÚlistrE   r4   r)   ÚinspectÚisclassÚ
issubclassr   Úmapr   ÚqualÚparents)r5   Ú	exc_valueÚexc_typeÚexc_tbrQ   r/   ÚstackOffsetr   r,   rG   r@   rA   ÚdÚparentCsr
   r
   r   r7   æ   sÀ   





ü

€
ûþ
è



€ûÿ	
è
zFailure.__init__c                 C   sz   t   |j¡| _t ¡ \}}}g }|dur2|j}|jtvr+| |jj|jj	|j
ddf¡ |j}|dus| | j¡ || _dS )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
   )r]   Ú__dict__rV   rW   r2   r:   rD   rE   rB   rC   r4   r)   Úextendr   )r5   ÚotherFailureÚ_r/   r   rG   r
   r
   r   rZ   Œ  s   

ÿú
zFailure._extrapolatec                 G   s   | j |Ž }|s|  ¡  |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)r5   Ú
errorTypesÚerrorr
   r
   r   Útrap©  s   
zFailure.trapc                 G   sB   |D ]}|}t  |¡rt|tƒrt |¡}|| jv r|  S qdS )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)ra   rb   rc   rX   r   re   rf   )r5   rs   rt   Úerrr
   r
   r   rq   Æ  s   

ÿzFailure.checkc                 C   s   | j  | j¡‚)zf
        raise the original exception, preserving traceback
        information if available.
        )rP   Úwith_tracebackr/   ©r5   r
   r
   r   rr   Ö  s   zFailure.raiseExceptionc                 C   s   |  | 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.
        )ÚthrowrO   rP   r/   )r5   Úgr
   r
   r   ÚthrowExceptionIntoGeneratorÝ  s   z#Failure.throwExceptionIntoGeneratorc                 C   sÄ   t  ¡ d }|s
dS d}|}|jr|}|j}|js|j}|j| jju r)|j d¡S |jj	r7|jj	|j
 | jkr9dS |rK|j}|j| jju rK|j d¡S |jj}|r^|j| jju r`|j d¡S dS dS )zV
        Find the failure that represents the exception currently in context.
        éÿÿÿÿNr5   )rV   rW   r)   r2   r:   rr   rF   r<   ÚgetÚco_codeÚtb_lastiÚ_yieldOpcoder{   r=   )Úclsr/   ÚsecondLastTbÚlastTbÚ	lastFramer6   r
   r
   r   rU   ë  s4   þ	ÿþÿzFailure._findFailureÚreturnc                 C   s"   d  t | j¡t | j¡|  ¡ ¡S )Nz<{} {}: {}>)Úformatr   re   rY   rO   ÚgetErrorMessagerx   r
   r
   r   Ú__repr__&  s
   

ýzFailure.__repr__c                 C   s   d|   ¡  S )Nz[Failure instance: %s])ÚgetBriefTracebackrx   r
   r
   r   Ú__str__-  s   zFailure.__str__c                 C   s\   | j r| jS | j ¡ }dd„ | jD ƒ|d< d|d< | jdur(dd„ | jD ƒ|d< d|d	< |S )
z(Avoid pickling objects in the traceback.c              	   S   ó6   g | ]}|d  |d |d t |d ƒt |d ƒg‘qS ©r   r%   é   é   r   ©Ú_safeReprVars©Ú.0Úvr
   r
   r   Ú
<listcomp>6  ó    ú

ûÿz(Failure.__getstate__.<locals>.<listcomp>r   Nr/   c              	   S   r‹   rŒ   r�   r‘   r
   r
   r   r”   G  r•   r,   r%   Úpickled)r–   rm   r]   r   r,   )r5   Úcr
   r
   r   Ú__getstate__0  s   

ø

øzFailure.__getstate__c                 C   s(   |   ¡ | _t| jddƒrd| j_dS dS )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}.
        rL   N)r˜   rm   r\   rP   rL   rx   r
   r
   r   ÚcleanFailureU  s   
þzFailure.cleanFailurec                 C   s0   | j dur| j S t| jƒdkrt| j| jƒS dS )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/   r&   r   r0   r,   rx   r
   r
   r   ÚgetTracebackObjecta  s
   

zFailure.getTracebackObjectc                 C   s"   t | jtƒr| j ¡ S t | j¡S )zJ
        Get a string of the exception which caused this Failure.
        )rR   rP   rI   r‡   r   Úsafe_strrx   r
   r
   r   r‡   r  s   
zFailure.getErrorMessagec                 C   s   t ƒ }| j|d� | ¡ S )N)Úfile)r   ÚprintBriefTracebackÚgetvalue)r5   Úior
   r
   r   r‰   z  s   zFailure.getBriefTracebackr   ÚelideFrameworkCoder   c                 C   s   t ƒ }| j|||d� | ¡ S )N)rœ   r    r   )r   ÚprintTracebackrž   )r5   r    r   rŸ   r
   r
   r   ÚgetTraceback  s
   ÿzFailure.getTracebackc                 C   sb  |du rddl m} |j}|j}|dkr| jsd}n|}|dkr/|d| j| jr)dp*df ƒ n"|d	krM| jr9d
}nd}|d|t 	| j
¡t 	| j¡f ƒ n|dƒ | jrq|sit| jt d… ||ƒ |t› d�ƒ t| j||ƒ n|d	ksy|dƒ |d	ks�|t | j
¡› dt 	| j¡› d�ƒ t| jtƒr¢| d¡ | j |||¡ |dkr¯|d| j ƒ dS dS )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%s: %s: %s
z#Traceback (most recent call last):
r   z	Failure: z: z (chained Failure)
z*--- End of Failure #%d ---
)Útwisted.pythonr£   Úlogerrr   rQ   rN   r–   r   r   r›   rO   rP   r"   r,   ÚtraceupLengthÚEXCEPTION_CAUGHT_HEREre   rR   rI   r¡   )r5   rœ   r    r   r£   r   ÚformatDetailÚ	hasFramesr
   r
   r   r¡   †  sL   ÿÿÿÿ$
ÿzFailure.printTracebackc                 C   ó   | j ||dd� dS )z;
        Print a traceback as densely as possible.
        r   ©r   N©r¡   ©r5   rœ   r    r
   r
   r   r�   Ë  ó   zFailure.printBriefTracebackc                 C   r¬   )zQ
        Print a traceback with detailed locals and globals information.
        r   r­   Nr®   r¯   r
   r
   r   ÚprintDetailedTracebackÑ  r°   zFailure.printDetailedTraceback)NNNF)r   r   )NFr   )Nr   )r   r   r	   r$   r–   r,   ÚopcodeÚopmapr€   r7   rZ   ru   rq   rr   rH   r{   ÚclassmethodrU   rS   rˆ   rŠ   r˜   r™   rš   r‡   r‰   Úintr¢   r¡   r�   r±   r
   r
   r
   r   rI   È   s4    

 '

:%

ErI   c                 C   s   dd„ | D ƒS )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.
    c                 S   s   g | ]\}}|t  |¡f‘qS r
   )r   Ú	safe_repr)r’   r    Úobjr
   r
   r   r”   ã  s    z!_safeReprVars.<locals>.<listcomp>r
   )ÚvarsDictItemsr
   r
   r   r�   Ø  s   r�   TFc           	      C   sˆ   |||fdkr:t  ¡ }|d | jks:tr:zt|d ƒ}W n ty'   d}Y nw td |¡ƒ ddl}| 	|d ¡ || ||||ƒ dS )z;
    Initialize failure object, possibly spawning pdb.
    )NNNr   r%   z
broken strz8Jumping into debugger for post-mortem of exception '{}':Nr�   )
rV   rW   rY   ÚDO_POST_MORTEMrS   ÚBaseExceptionÚprintr†   ÚpdbÚpost_mortem)	r5   rg   rh   ri   rQ   ÚFailure__init__ÚexcÚstrreprr¼   r
   r
   r   Ú
_debuginitë  s    ÿÿÿrÁ   c                   C   s
   t t_dS )z*
    Enable debug hooks for Failures.
    N)rÁ   rI   r7   r
   r
   r
   r   ÚstartDebugMode  s   
rÂ   )r   )r$   r]   ra   r   rV   r   rŸ   r   r²   r¦   r   rN   r¨   rX   r   r"   r©   r#   r0   r(   r'   r9   rD   rH   rº   rI   r�   r¹   r7   rÁ   rÂ   r
   r
   r
   r   Ú<module>   sF   
0&
    
ú