B
    ܇\RI                 @   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ZddlZddl	m
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ZdZdZdZdZeeeeefZdadd Zdd Zdd Zdd ZG dd deZG dd de Z!dd Z"dDd d!Z#G d"d# d#ej$Z%d$d% Z&d&d' Z'd(d) Z(G d*d+ d+ej)Z*d,d- Z+d.d/ Z,e
d0d1 Z-G d2d3 d3ej)Z.d4d5 Z/d6d7 Z0d8d9 Z1d:d; Z2d<d= Z3d>d? Z4ej5d@dAdBdC Z6dS )Ez5 discover and run doctests in modules and test files.    )absolute_import)division)print_functionN)contextmanager)ExceptionInfo)ReprFileLocation)TerminalRepr)safe_getattr)FixtureRequestZnoneZcdiffZndiffudiffZonly_first_failurec             C   s   | j ddddgd | j dddd	 | d
}|jdddddd |jdtjddtdd |jddg dddd |jdddddd |jdddd d!d d S )"Ndoctest_optionflagszoption flags for doctestsargsELLIPSIS)typedefaultdoctest_encodingzencoding used for doctest fileszutf-8)r   collectz--doctest-modules
store_trueFzrun doctests in all .py modulesdoctestmodules)actionr   helpdestz--doctest-reportr   z9choose another output format for diffs on doctest failuredoctestreport)r   r   r   choicesr   z--doctest-globappendZpatz2doctests file matching pattern, default: test*.txtdoctestglob)r   r   metavarr   r   z--doctest-ignore-import-errorszignore doctest ImportErrorsdoctest_ignore_import_errorsz--doctest-continue-on-failurez<for a given doctest, continue to run after the first failuredoctest_continue_on_failure)ZaddiniZgetgroupZ	addoptionstrlowerDOCTEST_REPORT_CHOICES)parsergroup r$   .lib/python3.7/site-packages/_pytest/doctest.pypytest_addoption%   sP    

r&   c             C   sJ   |j }| jdkr0|jjrFt|| |sFt| |S nt|| |rFt| |S d S )Nz.py)configextZoptionr   _is_setup_pyDoctestModule_is_doctestDoctestTextfile)pathparentr'   r$   r$   r%   pytest_collect_fileW   s    
r/   c             C   s&   |j dkrdS | }d|kp$d|kS )Nzsetup.pyFZ
setuptoolsZ	distutils)basenameread)r'   r-   r.   contentsr$   r$   r%   r)   `   s    
r)   c             C   sL   |j dkr|j|rdS | dp(dg}x|D ]}|j|dr0dS q0W dS )N)z.txtz.rstTr   z	test*.txt)ZfnmatchF)r(   sessionZ
isinitpath	getoptionZcheck)r'   r-   r.   globsZglobr$   r$   r%   r+   g   s    
r+   c               @   s   e Zd Zdd Zdd ZdS )ReprFailDoctestc             C   s
   || _ d S )N)reprlocation_lines)selfr7   r$   r$   r%   __init__r   s    zReprFailDoctest.__init__c             C   s:   x4| j D ]*\}}x|D ]}|| qW || qW d S )N)r7   line
toterminal)r8   Ztwreprlocationlinesr:   r$   r$   r%   r;   v   s    
zReprFailDoctest.toterminalN)__name__
__module____qualname__r9   r;   r$   r$   r$   r%   r6   q   s   r6   c                   s   e Zd Z fddZ  ZS )MultipleDoctestFailuresc                s   t t|   || _d S )N)superrA   r9   failures)r8   rC   )	__class__r$   r%   r9   ~   s    z MultipleDoctestFailures.__init__)r>   r?   r@   r9   __classcell__r$   r$   )rD   r%   rA   }   s   rA   c                 s"   dd l  G  fddd j} | S )Nr   c                   s6   e Zd ZdZd fdd	Z fddZ fd	d
ZdS )z/_init_runner_class.<locals>.PytestDoctestRunnerz
        Runner to collect failures.  Note that the out variable in this case is
        a list instead of a stdout-like object
        Nr   Tc                s    j j| |||d || _d S )N)checkerverboseoptionflags)DebugRunnerr9   continue_on_failure)r8   rF   rG   rH   rJ   )doctestr$   r%   r9      s    z8_init_runner_class.<locals>.PytestDoctestRunner.__init__c                s(     |||}| jr || n|d S )N)DocTestFailurerJ   r   )r8   outtestexamplegotfailure)rK   r$   r%   report_failure   s    z>_init_runner_class.<locals>.PytestDoctestRunner.report_failurec                s(     |||}| jr || n|d S )N)UnexpectedExceptionrJ   r   )r8   rM   rN   rO   exc_inforQ   )rK   r$   r%   report_unexpected_exception   s    zK_init_runner_class.<locals>.PytestDoctestRunner.report_unexpected_exception)NNr   T)r>   r?   r@   __doc__r9   rR   rU   r$   )rK   r$   r%   PytestDoctestRunner   s   rW   )rK   rI   )rW   r$   )rK   r%   _init_runner_class   s    rX   Tc             C   s   t d krt a t | |||dS )N)rF   rG   rH   rJ   )RUNNER_CLASSrX   )rF   rG   rH   rJ   r$   r$   r%   _get_runner   s    rZ   c                   sJ   e Zd Zd fdd	Zdd Zdd Zdd	 Z fd
dZdd Z  Z	S )DoctestItemNc                s.   t t| || || _|| _d | _d | _d S )N)rB   r[   r9   runnerdtestobjfixture_request)r8   namer.   r\   r]   )rD   r$   r%   r9      s
    zDoctestItem.__init__c             C   sZ   | j d k	rVt| | _t| jjd}x$| jd D ]\}}|||< q4W | j j| d S )N)Z
getfixturedoctest_namespace)r]   _setup_fixturesr_   dictZgetfixturevalueitemsr5   update)r8   r5   r`   valuer$   r$   r%   setup   s    

zDoctestItem.setupc             C   s8   t | j |   g }| jj| j|d |r4t|d S )N)rM   )_check_all_skippedr]   $_disable_output_capturing_for_darwinr\   runrA   )r8   rC   r$   r$   r%   runtest   s    
zDoctestItem.runtestc             C   sV   t  dkrdS | jjd}|rR|jdd | \}}tj	| tj
	| dS )zW
        Disable output capturing. Otherwise, stdout is lost to doctest (#985)
        ZDarwinNZcapturemanagerT)Zin_)platformsystemr'   pluginmanagerZ	getpluginZsuspend_global_captureZread_global_capturesysstdoutwritestderr)r8   ZcapmanrM   errr$   r$   r%   ri      s    z0DoctestItem._disable_output_capturing_for_darwinc                s  dd l }d }||j|jfr(|jg}n|tr:|jj}|d k	rg }xV|D ]L}|j}|j  j	} j
d krxd }n j
|j
 d }t|j}	t|||	}
t }t| jd}|d k	r|jjd} fddt|D }|t|j
d d|j
d  }n6dg}d	}x*|j D ]}|d
||f  d}qW t||jrb||||j|d7 }n.t|j}|dt|j g7 }|tj |j 7 }||
|f qPW t!|S t"t#| $|S d S )Nr      r   Fc                s&   g | ]\}}d | j  d |f qS )z%03d %srt   )lineno).0ix)rN   r$   r%   
<listcomp>   s   z,DoctestItem.repr_failure.<locals>.<listcomp>	   z?EXAMPLE LOCATION UNKNOWN, not showing all tests of that examplez>>>z	??? %s %sz...
zUNEXPECTED EXCEPTION: %s)%rK   ZerrisinstancerL   rS   rf   rA   rC   rO   rN   filenameru   r   r>   r   _get_checker_get_report_choicer'   r4   Z	docstring
splitlines	enumeratemaxsourcer   
isinstanceZoutput_differencerP   splitr   rT   repr	tracebackformat_exceptionr6   rB   r[   repr_failure)r8   excinforK   rC   r7   rQ   rO   r|   ru   messager<   rF   Zreport_choicer=   indentr:   Zinner_excinfo)rD   )rN   r%   r      sP    






 


zDoctestItem.repr_failurec             C   s   | j | jjd| j fS )Nz[doctest] %s)fspathr]   ru   r`   )r8   r$   r$   r%   
reportinfo  s    zDoctestItem.reportinfo)NN)
r>   r?   r@   r9   rg   rk   ri   r   r   rE   r$   r$   )rD   r%   r[      s   
7r[   c           
   C   s0   dd l } t| j| j| j| j| j| jt t	 dS )Nr   )DONT_ACCEPT_TRUE_FOR_1DONT_ACCEPT_BLANKLINENORMALIZE_WHITESPACEr   IGNORE_EXCEPTION_DETAILCOMPARISON_FLAGSALLOW_UNICODEALLOW_BYTES)
rK   rc   r   r   r   r   r   r   _get_allow_unicode_flag_get_allow_bytes_flag)rK   r$   r$   r%   _get_flag_lookup  s    r   c             C   s4   | j d}t }d}x|D ]}||| O }qW |S )Nr   r   )r'   getinir   )r.   Zoptionflags_strZflag_lookup_tableZflag_accflagr$   r$   r%   get_optionflags#  s    
r   c             C   s    |  d}|r|  drd}|S )Nr   ZusepdbF)getvalue)r'   rJ   r$   r$   r%   _get_continue_on_failure,  s
    

r   c               @   s   e Zd ZdZdd ZdS )r,   Nc             c   s   dd l }| jd}| j|}t| j}| jj}ddi}t| }td|t	 t
| jd}t|| | }	|	||||d}
|
jrt|
j| ||
V  d S )Nr   r   r>   __main__)rG   rH   rF   rJ   )rK   r'   r   r   Z	read_textr   r0   r   rZ   r}   r   _fix_spoof_python2ZDocTestParserZget_doctestexamplesr[   r`   )r8   rK   encodingtextr|   r`   r5   rH   r\   r"   rN   r$   r$   r%   r   9  s"    

zDoctestTextfile.collect)r>   r?   r@   r^   r   r$   r$   r$   r%   r,   6  s   r,   c                s2   ddl  t fdd| jD }|r.td dS )z\raises pytest.skip() if all examples in the given DocTest have the SKIP
    option set.
    r   Nc             3   s   | ]}|j  jd V  qdS )FN)ZoptionsgetZSKIP)rv   rx   )rK   r$   r%   	<genexpr>Z  s    z%_check_all_skipped.<locals>.<genexpr>z!all tests skipped by +SKIP option)rK   allr   pytestskip)rN   Zall_skippedr$   )rK   r%   rh   T  s    rh   c             C   s   t | dddk	S )zr
    returns if a object is possibly a mock object by checking the existence of a highly improbable attribute
    Z1pytest_mock_example_attribute_that_shouldnt_existN)r	   )r^   r$   r$   r%   
_is_mocked_  s    
r   c              #   sH   t tdd  dkrdV  n(d fdd	} | t_z
dV  W d t_X dS )z
    contextmanager which replaces ``inspect.unwrap`` with a version
    that's aware of mock objects and doesn't recurse on them
    unwrapNc                s,    d kr| t dS |  fdddS d S )N)stopc                s   t | p | S )N)r   )r^   )r   r$   r%   <lambda>x  s    zF_patch_unwrap_mock_aware.<locals>._mock_aware_unwrap.<locals>.<lambda>)r   )r^   r   )real_unwrap)r   r%   _mock_aware_unwrapt  s    z4_patch_unwrap_mock_aware.<locals>._mock_aware_unwrap)N)getattrinspectr   )r   r$   )r   r%   _patch_unwrap_mock_awarei  s    
r   c               @   s   e Zd Zdd ZdS )r*   c             #   s   dd l  G  fddd j}| jjdkr<| jj| j}nDy| j }W n4 tk
r~   | j	drxt
d| j  n Y nX | }t| }td|t t| jd}x.|||jD ]}|jrt|j| ||V  qW d S )Nr   c                   s   e Zd ZdZ fddZdS )z5DoctestModule.collect.<locals>.MockAwareDocTestFinderz
            a hackish doctest finder that overrides stdlib internals to fix a stdlib bug

            https://github.com/pytest-dev/pytest/issues/3456
            https://bugs.python.org/issue25532
            c                s<   t |rd S t    j| ||||||| W d Q R X d S )N)r   r   DocTestFinder_find)r8   Ztestsr^   r`   moduleZsource_linesr5   seen)rK   r$   r%   r     s
    z;DoctestModule.collect.<locals>.MockAwareDocTestFinder._findN)r>   r?   r@   rV   r   r$   )rK   r$   r%   MockAwareDocTestFinder  s   r   zconftest.pyr   zunable to import module %r)rG   rH   rF   rJ   )rK   r   r   r0   r'   rn   Z_importconftestZpyimportImportErrorr   r   r   r   rZ   r}   r   findr>   r   r[   r`   )r8   r   r   finderrH   r\   rN   r$   )rK   r%   r     s(    zDoctestModule.collectN)r>   r?   r@   r   r$   r$   r$   r%   r*     s   r*   c             C   s>   dd }i | _ | jj}|j| |ddd| _t| }|  |S )zO
    Used by DoctestTextfile and DoctestItem to setup fixture information.
    c               S   s   d S )Nr$   r$   r$   r$   r%   func  s    z_setup_fixtures.<locals>.funcNF)Znoder   clsfuncargs)r   r3   Z_fixturemanagerZgetfixtureinfoZ_fixtureinfor
   Z_fillfixtures)Zdoctest_itemr   Zfmr_   r$   r$   r%   rb     s    rb   c                 sH   t tdrt S ddl ddlG  fddd j} | t_t S )aJ  
    Returns a doctest.OutputChecker subclass that takes in account the
    ALLOW_UNICODE option to ignore u'' prefixes in strings and ALLOW_BYTES
    to strip b'' prefixes.
    Useful when the same doctest should run in Python 2 and Python 3.

    An inner class is used to avoid importing "doctest" at the module
    level.
    LiteralsOutputCheckerr   Nc                   s:   e Zd ZdZdjZdjZ fddZdS )z+_get_checker.<locals>.LiteralsOutputCheckerz
        Copied from doctest_nose_plugin.py from the nltk project:
            https://github.com/nltk/nltk

        Further extended to also support byte literals.
        z(\W|^)[uU]([rR]?[\'\"])z(\W|^)[bB]([rR]?[\'\"])c                s    j | |||}|rdS |t @ }|t @ }|s:|s:dS fdd}|rb|| j|}|| j|}|r~|| j|}|| j|} j | |||}|S d S )NTFc                s     | d|S )Nz\1\2)sub)ZregexZtxt)rer$   r%   remove_prefixes  s    zQ_get_checker.<locals>.LiteralsOutputChecker.check_output.<locals>.remove_prefixes)OutputCheckercheck_outputr   r   _unicode_literal_re_bytes_literal_re)r8   ZwantrP   rH   ZresZallow_unicodeZallow_bytesr   )rK   r   r$   r%   r     s     

z8_get_checker.<locals>.LiteralsOutputChecker.check_outputN)	r>   r?   r@   rV   compileUNICODEr   r   r   r$   )rK   r   r$   r%   r     s   )hasattrr}   r   rK   r   r   )r   r$   )rK   r   r%   r}     s    

#r}   c              C   s   ddl } | dS )z7
    Registers and returns the ALLOW_UNICODE flag.
    r   Nr   )rK   register_optionflag)rK   r$   r$   r%   r     s    r   c              C   s   ddl } | dS )z5
    Registers and returns the ALLOW_BYTES flag.
    r   Nr   )rK   r   )rK   r$   r$   r%   r     s    r   c          
   C   s,   ddl }t|jt|jt|jt|jt	di|  S )z
    This function returns the actual `doctest` module flag value, we want to do it as late as possible to avoid
    importing `doctest` and all its dependencies when parsing options, as it adds overhead and breaks tests.
    r   N)
rK   DOCTEST_REPORT_CHOICE_UDIFFZREPORT_UDIFFDOCTEST_REPORT_CHOICE_CDIFFZREPORT_CDIFFDOCTEST_REPORT_CHOICE_NDIFFZREPORT_NDIFF(DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILUREZREPORT_ONLY_FIRST_FAILUREDOCTEST_REPORT_CHOICE_NONE)keyrK   r$   r$   r%   r~   
  s    r~   c                sB   ddl m} |sdS ddlm  G  fddd }| | _dS )a  
    Installs a "SpoofOut" into the given DebugRunner so it properly deals with unicode output. This
    should patch only doctests for text files because they don't have a way to declare their
    encoding. Doctests in docstrings from Python modules don't have the same problem given that
    Python already decoded the strings.

    This fixes the problem related in issue #2434.
    r   )_PY2N)	_SpoofOutc                   s   e Zd Z fddZdS )z(_fix_spoof_python2.<locals>.UnicodeSpoofc                s&     | }r"t|tr"|}|S )N)r   r   bytesdecode)r8   result)r   r   r$   r%   r   +  s    

z1_fix_spoof_python2.<locals>.UnicodeSpoof.getvalueN)r>   r?   r@   r   r$   )r   r   r$   r%   UnicodeSpoof*  s   r   )_pytest.compatr   rK   r   Z_fakeout)r\   r   r   r   r$   )r   r   r%   r     s    	r   r3   )Zscopec               C   s   t  S )zg
    Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests.
    )rc   r$   r$   r$   r%   ra   4  s    ra   )NNr   T)7rV   Z
__future__r   r   r   r   rl   ro   r   
contextlibr   r   Z_pytest._code.coder   r   r   r   r	   Z_pytest.fixturesr
   r   r   r   r   r   r!   rY   r&   r/   r)   r+   r6   	ExceptionrA   rX   rZ   ZItemr[   r   r   r   ZModuler,   rh   r   r   r*   rb   r}   r   r   r~   r   Zfixturera   r$   r$   r$   r%   <module>   sb   2	
"
b	

.7		