U
    aG‘\/  ã                   @   sD  d Z ddlZddlZddlmZmZ ddlmZmZ ddl	m
Z
 ddlmZmZmZ zddlmZ W n ek
r|   dZY nX zedƒ W n. ek
r¢   d	ZY n ek
r¸   d
ZY nX G dd„ deƒZdd„ ZG dd„ deƒZddd„Zddd„Zddd„Zdd„ Zdd„ Zdd„ ZdZ edk�r@z
eƒ Z W n   Y nX [dS ) aQ  
    jinja2.debug
    ~~~~~~~~~~~~

    Implements the debug interface for Jinja.  This module does some pretty
    ugly stuff with the Python traceback system in order to achieve tracebacks
    with correct line numbers, locals and contents.

    :copyright: (c) 2017 by the Jinja Team.
    :license: BSD, see LICENSE for more details.
é    N)ÚTracebackTypeÚCodeType)ÚmissingÚinternal_code)ÚTemplateSyntaxError)Ú	iteritemsÚreraiseÚPY2)Útproxyzraise TypeError, 'foo'zraise __jinja_exception__[1]z4raise __jinja_exception__[0], __jinja_exception__[1]c                   @   s@   e Zd ZdZdd„ Zedd„ ƒZdd„ Zedd	„ ƒZd
d„ Z	dS )ÚTracebackFrameProxyzProxies a traceback frame.c                 C   s   || _ d | _d S ©N)ÚtbÚ_tb_next©Úselfr   © r   ú./usr/lib/python3/dist-packages/jinja2/debug.pyÚ__init__'   s    zTracebackFrameProxy.__init__c                 C   s   | j S r   )r   ©r   r   r   r   Útb_next+   s    zTracebackFrameProxy.tb_nextc                 C   sB   t d k	r8zt | j|r|jpd ƒ W n tk
r6   Y nX || _d S r   )Útb_set_nextr   Ú	Exceptionr   )r   Únextr   r   r   Úset_next/   s    zTracebackFrameProxy.set_nextc                 C   s   d| j jjkS )NÚ__jinja_template__)r   Útb_frameÚ	f_globalsr   r   r   r   Úis_jinja_frame:   s    z"TracebackFrameProxy.is_jinja_framec                 C   s   t | j|ƒS r   )Úgetattrr   )r   Únamer   r   r   Ú__getattr__>   s    zTracebackFrameProxy.__getattr__N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   r   r   r    r   r   r   r   r   $   s   

r   c                    s*   t | ƒ‰ td krˆ S ‡ fdd„}tt|ƒS )Nc                    s@   | dkrt ˆ |d ƒS | dkr,ˆ j||Ž nt ˆ | ƒ||ŽS d S )N)Ú__getattribute__r    r   Ú__setattr__)r   r'   )Z	operationÚargsÚkwargs©Úproxyr   r   Úoperation_handlerF   s
    z+make_frame_proxy.<locals>.operation_handler)r   r
   r   )Úframer,   r   r*   r   Úmake_frame_proxyB   s
    r.   c                   @   sP   e Zd ZdZdd„ Zddd„Zddd	„Zed
d„ ƒZedd„ ƒZ	edd„ ƒZ
dS )ÚProcessedTracebackz?Holds a Jinja preprocessed traceback for printing or reraising.c                 C   sR   |st dƒ‚|| _|| _|| _d }| jD ]}|d k	r>| |¡ |}q(| d ¡ d S )Nzno frames for this traceback?)ÚAssertionErrorÚexc_typeÚ	exc_valueÚframesr   )r   r1   r2   r3   Zprev_tbr   r   r   r   r   S   s    

zProcessedTraceback.__init__Nc                 C   s*   t j| j| j| jd |d�}d |¡ ¡ S )z#Return a string with the traceback.r   )ÚlimitÚ )Ú	tracebackÚformat_exceptionr1   r2   r3   ÚjoinÚrstrip)r   r4   Úlinesr   r   r   Úrender_as_texta   s
     ÿz!ProcessedTraceback.render_as_textFc                 C   s,   ddl m} d|| |d�|  ¡  dd¡f S )z<Return a unicode string with the traceback as rendered HTML.r   )Úrender_tracebackz%s

<!--
%s
-->)Úfullzutf-8Úreplace)Zjinja2.debugrendererr<   r;   Údecode)r   r=   r<   r   r   r   Úrender_as_htmlg   s
    
þz!ProcessedTraceback.render_as_htmlc                 C   s   t | jtƒS )z*`True` if this is a template syntax error.)Ú
isinstancer2   r   r   r   r   r   Úis_template_syntax_erroro   s    z+ProcessedTraceback.is_template_syntax_errorc                 C   s   | j | j| jd fS )z;Exception info tuple with a proxy around the frame objects.r   )r1   r2   r3   r   r   r   r   Úexc_infot   s    zProcessedTraceback.exc_infoc                 C   s*   | j d }t|ƒtk	r|j}| j| j|fS )z'Standard python exc_info for re-raisingr   )r3   Útyper   r   r1   r2   r   r   r   r   Ústandard_exc_infoy   s    
z$ProcessedTraceback.standard_exc_info)N)F)r!   r"   r#   r$   r   r;   r@   r%   rB   rC   rE   r   r   r   r   r/   P   s   



r/   c                 C   s2   | \}}}t |tƒr$t||ƒ} d}nd}t| |ƒS )z7Creates a processed traceback object from the exc_info.r   é   )rA   r   Útranslate_syntax_errorÚtranslate_exception)rC   Zsource_hintr1   r2   r   Úinitial_skipr   r   r   Úmake_traceback„   s    


rJ   c                 C   s8   || _ d| _| j| df}| j}|dkr*d}t||| jƒS )z4Rewrites a syntax error to please traceback systems.TNz	<unknown>)ÚsourceZ
translatedÚ	__class__ÚfilenameÚfake_exc_infoÚlineno)ÚerrorrK   rC   rM   r   r   r   rG   �   s    rG   c           	      C   sÔ   | d }g }t |ƒD ]}|dk	r|j}q|}|dk	r¤|jjtkrH|j}q,|j}|jj d¡}|dk	r�| |j¡}t	| dd… |f |j
|ƒd }| t|ƒ¡ |}q,|sÀt| d | d | d ƒ t| d | d |ƒS )z„If passed an exc_info it will automatically rewrite the exceptions
    all the way down to the correct line numbers and frames.
    é   Nr   r   rF   )Úranger   r   Úf_coder   r   ÚgetZget_corresponding_linenoÚ	tb_linenorN   rM   Úappendr.   r   r/   )	rC   rI   r   r3   ÚxZ
initial_tbr   ÚtemplaterO   r   r   r   rH   š   s0    ÿÿrH   c           	   	   C   sÞ   |   d¡}|r| ¡  ¡ }ni }i }t| ƒD ]x\}}| d¡r,|tkrHq,z| dd¡\}}}t|ƒ}W n tk
r~   Y q,Y nX |  |d¡d }||k r,||f||< q,t|ƒD ]*\}\}}|tkrÐ| 	|d ¡ q®|||< q®|S )NÚcontextZl_Ú_rQ   )éÿÿÿÿr   )
rT   Zget_allÚcopyr   Ú
startswithr   ÚsplitÚintÚ
ValueErrorÚpop)	Zreal_localsZctxÚlocalsZlocal_overridesr   ÚvaluerZ   ZdepthZ	cur_depthr   r   r   Úget_jinja_localsÆ   s*    


rd   c                 C   s‚  | \}}}|dk	r,t |jjƒ}| dd¡ ni }||| dd… ddœ}td|d  t |dƒ}z¼|dkrnd}	n8|jjj}
|
d	kr†d
}	n |
 d¡r¢d|
dd…  }	nd}	t	ràt
d|j|j|j|j|j|j|j||	|j|jddƒ}n8t
d|j|j|j|j|j|j|j|j||	|j|jddƒ}W n$ tk
�r> } zW 5 d}~X Y nX zt|||ƒ W n   t ¡ } | d j}Y nX | dd… |f S )z!Helper for `translate_exception`.NÚ__jinja_exception__rQ   )r!   Ú__file__re   r   Ú
rF   ÚexecrX   Úrootztop-level template codeZblock_z
block "%s"é   r   r   )rd   r   Úf_localsra   ÚcompileÚraise_helperrS   Úco_namer]   r	   r   Ú
co_nlocalsÚco_stacksizeÚco_flagsÚco_codeÚ	co_constsÚco_namesÚco_varnamesÚco_firstlinenoÚ	co_lnotabÚco_kwonlyargcountr   rh   ÚsysrC   r   )rC   rM   rO   r1   r2   r   rb   ÚglobalsÚcodeÚlocationZfunctionÚeZnew_tbr   r   r   rN   ä   sr    

ø

       ü        ûrN   c                     s  ddl ‰ddlm‰  tr4tˆjdƒr,ˆj} q:ˆj} nˆj} G dd„ dˆj	ƒ}d| fdˆ 
|¡fg|_ttd	ƒr°G d
d„ dˆj	ƒ}dˆ 
|¡fdˆ 
|¡fd| fdˆ 
|¡fg|_G dd„ d|ƒ‰dˆ 
ˆ¡fdˆ 
|¡fdˆjfdˆjfgˆ_‡ ‡‡fdd„}|S )zñThis function implements a few ugly things so that we can patch the
    traceback objects.  The function returned allows resetting `tb_next` on
    any python traceback object.  Do not attempt to use this on non cpython
    interpreters
    r   N)r   ZPy_InitModule4_64c                   @   s   e Zd ZdS ©z"_init_ugly_crap.<locals>._PyObjectN©r!   r"   r#   r   r   r   r   Ú	_PyObject>  s   r€   Ú	ob_refcntÚob_typeZ
getobjectsc                   @   s   e Zd ZdS r~   r   r   r   r   r   r€   G  s   Z_ob_nextZ_ob_prevc                   @   s   e Zd ZdS )z#_init_ugly_crap.<locals>._TracebackNr   r   r   r   r   Ú
_TracebackP  s   rƒ   r   r   Útb_lastirU   c                    sž   t | ˆ ƒr|dks$t |ˆ ƒs$tdƒ‚ˆ t| ƒ¡}| jdk	rZˆ t| jƒ¡}| jd8  _|dkrrˆ ˆ¡ƒ |_n(ˆ t|ƒ¡}| jd7  _ˆ |¡|_dS )z0Set the tb_next attribute of a traceback object.Nz/tb_set_next arguments must be traceback objectsrF   )rA   Ú	TypeErrorZfrom_addressÚidr   r�   ÚPOINTERZpointer)r   r   ÚobjÚold©r   rƒ   Úctypesr   r   r   Y  s    
ÿÿ
z$_init_ugly_crap.<locals>.tb_set_next)r‹   Útypesr   r	   ÚhasattrZ	pythonapiZc_int64Zc_intZ	c_ssize_tZ	Structurer‡   Z_fields_ry   )Z_Py_ssize_tr€   r   r   rŠ   r   Ú_init_ugly_crap*  s4    þ
üürŽ   )N)N)r   )!r$   ry   r6   rŒ   r   r   Zjinja2.utilsr   r   Zjinja2.exceptionsr   Zjinja2._compatr   r   r	   Z__pypy__r
   ÚImportErrorrh   ÚSyntaxErrorrm   r…   Úobjectr   r.   r/   rJ   rG   rH   rd   rN   rŽ   r   r   r   r   r   Ú<module>   s@   

4


,FD

