B
    Wc4                 @   s  d Z ddl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m	Z	 ddlm
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  er.ddl!m"Z" ddl#m$Z$ e%ee%e%f dddZ&eddddZ'edddd Z(G d!d" d"Z)G d#d$ d$Z*G d%d& d&Z+d'd( Z,d)d* Z-eee. e e d+d,d-Z/ee. ej0d.d/d0Z1ej0dd1d2d3Z2dS )4z4Interactive debugging with PDB, the Python Debugger.    N)Any)Callable)	Generator)List)Optional)Tuple)Type)TYPE_CHECKING)Union)outcomes)ExceptionInfo)Config)ConftestImportFailure)hookimpl)PytestPluginManager)Parser)
UsageError)Node)
BaseReport)CaptureManager)CallInfo)valuereturnc          
   C   sP   y|  d\}}W n4 tk
rF } zt| d|W dd}~X Y nX ||fS )z#Validate syntax of --pdbcls option.:z) is not in the format 'modname:classname'N)split
ValueErrorargparseZArgumentTypeError)r   modname	classnamee r    0lib/python3.7/site-packages/_pytest/debugging.py_validate_usepdb_cls!   s    
r"   )parserr   c             C   sF   |  d}|jddddd |jddd	td
d |jddddd d S )NZgeneralz--pdbusepdb
store_truezDStart the interactive Python debugger on errors or KeyboardInterrupt)destactionhelpz--pdbcls
usepdb_clszmodulename:classnamez{Specify a custom interactive Python debugger for use with --pdb.For example: --pdbcls=IPython.terminal.debugger:TerminalPdb)r&   metavartyper(   z--tracetracez(Immediately break when running each test)ZgetgroupZ
_addoptionr"   )r#   groupr    r    r!   pytest_addoption,   s"    
r.   )configr   c                s   dd l  | dr"| jt d | dr<| jt d tj j	tj
tjf tj	 _	| jt_
| t_d d fdd}| | d S )	Nr   r,   Zpdbtracer$   Z	pdbinvoke)r   c                  s   t j \ _t _t _d S )N)	pytestPDB_savedpop	set_trace_pluginmanager_configr    )pdbr    r!   finU   s    zpytest_configure.<locals>.fin)r6   getvaluepluginmanagerregisterPdbTrace	PdbInvoker0   r1   appendr3   r4   r5   Zadd_cleanup)r/   r7   r    )r6   r!   pytest_configureD   s    

r>   c               @   s   e Zd ZU dZdZee ed< dZee	 ed< g Z
eeed ee ee	 f  ed< dZdZeeee ee f  ed< eed	 eeef d
ddZeed	 dddZeed	 dddZedd ZeddddZdS )r0   z'Pseudo PDB that defers to the real pdb.Nr4   r5   ).Nr1   r   _wrapped_pdb_clsr   )capmanr   c             C   s   |r|  S dS )NF)Zis_capturing)clsr@   r    r    r!   _is_capturingj   s    zpytestPDB._is_capturing)r@   c          
   C   s
  | j sdd l}|jS | j d}| jr>| jd |kr>| jd S |r|\}}yNt| tj| }|d}t	||d }x|dd  D ]}	t	||	}qW W q t
k
r }
 z(d||f}td|d|
 |
W d d }
~
X Y qX ndd l}|j}| ||}||f| _|S )Nr   r)      .r   z--pdbcls: could not import z: )r5   r6   ZPdbr8   r?   
__import__sysmodulesr   getattr	Exceptionjoinr   _get_pdb_wrapper_class)rA   r@   r6   r)   r   r   modpartspdb_clspartexcr   Zwrapped_clsr    r    r!   _import_pdb_clsp   s2    



zpytestPDB._import_pdb_clsc                s$   dd l  G  fddd|}|S )Nr   c                   sl   e Zd ZZdZ fddZ fddZe ZZ fddZ	e	Z
e	Z fdd	Z fd
dZ  ZS )z:pytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapperFc                s,    j d7  _ t |} j d8  _ |S )NrC   )_recursive_debugsuperdo_debug)selfargret)	__class__rA   r    r!   rT      s    zCpytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapper.do_debugc                s   t  |}jdkrjd k	s$tjj}|  | j}t	
|}|r|dkrd|dd n|dd|  |d k	st|  n|dd jd k	stjjjj| d d| _|S )	Nr   global>z#PDB continue (IO-capturing resumed)z*PDB continue (IO-capturing resumed for %s)zPDB continue)r/   r6   T)rS   do_continuerR   r5   AssertionErrorr/   create_terminal_writerline_pytest_capmanr0   rB   sepZresumer4   hookZpytest_leave_pdb
_continued)rU   rV   rW   twr@   	capturing)rX   _pytestrA   r    r!   r[      s*    


zFpytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapper.do_continuec                s$   t  |}jdkr td |S )a  Raise Exit outcome when quit command is used in pdb.

                This is a bit of a hack - it would be better if BdbQuit
                could be handled, but this would require to wrap the
                whole pytest run, and adjust the report etc.
                r   zQuitting debugger)rS   do_quitrR   r   exit)rU   rV   rW   )rX   rA   r    r!   rf      s    

zBpytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapper.do_quitc                s0   t  ||}|s,| jr,| jr,| jjdd |S )zSuspend on setup().

                Needed after do_continue resumed, and entering another
                breakpoint again.
                T)in_)rS   setuprb   r_   suspend_global_capture)rU   ftbrW   )rX   r    r!   ri      s
    
z@pytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapper.setupc                s\   t  ||\}}|d krTtdt|d }x&|rR|| d jddrR|d8 }q.W ||fS )Nr   rC   Z__tracebackhide__F)rS   	get_stackmaxlenf_localsget)rU   rk   tstacki)rX   r    r!   rm      s    zDpytestPDB._get_pdb_wrapper_class.<locals>.PytestPdbWrapper.get_stack)__name__
__module____qualname__r_   rb   rT   r[   Zdo_cZdo_contrf   Zdo_qZdo_exitri   rm   __classcell__r    )re   r@   rA   )rX   r!   PytestPdbWrapper   s   ry   )_pytest.config)rA   rN   r@   ry   r    )re   r@   rA   r!   rK      s    Oz pytestPDB._get_pdb_wrapper_classc       
      O   s   ddl }| jdkrd}n| jd}|r4|jdd | jr|j| j}|  | jdkr|	dd}|dk	r||
d| nT| |}|dkr|
dd	| d
 n,|r|
dd||f  n|
dd	|  | |f |}	| jr| jjj| j|	d |	S )z4Initialize PDB debugging, dropping any IO capturing.r   NcapturemanagerT)rh   headerrZ   rY   zPDB z (IO-capturing turned off)z'PDB %s (IO-capturing turned off for %s))r/   r6   )rz   r4   	getpluginZsuspendr5   r/   r]   r^   rR   r2   r`   rB   rQ   ra   Zpytest_enter_pdb)
rA   methodargskwargsre   r@   rc   r|   rd   _pdbr    r    r!   	_init_pdb   s4    


zpytestPDB._init_pdb)r   c             O   s(   t  j}| jd||}|| dS )zBInvoke debugging via ``Pdb.set_trace``, dropping any IO capturing.r3   N)r3   )rF   	_getframef_backr   r3   )rA   r   r   framer   r    r    r!   r3     s    
zpytestPDB.set_trace)ru   rv   rw   __doc__r4   r   r   __annotations__r5   r   r1   r   r   r   rR   r?   r   r   classmethodr
   strboolrB   rQ   rK   r   r3   r    r    r    r!   r0   _   s   
& &V(r0   c               @   s4   e Zd ZededdddZee ddddZdS )	r<   zCallInfo[Any]N)nodecallreportr   c             C   sr   |j jd}|rB|jdd | \}}tj| tj| |jd k	sPt	t
|jjtjsnt||j| d S )Nr{   T)rh   )r/   r9   r}   rj   Zread_global_capturerF   stdoutwriteexcinfor\   
isinstancer   unittestZSkipTest
_enter_pdb)rU   r   r   r   r@   outerrr    r    r!   pytest_exception_interact  s    z#PdbInvoke.pytest_exception_interact)r   r   c             C   s   t |}t| d S )N)_postmortem_tracebackpost_mortem)rU   r   rl   r    r    r!   pytest_internalerror-  s    zPdbInvoke.pytest_internalerror)	ru   rv   rw   r   r   r   r   BaseExceptionr   r    r    r    r!   r<     s   r<   c               @   s(   e Zd Zedded dddZdS )r;   T)Zhookwrapper)NNN)r   c             c   s   t | d V  d S )N) wrap_pytest_function_for_tracing)rU   
pyfuncitemr    r    r!   pytest_pyfunc_call3  s    zPdbTrace.pytest_pyfunc_callN)ru   rv   rw   r   r   r   r    r    r    r!   r;   2  s   r;   c                s2   t d | jt fdd}|| _dS )zChange the Python function object of the given Function item by a
    wrapper which actually enters pdb before calling the python function
    itself, effectively leaving the user in the pdb prompt in the first
    statement of the function.runcallc                 s    t jf| |} | d S )N)	functoolspartialr   )r   r   func)r   testfunctionr    r!   wrapperD  s    z1wrap_pytest_function_for_tracing.<locals>.wrapperN)r0   r   objr   wraps)r   r   r    )r   r   r!   r   9  s    
r   c             C   s   | j drt|  dS )zaWrap the given pytestfunct item for tracing support if --trace was given in
    the command line.r,   N)r/   r8   r   )r   r    r    r!   &maybe_wrap_pytest_function_for_tracingL  s    r   )r   r   repr   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allrZ   z	captured 
	tracebackzentering PDBT)r/   r9   r}   Z_twr^   ZoptionshowcaptureZ	capstdoutZ	capstderrZcaplogr`   Z
toterminalr   Z	_pdbshownr   )r   r   r   rc   r   ZsectionnameZcontentrl   r    r    r!   r   S  s&    

r   )r   r   c             C   sX   ddl m} t| j|r$| jjd S t| jtr<| jjd S | jd k	sJt| jd S d S )Nr   )UnexpectedException   )	Zdoctestr   r   r   exc_infor   r   Z_excinfor\   )r   r   r    r    r!   r   r  s    r   )rr   r   c             C   s2   t d}|  |d |  |jr.td d S )Nr   zQuitting debugger)r0   r   resetZinteractionZquittingr   rg   )rr   pr    r    r!   r     s
    
r   )3r   r   r   rF   typesr   typingr   r   r   r   r   r   r   r	   r
   re   r   Z_pytest._coder   rz   r   r   r   r   Z_pytest.config.argparsingr   Z_pytest.config.exceptionsr   Z_pytest.nodesr   Z_pytest.reportsr   Z_pytest.capturer   Z_pytest.runnerr   r   r"   r.   r>   r0   r<   r;   r   r   r   r   TracebackTyper   r   r    r    r    r!   <module>   sP    @
