B
    ܇\"                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlmZ ddl	m
Z
 ddlmZ d	d
 Zdd ZG dd deZG dd deZG dd deZdd Zdd Zdd Zdd Zdd ZdS )z6 interactive debugging with PDB, the Python Debugger.     )absolute_import)division)print_functionN)UnexpectedException)outcomes)hookimplc             C   sD   |  d}|jddddd |jddd	d
d |jddddd d S )NZgeneralz--pdbusepdb
store_truezEstart the interactive Python debugger on errors or KeyboardInterrupt.)destactionhelpz--pdbcls
usepdb_clszmodulename:classnamezqstart a custom interactive Python debugger on errors. For example: --pdbcls=IPython.terminal.debugger:TerminalPdb)r
   metavarr   z--tracetracez)Immediately break when running each test.)ZgetgroupZ
_addoption)parsergroup r   0lib/python3.7/site-packages/_pytest/debugging.pypytest_addoption   s     
r   c             C   s   |  dr8|  dd\}}t| ttj| |}ntj}|  drX| j	t
 d |  drr| j	t d tjtjtjtjtjf tjt_| jt_| t_|t_dd }| j| d S )	Nr   :r   Zpdbtracer   Z	pdbinvokec               S   s   t j \t_t _t _t _d S )N)	pytestPDB_savedpoppdb	set_trace_pluginmanager_config_pdb_clsr   r   r   r   fin<   s    zpytest_configure.<locals>.fin)getvaluesplit
__import__getattrsysmodulesr   PdbpluginmanagerregisterPdbTrace	PdbInvoker   r   appendr   r   r   r   Z_cleanup)configmodnameZ	classnameZpdb_clsr   r   r   r   pytest_configure%   s"    


r-   c               @   s>   e Zd ZdZdZdZejZg Z	dZ
edd Zedd ZdS )r   z) Pseudo PDB that defers to the real pdb. Nr   c                s   ddl jdk	rԈjdr.jdd jj}|  jdkr|	dd}|dk	rp|
d| n&r r|
dd n|
dd	 G  fd
ddjt  f |}jjjj|d njf |}|S )z6 Initialize PDB debugging, dropping any IO capturing. r   NcapturemanagerT)in_header>z'PDB set_trace (IO-capturing turned off)zPDB set_tracec                   s^   e Zd ZZdZ fddZ fddZe ZZ fddZ	 fdd	Z
  ZS )
z(pytestPDB._init_pdb.<locals>._PdbWrapperFc                s0    j d7  _ t | |} j d8  _ |S )N   )_recursive_debugsuperdo_debug)selfargret)_PdbWrapper	__class__clsr   r   r5   i   s    z1pytestPDB._init_pdb.<locals>._PdbWrapper.do_debugc                s   t  | |}| jrdjj}|  jdkrd| j rN|	dd n|	dd | j
  jjjj| d d| _|S )Nr   r1   z#PDB continue (IO-capturing resumed)zPDB continue)r+   r   T)r4   do_continue_pytest_capmanr+   create_terminal_writerr   liner3   is_globally_capturingsepZresume_global_capturer   hookZpytest_leave_pdb
_continued)r6   r7   r8   tw)r9   r:   _pytestr;   r   r   r<   o   s    


z4pytestPDB._init_pdb.<locals>._PdbWrapper.do_continuec                s   t  |   td d S )NzQuitting debugger)r4   set_quitr   exit)r6   )r9   r:   r   r   rF      s    z1pytestPDB._init_pdb.<locals>._PdbWrapper.set_quitc                s4   t  | ||}|s0| jr0| jr0| jjdd |S )zSuspend on setup().

                    Needed after do_continue resumed, and entering another
                    breakpoint again.
                    T)r/   )r4   setuprC   r=   suspend_global_capture)r6   ftbr8   )r9   r:   r   r   rH      s
    
z.pytestPDB._init_pdb.<locals>._PdbWrapper.setup)__name__
__module____qualname__r=   rC   r5   r<   Zdo_cZdo_contrF   rH   __classcell__r   )r9   rE   capmanr;   )r:   r   r9   e   s   r9   )r+   r   )_pytest.configr   	getpluginrI   r+   r>   r   r?   r3   r   rA   r@   r   objectrB   Zpytest_enter_pdb)r;   argskwargsrD   r0   _pdbr   )r9   rE   rP   r;   r   	_init_pdbP   s&    

/
zpytestPDB._init_pdbc             O   s$   t  j}| j||}|| dS )zBInvoke debugging via ``Pdb.set_trace``, dropping any IO capturing.N)r#   	_getframef_backrW   r   )r;   rT   rU   framerV   r   r   r   r      s    
zpytestPDB.set_trace)rL   rM   rN   __doc__r   r   r   r%   r   r   r3   classmethodrW   r   r   r   r   r   r   G   s   Jr   c               @   s   e Zd Zdd Zdd ZdS )r)   c             C   sT   |j jd}|rB|jdd | \}}tj| tj| t||j	| d S )Nr.   T)r/   )
r+   r&   rR   rI   Zread_global_capturer#   stdoutwrite
_enter_pdbexcinfo)r6   nodeZcallZreportrP   outerrr   r   r   pytest_exception_interact   s    z#PdbInvoke.pytest_exception_interactc             C   s   t |}t| d S )N)_postmortem_tracebackpost_mortem)r6   Zexcreprr`   rK   r   r   r   pytest_internalerror   s    zPdbInvoke.pytest_internalerrorN)rL   rM   rN   rd   rg   r   r   r   r   r)      s   	r)   c               @   s   e Zd Zedddd ZdS )r(   T)Zhookwrapperc             c   s   t | d V  d S )N)_test_pytest_function)r6   
pyfuncitemr   r   r   pytest_pyfunc_call   s    zPdbTrace.pytest_pyfunc_callN)rL   rM   rN   r   rj   r   r   r   r   r(      s   r(   c             C   s   t  }| j}|j| _|  r@t| j}|d| t|| _n@d| j	j
krTtd|| jd< t| j	j
}|d t|| j	_
d S )Nr   funcz0--trace can't be used with a fixture named func!)r   rW   objZruncallZ_isyieldedfunctionlistZ_argsinserttupleZ_fixtureinfoZargnames
ValueErrorZfuncargsr*   )ri   rV   Ztestfunctionarg_listZnew_listr   r   r   rh      s    


rh   c             C   s   | j jdj}|  | j jj}xnd|jfd|jfd|j	ffD ]N\}}||dfkr@|r@|
dd|  |dd  d	kr|d d }|| q@W |
dd
 || |
dd t|}d|_t| |S )NZterminalreporterr]   stderrlogallr1   z	captured 
	tracebackzentering PDBT)r+   r&   rR   Z_twr?   ZoptionshowcaptureZ	capstdoutZ	capstderrZcaplogrA   Z
toterminalre   Z	_pdbshownrf   )ra   r`   ZreprD   rx   ZsectionnameZcontentrK   r   r   r   r_      s&    

r_   c             C   s&   t | jtr| jjd S | jd S d S )N   )
isinstancevaluer   exc_infoZ_excinfo)r`   r   r   r   re      s    re   c             C   s>   t dt| d }x&|r8| | d jddr8|d8 }qW |S )Nr   r2   Z__tracebackhide__F)maxlenf_localsget)stackir   r   r   _find_last_non_hidden_frame   s    r   c             C   s@   G dd dt j}| }|  |d |  |jr<td d S )Nc               @   s   e Zd Zdd ZdS )zpost_mortem.<locals>.Pdbc             S   s,   t j| ||\}}|d kr$t|}||fS )N)r   r%   	get_stackr   )r6   rJ   tr   r   r   r   r   r      s    z"post_mortem.<locals>.Pdb.get_stackN)rL   rM   rN   r   r   r   r   r   r%      s   r%   zQuitting debugger)r   r   resetZinteractionZquittingr   rG   )r   r%   pr   r   r   rf      s    rf   )r[   Z
__future__r   r   r   r   r#   Zdoctestr   rE   r   rQ   r   r   r-   rS   r   r)   r(   rh   r_   re   r   rf   r   r   r   r   <module>   s$   "[	