o
    ˷es.                     @   s   d Z ddlZddlZddlZddlZddlmZ eeZ	G dd dej
Z
G dd dejZG dd	 d	ejZG d
d dejZedZG dd dejeZdS )a  Nose Plugin that supports IPython doctests.

Limitations:

- When generating examples for use as doctests, make sure that you have
  pretty-printing OFF.  This can be done either by setting the
  ``PlainTextFormatter.pprint`` option in your configuration file to  False, or
  by interactively disabling it with  %Pprint.  This is required so that IPython
  output matches that of normal Python, which is used by doctest for internal
  execution.

- Do not rely on specific prompt numbers for results (such as using
  '_34==True', for example).  For IPython tests run via an external process the
  prompt numbers may be different, and IPython tests run as normal python code
  won't even have these special _NN variables set at all.
    N)modified_envc                       s   e Zd Z fddZ  ZS )DocTestFinderc                    sH   t  |||||}tt|ddr"|d ur"|jD ]}d|jtj< q|S )N__skip_doctest__FT)super	_get_testboolgetattrexamplesoptionsdoctestSKIP)selfobjnamemoduleglobssource_linestestexample	__class__ W/var/www/ideatree/venv/lib/python3.10/site-packages/IPython/testing/plugin/ipdoctest.pyr   *   s
   
zDocTestFinder._get_test)__name__
__module____qualname__r   __classcell__r   r   r   r   r   )   s    r   c                   @   s"   e Zd ZdZedZdd ZdS )IPDoctestOutputCheckerzSecond-chance checker with support for random tests.

    If the default comparison doesn't pass, this checker looks in the expected
    output string for flags that tell us to ignore the output.
    z#\s*random\s+c                 C   s*   t j| |||}|s| j|rdS |S )zCheck output, accepting special markers embedded in the output.

        If the output didn't pass the default validation but the special string
        '#random' is included, we accept it.T)r   OutputCheckercheck_output	random_research)r   wantgotoptionflagsretr   r   r   r   =   s   z#IPDoctestOutputChecker.check_outputN)r   r   r   __doc__recompiler    r   r   r   r   r   r   4   s    
r   c                   @   s   e Zd ZdS )	IPExampleN)r   r   r   r   r   r   r   r)   P   s    r)   c                   @   s   e Zd ZdZdZdZdZdZdZe	
eeeeef e	je	jB Ze	
eeeeef e	je	jB Ze	
dZdd	 ZdddZdddZdd ZdS )IPDocTestParserz
    A class used to parse strings containing doctest examples.

    Note: This is a version modified to properly recognize IPython input and
    convert any IPython examples into valid Python ones.
    z>>>z\.\.\.zIn\ \[\d+\]:z\ \ \ \.\.\.+:a]  
        # Source consists of a PS1 line followed by zero or more PS2 lines.
        (?P<source>
            (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*)    # PS1 line
            (?:\n           [ ]*  (?P<ps2> %s) .*)*)  # PS2 lines
        \n? # a newline
        # Want consists of any non-blank lines that do not start with PS1.
        (?P<want> (?:(?![ ]*$)    # Not a blank line
                     (?![ ]*%s)   # Not a line starting with PS1
                     (?![ ]*%s)   # Not a line starting with PS2
                     .*$\n?       # But any other line
                  )*)
                  z#\s*all-random\s+c                 C   s*   t j|}t| dkrt |S |S )z/Convert input IPython source into valid Python.   )_ipinput_transformer_managertransform_celllen
splitlines	prefilter)r   sourceblockr   r   r   ip2py   s   
zIPDocTestParser.ip2py<string>c                    sR  |  }| |  dkrd fdd|dD }g }d\}}| j|r+d}nd}d}t| j|}|r=t	j
}	nt| j|}t}	d	}|D ]R}
||||
   ||d||
 7 }| |
|||\}}}}||7 }| |s||	|||| t|
d
 |d ||d|
 |
 7 }|
 }qK|||d  |S )a=  
        Divide the given string into examples and intervening text,
        and return them as a list of alternating Examples and strings.
        Line numbers for the Examples are 0-based.  The optional
        argument `name` is a name identifying this string, and is only
        used for error messages.
        r   
c                       g | ]}| d  qS Nr   ).0l
min_indentr   r   
<listcomp>       z)IPDocTestParser.parse.<locals>.<listcomp>)r   r   z	
# random FTindent)linenor@   r
   N)
expandtabs_min_indentjoinsplit_RANDOM_TESTr!   list_EXAMPLE_RE_PYfinditerr   Example_EXAMPLE_RE_IPr)   appendstartcount_parse_example_IS_BLANK_OR_COMMENTr/   groupend)r   stringr   outputcharnorA   random_markerr4   termsrJ   mr2   r
   r"   exc_msgr   r;   r   parse   s@   



zIPDocTestParser.parseFc                    sR  t |d |dd}|d}|d}t || | || |r8| |dd d  | || d fd	d
|D }|rL| |}|d}	|	d}
t |
dkrgtd|
d rg|
d= | |
d  ||t |  t	dd|
d |
d< d fdd
|
D }	| j
|	}|r|d}nd}| |||}|||	|fS )a7  
        Given a regular expression match from `_EXAMPLE_RE` (`m`),
        return a pair `(source, want)`, where `source` is the matched
        example's source code (with prompts and indentation stripped);
        and `want` is the example's expected output (with indentation
        stripped).

        `name` is the string's name, and `lineno` is the line number
        where the example starts; both are used for error messages.

        Optional:
        `ip2py`: if true, filter the input via IPython to convert the syntax
        into valid python.
        r@   r2   r6   ps1ps2r+   N c                    s    g | ]}|  d  d qS )r+   Nr   )r9   slr@   ps1_lenr   r   r=      s     z2IPDocTestParser._parse_example.<locals>.<listcomp>r"   z *$zOut\[\d+\]: \s*?\n?r?   r   c                    r7   r8   r   )r9   wl)r@   r   r   r=      r>   msg)r/   rQ   rE   _check_prompt_blank_check_prefixrD   r4   r'   matchsub_EXCEPTION_RE_find_options)r   rX   r   rA   r4   r   r[   r\   r2   r"   
want_linesrY   r
   r   r_   r   rO      s4   

 



zIPDocTestParser._parse_examplec           
      C   sb   || }|d }t |D ]"\}}	t|	|kr.|	| dkr.td|| d ||	|| |	f qdS )a  
        Given the lines of a source string (including prompts and
        leading indentation), check to make sure that every prompt is
        followed by a space character.  If any line is not followed by
        a space character, then raise ValueError.

        Note: IPython-modified version which takes the input prompt length as a
        parameter, so that prompts of variable length can be dealt with.
        r+   r]   z8line %r of the docstring for %s lacks blank after %s: %rN)	enumerater/   
ValueError)
r   linesr@   r   rA   r`   	space_idxmin_leniliner   r   r   rd     s   
z#IPDocTestParser._check_prompt_blankN)r5   )F)r   r   r   r&   _PS1_PY_PS2_PY_PS1_IP_PS2_IP_RE_TPLr'   r(   	MULTILINEVERBOSErH   rK   rF   r4   rZ   rO   rd   r   r   r   r   r*   S   s$    




DAr*   r   c                       s"   e Zd ZdZd fdd	Z  ZS )IPDocTestRunnerzKTest runner that synchronizes the IPython namespace with test globals.
    NTc                    sH   t ddd tt| ||||W  d    S 1 sw   Y  d S )N8024)COLUMNSLINES)r   r   ry   run)r   r   compileflagsoutclear_globsr   r   r   r~   (  s
   $zIPDocTestRunner.run)NNT)r   r   r   r&   r~   r   r   r   r   r   ry   $  s    ry   )r&   r   loggingosr'   testpathr   	getLoggerr   logr   r   r   rJ   r)   DocTestParserr*   register_optionflagr   DocTestRunnerobjectry   r   r   r   r   <module>   s    
 
O