3
B^/                 @   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 yddlmZ W n ek
r|   dZY nX y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@y
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   ./tmp/pip-build-8app2_gc/Jinja2/jinja2/debug.py__init__'   s    zTracebackFrameProxy.__init__c             C   s   | j S )N)r   )r   r   r   r   tb_next+   s    zTracebackFrameProxy.tb_nextc             C   sB   t d k	r8yt | j|r|jpd  W n tk
r6   Y nX || _d S )N)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_globals)r   r   r   r   is_jinja_frame:   s    z"TracebackFrameProxy.is_jinja_framec             C   s   t | j|S )N)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   )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   sV   |st d|| _|| _|| _d }x$| jD ]}|d k	r@|j| |}q*W |jd  d S )Nzno frames for this traceback?)AssertionErrorexc_type	exc_valueframesr   )r   r-   r.   r/   Zprev_tbr   r   r   r   r   S   s    
zProcessedTraceback.__init__Nc             C   s*   t j| j| j| jd |d}dj|j S )z#Return a string with the traceback.r   )limit )	tracebackformat_exceptionr-   r.   r/   joinrstrip)r   r0   linesr   r   r   render_as_texta   s    z!ProcessedTraceback.render_as_textFc             C   s,   ddl m} d|| |d| j j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.debugrendererr8   r7   decode)r   r9   r8   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.)
isinstancer.   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   )r-   r.   r/   )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   )r/   typer   r   r-   r.   )r   r   r   r   r   standard_exc_infoy   s    
z$ProcessedTraceback.standard_exc_info)N)F)r   r   r    r!   r   r7   r<   r"   r>   r?   rA   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      )r=   r   translate_syntax_errortranslate_exception)r?   Zsource_hintr-   r.   r   initial_skipr   r   r   make_traceback   s    


rF   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)errorrG   r?   rI   r   r   r   rC      s    rC   c       	      C   s   | d }g }xt |D ]}|dk	r|j}qW |}xz|dk	r|jjtkrN|j}q2|j}|jjjd}|dk	r|j|j}t	| dd |f |j
|d }|jt| |}q2W |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   rB   )ranger   r   f_coder   r   getZget_corresponding_lineno	tb_linenorJ   rI   appendr*   r   r+   )	r?   rE   r   r/   xZ
initial_tbr   templaterK   r   r   r   rD      s*    


rD   c       	      C   s   | j d}|r|j j }ni }i }xt| D ]x\}}|jd s.|tkrLq.y|jdd\}}}t|}W n tk
r   w.Y nX |j |dd }||k r.||f||< q.W x6t|D ]*\}\}}|tkr|j	|d  q|||< qW |S )	NcontextZl__rM   rB   r   )rW   )
rP   get_allcopyr   
startswithr   splitint
ValueErrorpop)	Zreal_localsctxlocalsZlocal_overridesr   valuerV   depthZ	cur_depthr   r   r   get_jinja_locals   s*    
rc   c             C   s  | \}}}|dk	r,t |jj}|jdd ni }||| dd dd}td|d  t |d}y|dkrnd}	n8|jjj}
|
d	krd
}	n |
jdrd|
dd  }	nd}	t	rt
d|j|j|j|j|j|j|j||	|j|jf f }n8t
d|j|j|j|j|j|j|j|j||	|j|jf f }W n$ tk
r> } zW Y dd}~X nX yt||| W n   tj } | d j}Y nX | dd |f S )z!Helper for `translate_exception`.N__jinja_exception__rM   )r   __file__rd   r   
rB   execrT   rootztop-level template codeZblock_z
block "%s"   r   )rc   r   f_localsr^   compileraise_helperrO   co_namerZ   r	   r   
co_nlocalsco_stacksizeco_flagsco_code	co_constsco_namesco_varnamesco_firstlineno	co_lnotabco_kwonlyargcountr   rg   sysr?   r   )r?   rI   rK   r-   r.   r   r`   globalscodelocationfunctioneZnew_tbr   r   r   rJ      sN    





rJ   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j
|fg|_ttd	rG d
d dj	}dj
|fdj
|fd| fdj
|fg|_G dd d|dj
fdj
|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 )z"_init_ugly_crap.<locals>._PyObjectN)r   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>._TracebackN)r   r   r    r   r   r   r   
_TracebackP  s   r   r   r   tb_lastirQ   c                s   t |  o|dkpt | s$tdjt| }| jdk	rZjt| j}| jd8  _|dkrrj |_n(jt|}| jd7  _j||_dS )z0Set the tb_next attribute of a traceback object.Nz/tb_set_next arguments must be traceback objectsrB   )r=   	TypeErrorfrom_addressidr   r   POINTERpointer)r   r   objold)r   r   ctypesr   r   r   Y  s    

z$_init_ugly_crap.<locals>.tb_set_next)r   typesr   r	   hasattr	pythonapic_int64c_int	c_ssize_t	Structurer   _fields_rx   )Z_Py_ssize_tr~   r   r   )r   r   r   r   _init_ugly_crap*  s.    
r   )N)N)r   )!r!   rx   r2   r   r   r   Zjinja2.utilsr   r   Zjinja2.exceptionsr   Zjinja2._compatr   r   r	   Z__pypy__r
   ImportErrorrg   SyntaxErrorrl   r   objectr   r*   r+   rF   rC   rD   rc   rJ   r   r   r   r   r   r   <module>   s@   

4


,FD

