o
    Zhp.                     @   s   d 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 )NZ__skip_doctest__FT)super	_get_testboolgetattrZexamplesoptionsdoctestSKIP)selfobjnamemoduleglobssource_linestestZexample	__class__ W/var/www/html/lang_env/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gotZoptionflagsretr   r   r   r   <   s   z#IPDoctestOutputChecker.check_outputN)r   r   r   __doc__recompiler   r   r   r   r   r   r   3   s    
r   c                   @   s   e Zd ZdS )	IPExampleN)r   r   r   r   r   r   r   r%   O   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.   )_ipZinput_transformer_managerZtransform_celllen
splitlinesZ	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Z
min_indentr   r   
<listcomp>       z)IPDocTestParser.parse.<locals>.<listcomp>)r   r   z	
# random FTindent)linenor8   r   N)
expandtabsZ_min_indentjoinsplit_RANDOM_TESTr   list_EXAMPLE_RE_PYfinditerr	   Example_EXAMPLE_RE_IPr%   appendstartcount_parse_exampleZ_IS_BLANK_OR_COMMENTr)   groupend)r   stringr   outputZcharnor9   Zrandom_markerr-   ZtermsrA   mr+   r   r   exc_msgr   r4   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.
        r8   r+   r/   ps1ps2r'   N c                    s    g | ]}|  d  d qS )r'   Nr   )r2   slr8   ps1_lenr   r   r5      s     z2IPDocTestParser._parse_example.<locals>.<listcomp>r   z *$zOut\[\d+\]: \s*?\n?r7   r   c                    r0   r1   r   )r2   Zwl)r8   r   r   r5      r6   msg)r)   rG   r<   _check_prompt_blankZ_check_prefixr;   r-   r#   matchsubZ_EXCEPTION_REZ_find_options)r   rK   r   r9   r-   r   rN   rO   r+   r   Z
want_linesrL   r   r   rR   r   rF      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'   rP   z8line %r of the docstring for %s lacks blank after %s: %rN)	enumerater)   
ValueError)
r   linesr8   r   r9   rS   Z	space_idxmin_leniliner   r   r   rV     s   
z#IPDocTestParser._check_prompt_blankN)r.   )F)r   r   r   r"   Z_PS1_PYZ_PS2_PYZ_PS1_IPZ_PS2_IPZ_RE_TPLr#   r$   	MULTILINEVERBOSEr?   rB   r=   r-   rM   rF   rV   r   r   r   r   r&   R   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80Z24)COLUMNSLINES)r   r   ra   run)r   r   ZcompileflagsoutZclear_globsr   r   r   re   '  s
   $zIPDocTestRunner.run)NNT)r   r   r   r"   re   r   r   r   r   r   ra   #  s    ra   )r"   r	   loggingr#   Ztestpathr   	getLoggerr   logr   r   r   rA   r%   ZDocTestParserr&   Zregister_optionflagr
   ZDocTestRunnerobjectra   r   r   r   r   <module>   s    
 
O