
    ؄_%"                         d Z ddlZddl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	mZ 	 ddlZn# e$ r dZY nw xY wdZdZ G d d	e          ZddZej        dd            ZdS )zProfiling support for unit and performance tests.

These are special purpose profiling methods which operate
in a more fine-grained way than nose's profiling plugin.

    N   )config)
gc_collect   update_wrapperc                   R    e Zd ZdZd Zed             Zd Zd Zd Z	d Z
d Zd	 Zd
S )ProfileStatsFilezStore per-platform/fn profiling results in a file.

    We're still targeting Py2.5, 2.4 on 0.7 with no dependencies,
    so no json lib :(  need to roll something silly

    c                    t           j        d uot           j        j        | _        | j        pt           j        d uot           j        j        | _        t          j                            |          | _	        t          j        
                    | j	                  d         | _        t          j        d           | _        |                                  | j        r|                                  d S d S )Nc                  4    t          j        t                    S N)collectionsdefaultdictdict     a/var/www/book.euthymeo.com/html/venv/lib/python3.11/site-packages/sqlalchemy/testing/profiling.py<lambda>z+ProfileStatsFile.__init__.<locals>.<lambda>8   s    K+D11 r   )r   optionsforce_write_profilesforce_writewrite_profileswriteospathabspathfnamesplitshort_fnamer   r   data_read_write)selffilenames     r   __init__zProfileStatsFile.__init__.   s    N$&N6>+N 	 % 
N$&H6>+H 	
 W__X..
7==44R8+11
 
	 	

: 	 KKMMMMM	 	r   c                    t           j        j        dz   t           j        j        z   }t           j        j        dk    r8t           j        j                            t           j        j                  r|dz  }d                    d t          j	        dd         D                       }t          j                    t          j                                                    t          j                                                    ||g}|                    t           j        j        j        rdnd	           t           j                                        }|                    |rd
pd           d                    |          S )N_sqlite_file.c                 ,    g | ]}t          |          S r   str).0vs     r   
<listcomp>z1ProfileStatsFile.platform_key.<locals>.<listcomp>K   s    EEE!s1vvEEEr   r   r   nativeunicodedbapiunicodecextensionsnocextensions)r   dbnamedriverdialect_is_url_file_dburljoinsysversion_infoplatformmachinesystemlowerpython_implementationappendconvert_unicoderequirements_has_cextensions)r$   	dbapi_key
py_versionplatform_tokens	_has_cexts        r   platform_keyzProfileStatsFile.platform_key@   sG    INS(69+;;	9>X%%&)*;*K*KIM+
 +
%  I XXEEs/?!/DEEEFF
 O##%%*,,2244
 	y 0 OO	
 	
 	

 '88::	y:]MoNNNxx(((r   c                 J    t           }|| j        v o| j        | j        |         v S r   )_current_testr!   rL   )r$   test_keys     r   	has_statszProfileStatsFile.has_stats^   s*     	!Nd&749X;N&N	
r   c                 h   t           }| j        |         }|| j                 }d|vrg x|d<   }n|d         }d|vrdx|d<   }n|d         }t          |          |k    }|s3|                    |           | j        r|                                  d }n|d         ||         f}|dxx         dz  cc<   |S )Ncountscurrent_countr   linenor   )rN   r!   rL   lenrD   r   r#   )	r$   	callcountrO   per_fnper_platformrR   rS   	has_countresults	            r   rZ   zProfileStatsFile.resultd   s     8$d/0<''.00L"VV!(+F,..<==L)MM(9MKK-/	 	CMM)$$$z FF!(+VM-BBF_%%%*%%%r   c                     t           }| j        |         }|| j                 }|d         }|d         }|t          |          k     r	|||dz
  <   n||d<   | j        r|                                  d S d S )NrR   rS   r   r   )rN   r!   rL   rU   r   r#   )r$   rV   rO   rW   rX   rR   rS   s          r   replacezProfileStatsFile.replace   s     8$d/0h'$_53v;;&&(1F=1$%%"F2J: 	KKMMMMM	 	r   c                     d| j         z  S )Na  # %s
# This file is written out on a per-environment basis.
# For each test in aaa_profiling, the corresponding function and 
# environment is located within this file.  If it doesn't exist,
# the test is skipped.
# If a callcount does exist, it is compared to what we received. 
# assertions are raised if the counts do not match.
# 
# To add a new callcount test, apply the function_call_count 
# decorator and re-run the tests using the --write-profiles 
# option - this file will be rewritten including the new count.
# 
)r   )r$   s    r   _headerzProfileStatsFile._header   s     Z! 	r   c                    	 t          | j                  }n# t          $ r Y d S w xY wt          |          D ]\  }}|                                }|r|                    d          r1|                                \  }}}| j        |         }||         }d |                    d          D             }	|	|d<   |dz   |d<   d|d<   |                                 d S )	N#c                 ,    g | ]}t          |          S r   )intr/   counts     r   r1   z*ProfileStatsFile._read.<locals>.<listcomp>   s    ;;;U;;;r   ,rR   r   rT   r   rS   )	openr   IOError	enumeratestrip
startswithr   r!   close)
r$   	profile_frT   linerO   rL   rR   rW   rX   cs
             r   r"   zProfileStatsFile._read   s   	TZ((II 	 	 	FF	%i00 	. 	.LFD::<<D 4??3// -1ZZ\\*HlFYx(F!,/L;;c):):;;;A%&L"%+aZL",-L))s    
%%c           
         t          d| j        z             t          | j        d          }|                    |                                            t          | j                  D ]}| j        |         }|                    d|z             t          |          D ]M}||         }d                    d |d         D                       }|                    |d|d|d           N|                                 d S )	NzWriting profile file %swz
# TEST: %s

re   c              3   4   K   | ]}t          |          V  d S r   r-   rc   s     r   	<genexpr>z*ProfileStatsFile._write.<locals>.<genexpr>   s(      LLESZZLLLLLLr   rR    
)	printr   rf   r   r^   sortedr!   r<   rk   )r$   rl   rO   rW   rL   rX   rn   s          r   r#   zProfileStatsFile._write   s   (4:5777S))	'''ty)) 	L 	LHYx(FOO.9::: &v L L%l3HHLL\(5KLLLLL,,, JKKKKL 	r   N)__name__
__module____qualname____doc__r&   propertyrL   rP   rZ   r\   r^   r"   r#   r   r   r   r
   r
   &   s           $ ) ) X):
 
 
  6    &  &    r   r
   皙?c                       fd}|S )a  Assert a target for a test case's function call count.

    The main purpose of this assertion is to detect changes in
    callcounts for various functions - the actual number is not as important.
    Callcounts are stored in a file keyed to Python version and OS platform
    information.  This file is generated automatically for new tests,
    and versioned so that unexpected changes in callcounts will be detected.

    c                 6      fd}t          |           S )Nc                      t          	          D ]
} | i | t                    }t                    5  |D ]
} | i |}|cd d d            S # 1 swxY w Y   d S )N)variance)rangecount_functions)
argskwwarm	timerangetimervfntimesr   warmups
         r   wrapz3function_call_count.<locals>.decorate.<locals>.wrap   s    f    DBeI (333  % ) )DTRBB                 s   AAAr   )r   r   r   r   r   s   ` r   decoratez%function_call_count.<locals>.decorate   s>    	 	 	 	 	 	 	 	 dB'''r   r   )r   r   r   r   s   ``` r   function_call_countr      s/    
( 
( 
( 
( 
( 
( 
( Or   c              #     K   t           t          j        d          t                                          s-t          j        s!t          j        dt          j        z             t                       t          j	                    }|
                                 d V  |                                 t          j        |t          j                  }|j        }t                              |          }|d }n|\  }}t%          d||fz             |                    d           |                                 |rt+          || z            }t-          ||z
            |k    }|st          j        rSt          j        rt                              |           d S t3          d|d| dz  d	|d
t          j        d	          d S d S )NzcProfile is not installedzNo profiling stats available on this platform for this function.  Run tests with --write-profiles to add statistics to %s for this platform.)streamzPstats calls: %d Expected %s
cumulativezAdjusted function call count z not within d   z% of expected z, platform z;. Rerun with --write-profiles to regenerate this callcount.)cProfiler   _skip_test_exception_profile_statsrP   r   	skip_testr    r   ProfileenabledisablepstatsStatsr=   stdouttotal_callsrZ   ru   
sort_statsprint_statsrb   absr   r\   AssertionErrorrL   )	r   prstatsrV   expectedexpected_countline_nodeviancefaileds	            r   r   r      s     )*EFFF##%% 
n.B 
  .9:	
 	
 	
 LLL				BIIKKK	EEEJJLLL LCJ///E !I$$Y//H"*	)Y,GGIII	\"""	 y8+,,Y/008; 	^/ 	# &&y11111$n "		!C&&333	   	 	r   )r|   r   r   )r|   )rz   r   
contextlibr   r?   r   r=    r   utilr   r   r   ImportErrorrN   r   objectr
   r   contextmanagerr   r   r   r   <module>r      s:            				   



             ! ! ! ! ! !OOOO   HHH  X X X X Xv X X Xv   4 9 9 9 9 9 9s   3 ==