o
    i e                     @   sL   d Z ddlZddlZddlZddlZG dd deZG dd dejeZ	dS )zRun doctests for Keras.    Nc                   @   s4   e Zd ZdZedjdddddejZdd	 Z	d
S )_FloatExtractorzClass for extracting floats from a string.

    For example:

    >>> text_parts, floats = _FloatExtractor()("Text 1.0 Text")
    >>> text_parts
    ['Text ', ' Text']
    >>> floats
    array([1.])
    a  
      (                          # Captures the float value.
        (?:
           [-+]|                 # Start with a sign is okay anywhere.
           (?:                   # Otherwise:
               ^|                # Start after the start of string
               (?<=[^\w.])       # Not after a word char, or a .
           )
        )
        (?:                      # Digits and exponent - something like:
          {digits_dot_maybe_digits}{exponent}?|   # "1.0" "1." "1.0e3", "1.e3"
          {dot_digits}{exponent}?|                # ".1" ".1e3"
          {digits}{exponent}|                     # "1e3"
          {digits}(?=j)                           # "300j"
        )
      )
      j?                         # Optional j for cplx numbers, not captured.
      (?=                        # Only accept the match if
        $|                       # * At the end of the string, or
        [^\w.]                   # * Next char is not a word char or "."
      )
      z(?:[0-9]+\.(?:[0-9]*))z(?:\.[0-9]+)z
(?:[0-9]+)z(?:[eE][-+]?[0-9]+))digits_dot_maybe_digits
dot_digitsdigitsexponentc                 C   sV   g }g }t | j|D ]\}}|d dkr|| q|t| q|t|fS )a  Extracts floats from a string.

        >>> text_parts, floats = _FloatExtractor()("Text 1.0 Text")
        >>> text_parts
        ['Text ', ' Text']
        >>> floats
        array([1.])

        Args:
          string: the string to extract floats from.

        Returns:
          A (string, array) pair, where `string` has each float replaced by
          "..." and `array` is a `float32` `numpy.array` containing the
          extracted floats.
           r   )	enumerate	_FLOAT_REsplitappendfloatnparray)selfstringtextsfloatsipart r   X/var/www/myenv/lib/python3.10/site-packages/keras/src/testing_infra/keras_doctest_lib.py__call__J   s   z_FloatExtractor.__call__N)
__name__
__module____qualname____doc__recompileformatVERBOSEr	   r   r   r   r   r   r      s     $r   c                       sl   e Zd ZdZ fddZedZedejZ	dddZ
d	d
 ZedZ fddZ fddZ  ZS )KerasDoctestOutputCheckerzACustomizes how `want` and `got` are compared, see `check_output`.c                    s*   t  j|i | t | _d | _d | _d S )N)super__init__r   extract_floats	text_goodfloat_size_good)r   argskwargs	__class__r   r   r"   i   s   
z"KerasDoctestOutputChecker.__init__z\bat 0x[0-9a-f]*?>z<tf.Tensor.*?numpy=(.*?)>MbP?c                 C   s   t j||||dS )N)rtolatol)r   allclose)r   wantgotr+   r,   r   r   r   	_allcloset   s   z#KerasDoctestOutputChecker._allclosec                 C   s   | j d|}|||kfS )Nz\1)_NUMPY_OUTPUT_REsub)r   r   modified_stringr   r   r   _tf_tensor_numpy_outputw   s   z1KerasDoctestOutputChecker._tf_tensor_numpy_outputz

        #############################################################
        Check the documentation (go/testable-docstrings) on how to
        write testable docstrings.
        #############################################################c                    s   |r|sdS |du rd}| j d|}| |\}}|r#| |\}}| |\}| _d|}| |\}| _t j|||d| _	| j	sGdS | jj
dkrOdS | jj
| jj
k| _| jrc| | j| jS dS )	a  Compares the docstring output to the output gotten by running the
        code.

        Python addresses in the output are replaced with wildcards.

        Float values in the output compared as using `np.allclose`:

          * Float values are extracted from the text and replaced with
            wildcards.
          * The wildcard text is compared to the actual output.
          * The float values are compared using `np.allclose`.

        The method returns `True` if both the text comparison and the numeric
        comparison are successful.

        The numeric comparison will fail if either:

          * The wrong number of floats are found.
          * The float values are not within tolerence.

        Args:
          want: The output in the docstring.
          got: The output generated after running the snippet.
          optionflags: Flags passed to the doctest.

        Returns:
          A bool, indicating if the check was successful or not.
        TN zat ...>z...)r.   r/   optionflagsFr   )_ADDRESS_REr2   r4   r#   want_floatsjoin
got_floatsr!   check_outputr$   sizer%   r0   )r   r.   r/   r6   want_changed_want_text_partswant_text_wildr(   r   r   r;      s,   "
z&KerasDoctestOutputChecker.check_outputc                    sB   |g}| j r| js|d || j d|}t |||S )NzZ

CAUTION: tf_doctest doesn't work if *some* of the *float output* is hidden with a "...".
)r$   r%   r   MESSAGEr9   r!   output_difference)r   exampler/   r6   r(   r   r   rC      s   
z+KerasDoctestOutputChecker.output_difference)r*   r*   )r   r   r   r   r"   r   r   r7   DOTALLr1   r0   r4   textwrapdedentrB   r;   rC   __classcell__r   r   r(   r   r    f   s    

Lr    )
r   doctestr   rF   numpyr   objectr   OutputCheckerr    r   r   r   r   <module>   s   N