
    gfF                     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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Zd dlZd dlmZmZmZmZmZ ddlmZmZmZ ddlmZ e j>                  d	        Z d
 Z!d Z"d Z#e j>                  d        Z$d Z% G d d      Z&d Z'	 	 	 	 ddZ(dd ddZ)d Z*y)    N)uname)Path)parse)_pylab_helperscbookft2fontpyplotticker   )comparable_formatscompare_imagesmake_test_filename)ImageComparisonFailurec               #     K   t         j                  j                  j                         } 	 t	        j
                         5  t        j                         5  d  d d d        d d d        t         j                  j                  j                          t         j                  j                  j                  |        t        j                  d       y # 1 sw Y   xxY w# 1 sw Y   |xY w# t         j                  j                  j                          t         j                  j                  j                  |        t        j                  d       w xY ww)Nall)
matplotlibunitsregistrycopywarningscatch_warnings
rc_contextclearupdatepltclose)orig_units_registrys    Z/var/www/dash_apps/app1/venv/lib/python3.12/site-packages/matplotlib/testing/decorators.py_cleanup_cmr      s     $**3388:$$& 	
(=(=(? 		 	 	!!'')!!(()<=		%	 	 	 	 	!!'')!!(()<=		%sN   )EC)  CCC"C) *A'EC	CC&"C) )A(EEc                     | yt        | t              r| | f} | D cg c]  }t        |       } }t        t        j                        }| d   |cxk  xr | d   k  S c S c c}w )NTr   r   )
isinstancestrparse_versionr   __freetype_version__)verxfounds      r   _check_freetype_versionr(   "   sh    
{#sCj%(
)=
)C
)'667Eq6U$c!f$$$$ *s   Ac                     dd l }|j                  j                  t        |        d|  dt        j
                   dt        d      S )Nr   z/Mismatched version of freetype. Test requires 'z', you have ''F)reasonraisesstrict)pytestmarkxfailr(   r   r$   r   )required_freetype_versionr.   s     r   _checked_on_freetype_versionr2   .   sW    ;;#$=>>!!: ; <#889< &e  5 5    c                     | j                  d       t        j                         fd| j                         D ]
  } |        y )N c                    | j                  d       | j                  j                         | j                  j                         | j                  j                         | j                  j                         	 | j
                  j                         | j
                  j                         | j                  D ]
  } |        y# t        $ r Y %w xY w)z,Remove ticks in *ax* and all its child Axes.r5   N)	set_titlexaxisset_major_formatterset_minor_formatteryaxiszaxisAttributeError
child_axes)axchildnull_formatterremove_tickss     r   rB   z-remove_ticks_and_titles.<locals>.remove_ticks;   s    
R
$$^4
$$^4
$$^4
$$^4	HH((8HH((8 ]] 	 E	   		s    6C 	CC)suptitler
   NullFormatterget_axes)figurer?   rA   rB   s     @@r   remove_ticks_and_titlesrG   8   sB    
OOB))+N  oo Rr3   c            	   #     K   t         j                  j                  } | j                         D cg c]  }| }}g }	 | t	        | j                         D cg c]  }||vr|
 c}d       }|D cg c]  }|j
                  j                   c}|dd yc c}w c c}w c c}w # t	        | j                         D cg c]  }||vr|
 nc c}w c}d       }|D cg c]  }|j
                  j                   nc c}w c}|dd w xY ww)z
    After::

        with _collect_new_figures() as figs:
            some_code()

    the list *figs* contains the figures that have been created during the
    execution of ``some_code``, sorted by figure number.
    c                     | j                   S N)num)managers    r   <lambda>z&_collect_new_figures.<locals>.<lambda>`   s
    '++ r3   )keyN)r   GcffigsvaluessortedcanvasrF   )managersrL   preexistingnew_figsnew_managerss        r   _collect_new_figuresrX   M   s      !!&&H*2//*;<w7<K<HJhoo6G >7")"<  ' >"=? =IIw~~,,I =
> J hoo6G >7")"<  ' > >"=? =IIw~~,,IIsV   -D	BDB& DB%D3B!D&D	>CD	C=<D		Dc                     d}t        | ||d      }|r:dD ]'  }t        j                  j                  ||         ||<   ) t	        d|z        y )NT)in_decorator)actualexpecteddiffzEimages not close (RMS %(rms).3f):
	%(actual)s
	%(expected)s
	%(diff)s)r   ospathrelpathr   )r\   r[   tol__tracebackhide__errrN   s         r   _raise_on_image_differencerd   d   sf    
63T
BC
1 	1Cwws3x0CH	1$=@CDE 	E r3   c                   (    e Zd ZdZd Zd ZdddZy)_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                 l    || _         t        |      \  | _        | _        || _        || _        || _        y rJ   )func_image_directoriesbaseline_dir
result_dirra   remove_textsavefig_kwargs)selfrh   ra   rl   rm   s        r   __init__z_ImageComparisonBase.__init__x   s4    	-?-E*4?&,r3   c                 z   | j                   |z  }|j                  d|       }|dk(  r!|j                         s|j                  d      }t        | j                  |j
                  z  d      }	 t        j                  t              5  t        j                  |       d d d        	 dt               j                  j                         v rt        t        j                  ||       |S # 1 sw Y   LxY w# t        $ r t        j                   ||       Y |S w xY w# t        $ r}t#        d| d|       |d }~ww xY w)N.epsz.pdfr\   	microsoftzMissing baseline image z0 because the following file cannot be accessed: )rj   with_suffixexistsr   rk   name
contextlibsuppressOSErrorr^   remover   releaselowersymlinkshutilcopyfiler   )rn   baseline	extensionbaseline_pathorig_expected_pathexpected_fnamerc   s          r   copy_baselinez"_ImageComparisonBase.copy_baseline   s=   ))H4*669+G&8&?&?&A!3!?!?!G+OO0555zC	2$$W- *		.)*D%'//"7"7"99!M

-~> * *  D 2NC D 	2().)9 :6%&() /22	2sO   .D C(D &A C4 (C1-D 4DD DD 	D:#D55D:F_lockc                >   d}| j                   rt        |       | j                  |z  j                  d|       }| j                  j                         }|dk(  r|j                  dd d d d       |rt        j                  |      nt        j                         }|5  	  |j                  |fi | t        j                  |       | j                  ||      }	t        |	|| j                          d d d        y # t        j                  |       w xY w# 1 sw Y   y xY w)NTrq   pdfmetadata)CreatorProducerCreationDate)rl   rG   rk   rt   rm   r   
setdefaultr   
_lock_pathrw   nullcontextsavefigr   r   r   rd   ra   )
rn   figr   r   r   rb   actual_pathkwargslockexpected_paths
             r   comparez_ImageComparisonBase.compare   s    #C(1>>9+O$$))+j*.D/356
    -(446 	 	MK262 		# ..xCM&}k488L	M 	M 		#	M 	Ms$   DC92>D9DDDN)__name__
__module____qualname____doc__ro   r   r    r3   r   rf   rf   p   s    -0 :? Mr3   rf   c           	      n    	 ddl 	t        j                  j                   	f	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                   	  t        j                         t        j                         
j                  j                  d      t        j                  j                        t        	      t        j                          
fd                                   }t        j                  j                               }dj                  vr|t        j                  d      gz  }dj                  vr|t        j                  d      gz  }j                  |      }||_        t!         dg       |j"                  z   }||_        |S )Nr   c                    d}dj                   v r| |d<   dj                   v r||d<   | t               vr-ddddj                  | d      }j                  d|  d	|        t	        
      }t
        j                  j                          t               5 } |i | d d d        t        d |j                  j                  d      D              }}	n|j                  d      }	t              t        |	      k(  s J dt        |       dt        |	       d       t        ||	      D ]  \  }
}|j                  |
|| |        y # 1 sw Y   xY w)NTr   requestz$because Ghostscript is not installedz!because Inkscape is not installed)r   rr   svgzon this systemzCannot compare z files )ra   rl   rm   c              3   @   K   | ]  }|j                   d    dk7    yw)r   r   N)args).0markers     r   	<genexpr>zO_pytest_image_comparison.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>   s'      H A+-Hs   parametrizebaseline_imageszTest generated z images but there are z baseline imagesr   )
parametersr   getskiprf   r   testingset_font_settings_for_testingrX   anynodeiter_markersgetfixturevaluelenzipr   )r   r   r   r   rb   r+   imgrP   
needs_lockour_baseline_imagesr   r   r   rh   old_sigr.   rl   rm   ra   s               r   wrapperz<_pytest_image_comparison.<locals>.decorator.<locals>.wrapper   s    !%g000&/{#G...$+y! 2 44AA> #i!12	 
 oi[xHI&t+6DFC<<>%' &4d%f%&  H%ll77FH HJ *&5# '.&=&=%''# t9$7 88 ?!#d),B*+,,<>?8 "%T+>!? HXC9JGH+& &s   	EEr   r   
pytestmark)inspect	signature	functoolswrapsr/   r   r   stylecontextr2   listr   rQ   	Parameterreplace__signature__getattrr   )rh   r   r   new_sig	new_marksr   KEYWORD_ONLYr   
extensionsfreetype_versionr.   rl   rm   r   ra   s   `    @r   	decoratorz+_pytest_image_comparison.<locals>.decorator   s3   ##D)				 	 j	9				!	!%	(	%&6	7		)	H )	H 
 
8 
) 
: 

)	HV ',,3356
g0007,,[,GHHJG...7,,YEFFJ//Z/8 ' D,3g6H6HH	&r3   )r.   r   r   r   )
r   r   ra   r   rl   rm   r   r   r   r.   s
   ``````` @@r   _pytest_image_comparisonr      s/     $$11L@ @D r3   c           
         | ~g t        d| D ch c]  }t        |      j                  dd  c}      }|rJ|t        d      t	        |      dkD  rt        d      |}| D cg c]  }t        |      j
                   } }|g d}|
t               }t        j                  dk  r|dz  }t        | ||||||      S c c}w c c}w )	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"]``.
    Nr   z[When including extensions directly in 'baseline_images', 'extensions' cannot be set as wellzaWhen including extensions directly in 'baseline_images', all baselines must share the same suffixpngr   r   l        gQ?)r   r   ra   r   rl   rm   r   )
filterr   suffix
ValueErrorr   stemdictsysmaxsizer   )	r   r   ra   r   rl   savefig_kwargr   r   baseline_extss	            r   image_comparisonr     s   z "K&8G(I,4 )-X(=(=ab(A (I J K% 9: : =!A% ?@ @ 'J4CE(0X##EO E*

{{et#'JC){$E3 3+(IEs   B=#Cr   )r   ra   c                      t        t        j                  t        j                  z   dz         t        j
                  j                   fd}|S )a5  
    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.

    Raises
    ------
    RuntimeError
        If any new figures are created (and not subsequently closed) inside
        the test function.

    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                    	 dd l }t               \  }	t        j                         ddhj	                  j
                        st        d       |j                  j                  d      
 	fd       }j
                  j                         D cg c]  }|j                  dvr| }}dj
                  vr|t        j                  d      gz  }dj
                  vr|t        j                  d      gz  }j                  |	      }||_        t         d
g       |j                  z   }||_        |S c c}w )Nr   fig_testfig_refzwThe decorated function must have at least the parameters 'fig_test' and 'fig_ref', but your function has the signature extc                    dj                   v r| |d<   dj                   v r||d<   dj                  
fd|j                  j                  D              }	 t	        j
                  d      }t	        j
                  d      }t               5 } |||d| d d d        rt        d      |d	z   | z   z  }|d
z   | z   z  }	|j                  |       |j                  |	       t        |	|       t	        j                  |       t	        j                  |       y # 1 sw Y   xY w# t	        j                         t	        j                         w xY w)Nr   r   r5   c              3   *   K   | ]
  }|v r|  y wrJ   r   )r   cALLOWED_CHARSs     r   r   zJcheck_figures_equal.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>  s        7a#$#5 !"  7s   test	reference)r   r   zNumber of open figures changed during test. Make sure you are plotting to fig_test or fig_ref, or if this is deliberate explicitly close the new figure(s) inside the test.rq   z
-expected.)ra   )r   joinr   rv   r   rF   rX   RuntimeErrorr   rd   r   )r   r   r   r   	file_namer   r   rP   test_image_pathref_image_pathr   rh   r   rk   ra   s             r   r   z7check_figures_equal.<locals>.decorator.<locals>.wrapper  sH   *** #uG...$+y!  77<<+<+<  7 7I#::f-**[1)+ Nt$7MfMN& (H I I
 #-	C#0E"F!+y</G#/M!N  1/*"O 		(#		'"#N N  		(#		'"s%   4D) DAD) D&"D) ),E>   r   r   r   r   r   )r.   ri   r   r   issubsetr   r   r/   r   rQ   rv   r   r   r   r   r   )rh   r.   _r   paramr   r   r   r   rk   r   r   r   ra   s   `       @@r   r   z&check_figures_equal.<locals>.decorator  sT   *40:##D)I&//0B0BC ;;B)E F F 
	 	 
	3	# 
4	#@ !++224
zz!88 

 

 ***7,,ULABBJG...7,,YEFFJ//Z/8 ' D,3g6H6HH	&#
s   E )setstringdigitsascii_lettersr   r   r   )r   ra   r   r   r   s   `` @@r   check_figures_equalr   ]  sC    F (<(<<xGHM$$11L;z r3   c                     t        t        j                  |             }|j                  dz  |j                  z  }t               j                         dz  |j                  z  }|j                  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   getfileparentr   resolvemkdir)rh   module_pathrj   rk   s       r   ri   ri     so     wt,-K%%(99K<L<LLL!O3k6F6FFJTD1##r3   )Nr   NFN)classic_classic_test_patch)+rw   r   r   r^   platformr   pathlibr   r~   r   r   r   packaging.versionr   r#   matplotlib.styler   matplotlib.unitsmatplotlib.testingr   r   r   r	   r   r
   r   r   r   r   
exceptionsr   contextmanagerr   r(   r2   rG   rX   rd   rf   r   r   r   ri   r   r3   r   <module>r     s       	     
  4    L L K K .  	%5* J J,	E>M >MBOd <=8=#'=	W3t '< cL$r3   