o
    i&I                     @   s  d dl Z d dlm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	Z	d dl
Z
d dlZd dlZzd dl mZ W n eyG   d dl mZ Y nw 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mZmZ d
dlmZ e j dd Z!G dd dej"Z#d-ddZ$dd Z%dd Z&dd Z'dd Z(dd Z)dd Z*G dd  d Z+d!d" Z,	 	#		$d.d%d&Z-d'd d(d)d*Z.d+d, Z/dS )/    NStrictVersion)Path)nullcontext)	ExitStack)cbook)ft2font)pyplot)ticker   )comparable_formatscompare_imagesmake_test_filename)ImageComparisonFailurec               	   c   s    t jj } zUt  t   d V  W d    n1 sw   Y  W d    n1 s.w   Y  W t jj  t jj|  t	
d d S W t jj  t jj|  t	
d d S t jj  t jj|  t	
d w )Nall)
matplotlibunitsregistrycopywarningscatch_warnings
rc_contextclearupdatepltclose)orig_units_registry r   X/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/matplotlib/testing/decorators.py_cleanup_cm   s$    r   c                   @   s(   e Zd ZdZedd Zedd ZdS )CleanupTestCasezAA wrapper for unittest.TestCase that includes cleanup operations.c                 C   s   t   | _d S N)r   	__enter___cmclsr   r   r   
setUpClass,   s   zCleanupTestCase.setUpClassc                 C   s   | j d d d  d S r!   )r#   __exit__r$   r   r   r   tearDownClass0   s   zCleanupTestCase.tearDownClassN)__name__
__module____qualname____doc__classmethodr&   r(   r   r   r   r   r    *   s    
r    c                    s,    fdd}t  r| }ddg |S |S )z
    A decorator to ensure that any global state is reset before
    running a test.

    Parameters
    ----------
    style : str, dict, or list, optional
        The style(s) to apply.  Defaults to ``["classic",
        "_classic_test_patch"]``.
    c                    sB   t  rt  fdd}|S t  fdd}|S )Nc               	   ?   s~    t  1 tj  | i |E d H  W d    n1 s w   Y  W d    d S W d    d S 1 s8w   Y  d S r!   r   r   stylecontextargskwargsfuncr/   r   r   wrapped_callableI   s   Pz7cleanup.<locals>.make_cleanup.<locals>.wrapped_callablec               	      sv   t  . tj  | i | W d    n1 sw   Y  W d    d S W d    d S 1 s4w   Y  d S r!   r.   r1   r4   r   r   r6   N   s   P)inspectisgeneratorfunction	functoolswraps)r5   r6   r/   )r5   r   make_cleanupG   s   
	zcleanup.<locals>.make_cleanupclassic_classic_test_patch)callable)r/   r<   resultr   r;   r   cleanup5   s   rA   c                 C   sV   | d u rdS t | tr| | f} dd | D } ttj}| d |  ko(| d kS   S )NTc                 S   s   g | ]}t |qS r   r   ).0xr   r   r   
<listcomp>d   s    z*check_freetype_version.<locals>.<listcomp>r   r   )
isinstancestrr   r   __freetype_version__)verfoundr   r   r   check_freetype_version^   s   

 rJ   c                 C   s0   dd l }d| tjf }|jjt|  |tddS )Nr   zAMismatched version of freetype. Test requires '%s', you have '%s'F)reasonraisesstrict)pytestr   rG   markxfailrJ   r   )required_freetype_versionrN   rK   r   r   r   _checked_on_freetype_versionj   s   rR   c              	   C   s   |  d t }|  D ]6}|d |j| |j| |j| |j| z|j	| |j	| W q t
yC   Y qw d S )N )suptitler
   NullFormatterget_axes	set_titlexaxisset_major_formatterset_minor_formatteryaxiszaxisAttributeError)figurenull_formatteraxr   r   r   remove_ticks_and_titlest   s   

ra   c                 C   sF   d}t | ||dd}|r!dD ]}tj|| ||< qtd| d S )NT)in_decorator)actualexpecteddiffzEimages not close (RMS %(rms).3f):
	%(actual)s
	%(expected)s
	%(diff)s)r   ospathrelpathr   )rd   rc   tol__tracebackhide__errkeyr   r   r   _raise_on_image_difference   s   rm   c                 C   s$   dd l }|jj| t vd| dS )Nr   z&Cannot compare {} files on this system)rK   )rN   rO   skipifr   format)	extensionrN   r   r   r   _skip_if_format_is_uncomparable   s
   rq   c                 C   sd   dd l }t| tr| }g }nt| tr| j\}g | j}n| j\}| jg}|j|g |t	|dS )Nr   )marks)
rN   rE   rF   tuplevaluesrr   r2   rO   paramrq   )rp   rN   namerr   r   r   r   $_mark_skip_if_format_is_uncomparable   s   

rw   c                   @   s.   e Zd ZdZdd Zdd Zdddd	Zd
S )_ImageComparisonBasez
    Image comparison base class

    This class provides *just* the comparison-related functionality and avoids
    any code that would be specific to any testing framework.
    c                 C   s,   || _ t|\| _| _|| _|| _|| _d S r!   )r5   _image_directoriesbaseline_dir
result_dirri   remove_textsavefig_kwargs)selfr5   ri   r|   r}   r   r   r   __init__   s
   
z_ImageComparisonBase.__init__c              
   C   s   | j | }|d| }|dkr| s|d}t| j|j d}z6tt t	
| W d    n1 s9w   Y  z
t	|| W W |S  tyY   t|| Y W |S w  typ } ztd| d| |d }~ww )N.epsz.pdfrd   zMissing baseline image z0 because the following file cannot be accessed: )rz   with_suffixexistsr   r{   rv   
contextlibsuppressOSErrorrf   removesymlinkshutilcopyfiler   )r~   baselinerp   baseline_pathorig_expected_pathexpected_fnamerk   r   r   r   copy_baseline   s8   

z"_ImageComparisonBase.copy_baselineF_lockc                C   s   d}t  | }t |}| jrt| | j| d| }| j }	|dkr2|		dd d d d |r9t
|nt }
|
 |j|fi |	 | ||}t||| j W d    d S 1 s`w   Y  d S )NTr   pdfmetadata)CreatorProducerCreationDate)r   get_fignumsr^   r|   ra   r{   r   r}   r   
setdefaultr   
_lock_pathr   savefigr   rm   ri   )r~   idxr   rp   r   rj   fignumfigactual_pathr3   lockexpected_pathr   r   r   compare   s&   

"z_ImageComparisonBase.compareN)r)   r*   r+   r,   r   r   r   r   r   r   r   rx      s
    rx   c              	      s:   ddl tttjj  f	dd}|S )z
    Decorate function with image comparison for pytest.

    This function creates a decorator that wraps a figure-generating function
    with image comparison code.
    r   Nc                    s   t  t jdj	tt  
fdd}tj	
 }dj	vr@|t dg7 }dj	vrN|t dg7 }j|d}||_t dg |j }||_|S )Nrp   c           
         s   d}dj v r| |d< dj v r||d< td}tj  |i | tdd |jdD } d ur< }n|d}t	t
 t	|ksYJ d	t	t
 t	|t|D ]\}}	|j||	| |d
 q]d S )NTrp   request)ri   r|   r}   c                 s   s    | ]
}|j d  dkV  qdS )r   rp   N)r2   )rB   markerr   r   r   	<genexpr>
  s
    
zO_pytest_image_comparison.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>parametrizebaseline_imagesz9Test generated {} images but there are {} baseline imagesr   )
parametersrx   r   testingset_font_settings_for_testinganynodeiter_markersgetfixturevaluelenr   r   ro   	enumerater   )
rp   r   r2   r3   rj   img
needs_lockour_baseline_imagesr   r   )r   r5   old_sigr|   r}   ri   r   r   wrapper   s2   



z<_pytest_image_comparison.<locals>.decorator.<locals>.wrapperr   r   
pytestmark)r7   	signaturer9   r:   rO   r   r/   rR   listr   rt   	Parameterreplace__signature__getattrr   )r5   r   r   new_sig	new_marks	KEYWORD_ONLYr   
extensionsfreetype_versionrN   r|   r}   r/   ri   )r5   r   r   	decorator   s"   

 !

z+_pytest_image_comparison.<locals>.decorator)rN   maprw   r7   r   r   )r   r   ri   r   r|   r}   r/   r   r   r   r   _pytest_image_comparison   s
   	
8r   Fr=   r>   c              	   C   s   | dur-g t ddd | D }|r-|durtdt|dkr$td|}dd | D } |du r5g d	}|du r<t }tjd
krE|d7 }t| ||||||dS )a  
    Compare images generated by the test with those specified in
    *baseline_images*, which must correspond, else an `ImageComparisonFailure`
    exception will be raised.

    Parameters
    ----------
    baseline_images : list or None
        A list of strings specifying the names of the images generated by
        calls to `.Figure.savefig`.

        If *None*, the test function must use the ``baseline_images`` fixture,
        either as a parameter or with `pytest.mark.usefixtures`. This value is
        only allowed when using pytest.

    extensions : None or list of str
        The list of extensions to test, e.g. ``['png', 'pdf']``.

        If *None*, defaults to all supported extensions: png, pdf, and svg.

        When testing a single extension, it can be directly included in the
        names passed to *baseline_images*.  In that case, *extensions* must not
        be set.

        In order to keep the size of the test suite from ballooning, we only
        include the ``svg`` or ``pdf`` outputs if the test is explicitly
        exercising a feature dependent on that backend (see also the
        `check_figures_equal` decorator for that purpose).

    tol : float, default: 0
        The RMS threshold above which the test is considered failed.

        Due to expected small differences in floating-point calculations, on
        32-bit systems an additional 0.06 is added to this threshold.

    freetype_version : str or tuple
        The expected freetype version or range of versions for this test to
        pass.

    remove_text : bool
        Remove the title and tick text from the figure before comparison.  This
        is useful to make the baseline images independent of variations in text
        rendering between different versions of FreeType.

        This does not remove other, more deliberate, text, such as legends and
        annotations.

    savefig_kwarg : dict
        Optional arguments that are passed to the savefig method.

    style : str, dict, or list
        The optional style(s) to apply to the image test. The test itself
        can also apply additional styles if desired. Defaults to ``["classic",
        "_classic_test_patch"]``.
    Nc                 S   s   h | ]}t |jd d qS )r   N)r   suffixrB   r   r   r   r   	<setcomp>m  s    z#image_comparison.<locals>.<setcomp>z[When including extensions directly in 'baseline_images', 'extensions' cannot be set as wellr   zaWhen including extensions directly in 'baseline_images', all baselines must share the same suffixc                 S   s   g | ]}t |jqS r   )r   stemr   r   r   r   rD   y  s    
z$image_comparison.<locals>.<listcomp>pngr   svgl        gQ?)r   r   ri   r   r|   r}   r/   )filter
ValueErrorr   dictsysmaxsizer   )r   r   ri   r   r|   savefig_kwargr/   baseline_extsr   r   r   image_comparison.  s8   =

r   r   )r   ri   c                    s2   t tjtj d  tjj fdd}|S )a  
    Decorator for test cases that generate and compare two figures.

    The decorated function must take two keyword arguments, *fig_test*
    and *fig_ref*, and draw the test and reference images on them.
    After the function returns, the figures are saved and compared.

    This decorator should be preferred over `image_comparison` when possible in
    order to keep the size of the test suite from ballooning.

    Parameters
    ----------
    extensions : list, default: ["png", "pdf", "svg"]
        The extensions to test.
    tol : float
        The RMS threshold above which the test is considered failed.

    Examples
    --------
    Check that calling `.Axes.plot` with a single argument plots it against
    ``[0, 1, 2, ...]``::

        @check_figures_equal()
        def test_plot(fig_test, fig_ref):
            fig_test.subplots().plot([1, 3, 5])
            fig_ref.subplots().plot([0, 1, 2], [1, 3, 5])

    z_-[]()c                    s   dd l }t \}t ddhjstd |jd fdd}dd	 j	 D }djvrG|t
dg7 }d
jvrU|t
d
g7 }j|d}||_t dg |j }||_|S )Nr   fig_testfig_refzwThe decorated function must have at least the parameters 'fig_ref' and 'fig_test', but your function has the signature extc           	   	      s   dj v r	| |d< dj v r||d< d fdd|jjD }zBtd}td}|||d| |d	 |   }|d
 |   }|| || t||d W t| t| d S t| t| w )Nr   r   rS   c                 3   s    | ]	}| v r|V  qd S r!   r   )rB   c)ALLOWED_CHARSr   r   r     s    zJcheck_figures_equal.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>test	reference)r   r   r   z
-expected.)ri   )	r   joinr   rv   r   r^   r   rm   r   )	r   r   r2   r3   	file_namer   r   test_image_pathref_image_path)r   r5   r   r{   ri   r   r   r     s(   







z7check_figures_equal.<locals>.decorator.<locals>.wrapperc                 S   s   g | ]	}|j d vr|qS )>   r   r   )rv   )rB   ru   r   r   r   rD     s
    
z:check_figures_equal.<locals>.decorator.<locals>.<listcomp>r   r   r   )rN   ry   r7   r   issubsetr   r   rO   r   rt   r   r   r   r   r   )r5   rN   _r   r   r   r   r   r   r   ri   )r5   r   r{   r   r     s*   


z&check_figures_equal.<locals>.decorator)setstringdigitsascii_lettersr7   r   r   )r   ri   r   r   r   r   check_figures_equal  s   6r   c                 C   sL   t tj| j j}|jd |j }t   d |j }|jddd ||fS )a=  
    Compute the baseline and result image directories for testing *func*.

    For test module ``foo.bar.test_baz``, the baseline directory is at
    ``foo/bar/baseline_images/test_baz`` and the result directory at
    ``$(pwd)/result_images/test_baz``.  The result directory is created if it
    doesn't exist.
    r   result_imagesT)parentsexist_ok)	r   r   modulesr*   __file__parentr   resolvemkdir)r5   module_pathrz   r{   r   r   r   ry     s
   	ry   r!   )Nr   NFNr   )0r   distutils.versionr   r9   r7   rf   pathlibr   r   r   r   unittestr   r   ImportErrorr   r   mplmatplotlib.stylematplotlib.unitsmatplotlib.testingr   r   r	   r   r
   r   r   r   r   
exceptionsr   contextmanagerr   TestCaser    rA   rJ   rR   ra   rm   rq   rw   rx   r   r   r   ry   r   r   r   r   <module>   sZ    

)
;I
ZX