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,|st| d | d | d  t| d | d |S )zIf 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rd
}	n |
drd|
dd  }	nd}	t	rt
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	rG 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 )zThis 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

