o znh!@sdZddlZddlZddlZddlZddlZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z zddlZWn eyKdZYnwdZdZGd d d eZdddZejdddZdS)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)jython)pypyupdate_wrapper)win32c@sTeZdZdZddZeddZddZdd Zd d Z d d Z ddZ ddZ dS)ProfileStatsFilez"Store 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 cCs~tjduotjj|_|jptjduotjj|_tj||_ tj |j d|_ t dd|_||jr=|dSdS)NcSs ttSN) collections defaultdictdictrrG/usr/local/lib/python3.10/dist-packages/sqlalchemy/testing/profiling.py:s z+ProfileStatsFile.__init__..)roptionsforce_write_profiles force_writewrite_profileswriteospathabspathfnamesplit short_fnamerrdata_read_write)selffilenamerrr__init__0s zProfileStatsFile.__init__cCstjjdtjj}dddtjddD}|g}||tr(|dt r/|dt r6|d |tjj j r?d nd tj }||rMd pNd d|S)N_.cSg|]}t|qSrstr).0vrrr Hz1ProfileStatsFile.platform_key..rrrrwin nativeunicode dbapiunicode cextensions nocextensions)rdbnamedriverjoinsys version_infoappendrrr dialectconvert_unicode requirements_has_cextensions)r" dbapi_key py_versionplatform_tokens _has_cextrrr platform_keyBs$      zProfileStatsFile.platform_keycCst}||jvo|j|j|vSr ) _current_testrrB)r"test_keyrrr has_stats[szProfileStatsFile.has_statsc Cst}|j|}||j}d|vrg|d<}n|d}d|vr&d|d<}n|d}t||k}|sA|||jr>|d}n|d||f}|dd7<|S)Ncounts current_countrlinenor)rCrrBlenr9rr!) r" callcountrDper_fn per_platformrFrG has_countresultrrrrNas$    zProfileStatsFile.resultcCs`t}|j|}||j}|d}|d}|t|kr!|||d<n||d<|jr.|dSdS)NrFrGrr )rCrrBrIrr!)r"rJrDrKrLrFrGrrrreplace|s    zProfileStatsFile.replacecCs d|jS)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"rrr_headerszProfileStatsFile._headerc Cszt|j}Wn tyYdSwt|D]8\}}|}|r%|dr&q|\}}}|j|}||}dd|dD} | |d<|d|d<d|d <q|dS) N#cSr'r)intr*countrrrr,r-z*ProfileStatsFile._read..,rFrrHrrG) openrIOError enumeratestrip startswithrrclose) r" profile_frHlinerDrBrFrKrLcrrrr s"     zProfileStatsFile._readcCstd|jt|jd}||t|jD]/}|j|}|d|t|D]}||}ddd|dD}|d|||fq+q|dS) NzWriting profile file %swz # TEST: %s rUcss|]}t|VqdSr r(rSrrr sz*ProfileStatsFile._write..rFz %s %s %s ) printrrVrrPsortedrr6r[)r"r\rDrKrBrLr^rrrr!s    zProfileStatsFile._writeN) __name__ __module__ __qualname____doc__r$propertyrBrErNrOrPr r!rrrrr (s   r 皙?csfdd}|S)aAssert 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. csfdd}t|S)NcsRt}td|D] }|i|}q |WdS1s"wYdS)N)variance)rangecount_functions)argskw timerangetimerv)fntimesrirrwraps  $z3function_call_count..decorate..wrapr)rqrsrrri)rqrdecorates z%function_call_count..decorater)rirrrurrtrfunction_call_counts  rvc cstdur tdtstjstdtjtt }| dV| t j |tjd}|j}t|}|durBd}n|\}}td||f|d||rt||}t|||k}|sltjrtjrvt|dStd||d|tjfdSdS)NzcProfile 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.)streamzPstats calls: %d Expected %s cumulativezAdjusted function call count %s not within %s%% of expected %s, platform %s. Rerun with --write-profiles to regenerate this callcount.d)cProfiler_skip_test_exception_profile_statsrEr skip_testrrProfileenabledisablepstatsStatsr7stdout total_callsrNra sort_stats print_statsrRabsrrOAssertionErrorrB) riprstatsrJexpectedexpected_countline_nodeviancefailedrrrrksP     rk)rhr)rh)rfr contextlibrrr7rutilrrrr r rz ImportErrorrCr|objectr rvcontextmanagerrkrrrrs0