QfrdZddgZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlZdZGddZd Zd ZGd dZd Zd ZddZdZGddZdZedk(reyy)aprogram/module to trace Python program or function execution Sample use, command line: trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs trace.py -t --ignore-dir '$prefix' spam.py eggs trace.py --trackcalls spam.py eggs Sample use, programmatically import sys # create a Trace object, telling it what to ignore, and whether to # do tracing or line-counting or both. tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], trace=0, count=1) # run the new command using the given tracer tracer.run('main()') # make a report, placing output in /tmp r = tracer.results() r.write_results(show_missing=True, coverdir="/tmp") TraceCoverageResultsN) monotonicz#pragma NO COVERceZdZddZdZy)_IgnoreNc|s tn t||_|sgn,|Dcgc]!}tjj |#c}|_ddi|_ycc}w)Nz)set_modsospathnormpath_dirs_ignore)selfmodulesdirsds ,/opt/alt/python312/lib64/python3.12/trace.py__init__z_Ignore.__init__FsW")SUs7| #R37*937a+-''*:*:1*=37*9 #Q( *9s&Ac||jvr|j|S||jvrd|j|<y|jD]'}|j|dzsd|j|<y|d|j|<y|jD]5}|j|tj zs&d|j|<yd|j|<y)Nr .r)rr startswithrr sep)rfilename modulenamemodrs rnamesz _Ignore.namesLs  %<< + +  #'(DLL $::C$$S3Y/+, Z(   '(DLL $A""1rvv:.+, Z($% Z NN)__name__ __module__ __qualname__rrrrrrEs ) )rrctjj|}tjj|\}}|S),Return a plausible module name for the path.)r r basenamesplitext)r baserexts r_modnamer+ws5 77  D !DGG$$T*MHc Orctjj|}d}tjD]m}tjj|}|j |s4|t |tj k(sTt |t |kDsl|}o|r|t |dzd}n|}tjj|\}}|jtj d}tjr |jtjd}tjj|\}}|jdS)r&r Nr) r r normcasesysrlenr splitdrivereplacealtsepr(lstrip)r comparepathlongestdirr)driverr*s r _fullmodnamer9~s''""4(KGxxggs#  ! !# &;s3x+@BFF+J3x#g,&  CL1$%&''$$T*KE4 << $D yy||BIIs+GG$$T*MHc ??3 rc4eZdZ ddZdZdZddZd dZy) rNc||_|ji|_|jj|_||_|ji|_|jj|_||_|ji|_|jj|_||_||_|j r] t|j d5}tj|\}}}ddd|j|j|||yy#1swY.xYw#tttf$r5}td|j d|t j"Yd}~yd}~wwxYw)Nrb)callerszSkipping counts file : file)countscopycounter calledfuncsr=infileoutfileopenpickleloadupdate __class__OSErrorEOFError ValueErrorprintr/stderr)rrArDrEr=rFferrs rrzCoverageResults.__init__s8 ;; DK{{'') &    #!D ++002 << DL||((*   ;; N$++t,39;;q>0FK- DNN6;NPQ -,Xz2 N)-c;BE**NN Ns0D0D$7+D0$D-)D00E9+E44E9cJ|jdxr|jdS)z_Return True if the filename does not refer to a file we want to have reported. <>)rendswith)rrs ris_ignored_filenamez#CoverageResults.is_ignored_filenames%""3'BH,=,=c,BBrc|j}|j}|j}|j}|j}|j}|D]}|j|d||z||<|D]}d||< |D]}d||< y)z.Merge in the data from another CoverageResultsrr N)rArDr=get) rotherrArDr= other_countsother_calledfuncs other_callerskeys rrJzCoverageResults.updates&& ,,|| !-- C **S!,|C/@@F3K %C K %!CGCL!rc |jrIttd|j}t|D]\}}}td|d|d||jrttddx}} t|jD]\\\} } } \} }}| |k7rttd| d| }d} | | k7r| | k7rtd| | } td | d | d |d |^i}|jD]0\}}|j |ix}||<|j||f||<2i}|j D]U\}}|j|r|jd r|d d}|Htjjtjj|}t|}n$|}tj|dt|}|r t!|}ni}t#j$|}tjj'||dz}t)|d5}t+j,|j.\}}d d d |j1||||\}}|s8|sYd }!~!y d }!~!wwxYw)af Write the coverage results. :param show_missing: Show lines that had no hits. :param summary: Include coverage summary per module. :param coverdir: If None, the results of each module are placed in its directory, otherwise it is included in the directory specified. zfunctions called:z filename: z, modulename: , funcname: zcalling relationships:r-z***z -->z rz -> z.pycNT)exist_okz.coverr<dzlines cov% module (path)z%5d %3d%% %s (%s)wbr z"Can't save counts files because %sr?) rDrOsortedr=rArYitemsrWrVr r dirnameabspathr+makedirsr9_find_executable_linenos linecachegetlinesjoinrGtokenizedetect_encodingreadlinewrite_results_fileintrFrHdumprLr/rP)"r show_missingsummarycoverdircallsrrfuncnamelastfile lastcfilepfilepmodpfunccfilecmodcfuncper_filelineno lines_hitsumscountr7lnotabsource coverpathfpencoding_n_hitsn_linespercentmrQrRs" r write_resultszCoverageResults.write_resultssL    G % &$$E28-.*h"J:<3@ << G * +#% %Hydll+=%%u';tUH$G%.$H "IE>i5&8'5) %IdE4GH, $ Hf-5\\(B-G GI* $ Xv,> ?If !, '~~/OHe''1  (#CR=ggoobggooh&?@%h/  C$/)(3 1(;''1F S*x*?@Ih%&66r{{C !&"55i6.> M !1&.- &%$.- S:S@szzRR SsB3#L;"M89M1M;M M MM NM??Nc t|d|}d }d } |5t |d D]\} } | |vr"|j d || z| d z } |d z }n4| |vrt| vr|j d |d z }n|j d |j | jd ddd| |fS#t$r,}td|d|dtjYd}~yd}~wwxYw#1swY| |fSxYw)z'Return a coverage results file in path.wrztrace: Could not open z for writing: z - skippingr?N)rrrr z%5d: z>>>>>> z ) rGrLrOr/rP enumeratewritePRAGMA_NOCOVER expandtabs) rr linesrrrrFrRrrrlines rrqz"CoverageResults.write_results_file(s 4x8G   )% 3 Y&MM'If,="=>aKFqLGv%n.DMM),qLGMM), dooa01!4"w1  26=DGJJ P "ws#B2BC*2 C';"C""C'*C6)NNNNN)TFNN)r!r"r#rrWrJrrqr$rrrrs&=A'+N4C $YSvrcXi}tj|D]\}}||vs d||<|S)z:Return dict where keys are lines in the line number table.r )disfindlinestarts)codestrslinenosrrs r_find_lines_from_coderHs8G''- 6  GFO. Nrct||}|jD]3}tj|s|j t ||5|S)z>!  NN;q$/ 0 Nrc`i}tj}t||5}tj|j }|D]S\}}}} } |tj k(r6|tjk(r#|\} } | \} }t| | dzD]}d||< |}U ddd|S#1swY|SxYw)zReturn a dict of possible docstring positions. The dict maps line numbers to strings. There is an entry for line that contains only a string or a part of a triple-quoted string. rr N)tokenINDENTrGrngenerate_tokensrpSTRINGrange)rrr prev_ttyperQtokttypetstrstartendrslinescolelineecolis r _find_stringsr^s AJ h *a&&qzz2-0 )E4T $-"'KE4"%KE4"5%!)4 !5J.1 + H + Hs A8B##B-cL tj|5}|j}|j}dddt|d}t|}t||S#1swY.xYw#t$r-}t d|d|t jicYd}~Sd}~wwxYw)zAReturn dict where keys are line numbers in the line number table.NzNot printing coverage data for r>r?exec) rnrGreadrrLrOr/rPcompilerr)rrQprogrrRrrs rrjrjus ]]8 $668DzzH% 46 *D 8 ,D tT ""% $  !)307:zz C s3A-A!A-!A*&A-- B#6"BB#B#c^eZdZ ddZdZddZdZdZdZdZ d Z d Z d Z d Z d Zy)rNc ||_||_t|||_i|_i|_d|_||_i|_i|_ i|_ d|_ | rt|_ |r|j|_y|r|j|_y|r%|r#|j |_|j"|_y|r#|j |_|j&|_y|r#|j |_|j(|_yd|_y)ax @param count true iff it should count number of times each line is executed @param trace true iff it should print out each line that is being counted @param countfuncs true iff it should just output a list of (filename, modulename, funcname,) for functions that were called at least once; This overrides `count' and `trace' @param ignoremods a list of the names of modules to ignore @param ignoredirs a list of the names of directories to ignore all of the (recursive) contents of @param infile file from which to read stored counts to be added into the results @param outfile file in which to write the results @param timing true iff timing information be displayed rNr )rErFrignorerApathtobasename donothingtrace _calledfuncs_callers _caller_cache start_time_timeglobaltrace_trackcallers globaltraceglobaltrace_countfuncsglobaltrace_ltlocaltrace_trace_and_count localtracelocaltrace_tracelocaltrace_count) rrr countfuncs countcallers ignoremods ignoredirsrErFtimings rrzTrace.__init__s(  j*5      #gDO #<tj|jt j|j t ||||js+t jdtjdyy#|js+t jdtjdwwxYwr)r threadingsettracerr/r)rrglobalslocalss rrz Trace.runctxs ?bG >B6~~   t// 0 LL)) * ) gv &>> T"""4("4>> T"""4("s  B9Ccd}|jstj|j ||i|}|jstjd|S#|jstjdwwxYwr)rr/rr)rfuncargskwresults rrunfuncz Trace.runfuncsh~~ LL)) * #4&2&F>> T" >> T""s A$A>c|j}|j}|r t|}nd}|j}d}||jvr |j||j|}nd|j|<t j |Dcgc]}tj|r|}}t|dk(rt j |dD cgc]} t| tr| } } t| dk(r]t j | dD cgc]} t| dr| } } t| dk(r| dj}||j|<||d|}|||fScc}wcc} wcc} w)Nr r __bases__r)f_code co_filenamer+co_namergc get_referrersr isfunctionr0 isinstancerhasattrr!) rframerrrrxclsnamerQfuncsrdictsrclassess rfile_module_function_ofzTrace.file_module_function_ofs||## !(+JJ<< 4%% %!!$'3,,T2'+D  t $!# 0 0 63 61#..q1 6E3 5zQ$&$4$4U1X$>5$>q *1d 3$>5u:?*,*:*:58*D?*DQ&-a&= !*DG?7|q(")!*"5"5 4;**40  ")84HX---3 5?s E'E,E1c|dk(r>|j|}|j|j}d|j||f<yy)zkHandler for call events. Adds information about who called who to the self._callers dict. callr N)rf_backr)rrwhyarg this_func parent_funcs rrzTrace.globaltrace_trackcallerssG &=44U;I66u||DK67DMM; 2 3 rcP|dk(r!|j|}d|j|<yy)zoHandler for call events. Adds (filename, modulename, funcname) to the self._calledfuncs dict. rr N)rr)rrrrrs rrzTrace.globaltrace_countfuncss0 &=44U;I+,D  i ( rc$|dk(r|j}|jjdd}|r`t|}|R|jj ||}|s3|j rtd|d|j|jSyyyy)zHandler for call events. If the code block being entered is to be ignored, returns `None', else returns self.localtrace. r__file__Nz --- modulename: r`) r f_globalsrYr+rrrrOrr)rrrrrrr ignore_its rrzTrace.globaltrace_lts &=<)rrf_linenorArYrrOrr r r'rkgetliner) rrrrrrr^bnamers rrz Trace.localtrace_trace_and_count's &=||//H^^FF"C#{{sA6:DKK f$// 9:DGG$$X.E$$Xv6D (eV_," 5dDb)rc|dk(r|jj}|j}|jr%t dt |jz zdt jj|}tj||}t d||fzd|rt d|d|jSt |jS)Nrrrr r r-r>) rrr rrOrr r r'rkr r)rrrrrrr rs rrzTrace.localtrace_trace:s &=||//H^^Ff$// 9:DGG$$X.E$$Xv6D (eV_," 5dDb)rc|dk(rR|jj}|j}||f}|jj |ddz|j|<|j S)Nrrr )rrr rArYr)rrrrrrr^s rrzTrace.localtrace_countKsW &=||//H^^FF"C#{{sA6:DKK rct|j|j|j|j|j S)N)rErFrDr=)rrArErFrr)rs rresultsz Trace.resultsSs2t{{4;;'+||+/+<+<'+}}6 6r) r r rrr$r$NNFr )r!r"r#rrrrrrrrrrrrr$rrrrsIDEDH0d% ) '.R 8-.&"6rc  ddl}|j}|jddd|jdd}|jdd d d |jd dd d |jddd d |jddd d |jd}|j }|jddd d |jddd d |jddd |jd!d"d# |jd$d%d d& |jd'd(d d) |jd*d+d d, |jd-d.}|jd/d0gd12|jd3d0gd42|jd5d d6d72|jd8d9d:;|jd<|j d=;|j }|jr*tjd>tjd?fd@}|jDcgc](}|jdAD]}|j*c}}|_ |jDcgc].}|jtjD] }|| 0c}}|_|jro|j s|j#dBt%|j |j C} | j'|j(|j*|j,St/|j0|j2|j4|j6gs|j#dD|j4r)|j2s |j0r|j#dE|j*r|j2s|j#dF|j8|j#dGt;|j2|j0|j4|j6|j|j|j |j |j<H } |j>roddl } |j8} | jC| \} }}|jDg|jFtH_%dI|jD|jL|jN|ddJ}n|j8g|jFtH_%tjPjS|j8tHjPd<tUjV|j85}tY|j[|j8dK}ddd|j8dIdddL}| j]||| je} |jfs2| j'|j(|j*|j,yycc}}wcc}}w#1swYxYw#t^$r6}tIj`dMtHjJddN|Yd}~d}~wtb$rYwxYw)ONrz --versionversionz trace 2.0)actionrz Main optionsz(One of these (or --report) must be givenz-cz--count store_truezCount the number of times each line is executed and write the counts to .cover for each module executed, in the module's directory. See also --coverdir, --file, --no-report below.)rhelpz-tz--tracez3Print each line to sys.stdout before it is executedz-lz --listfuncszKeep track of which functions are executed at least once and write the results to sys.stdout after the program exits. Cannot be specified alongside --trace or --count.z-Tz --trackcallsz^Keep track of caller/called pairs and write the results to sys.stdout after the program exits. Modifiersz-rz--reportzGenerate a report from a counts file; does not execute any code. --file must specify the results file to read, which must have been created in a previous run with --count --file=FILEz-Rz --no-reportz^Do not generate the coverage report files. Useful if you want to accumulate over several runs.z-fz--filez+File to accumulate counts over several runs)rz-Cz --coverdirzDirectory where the report files go. The coverage report for . will be written to file //.coverz-mz --missingz?Annotate executable lines that were not executed with ">>>>>> "z-sz --summaryz\Write a brief summary for each file to sys.stdout. Can only be used with --count or --reportz-gz--timingzQPrefix each line with the time since the program started. Only used while tracingFilterszCan be specified multiple timesz--ignore-moduleappendzqIgnore the given module(s) and its submodules (if it is a package). Accepts comma separated list of module names.)rdefaultrz --ignore-dirzWIgnore files in the given directory (multiple directories can be joined by os.pathsep).z--moduleFzTrace a module. progname?zfile to run as main program)nargsr argumentszarguments to the programstdlib platstdlibctjjtjj|}|j dj d}tjj |S)Nz$prefixz $exec_prefix)r r expanduser expandvarsr2r)s _exec_prefix_prefixs rparse_ignore_dirzmain..parse_ignore_dirsX GG  rww11!4 5 IIi ) 1 1., Oww""r,z-r/--report requires -f/--file)rErFzLmust specify one of --trace, --count, --report, --listfuncs, or --trackcallsz8cannot specify both --listfuncs and (--trace or --count)z3--summary can only be used with --count or --reportz3progname is missing: required with the main options)rrrrrErFrr)r!r __package__ __loader____spec__ __cached__r)rr!r)r,zCannot run file z because: )4argparseArgumentParser add_argumentadd_argument_groupadd_mutually_exclusive_group REMAINDER parse_args ignore_dir sysconfigget_path ignore_modulesplitstripr pathsepreportr@errorrrmissingrurvanyrr listfuncs trackcallsrrrmodulerunpy_get_module_detailsrrr/argvparentloaderr rgio open_coderrrrLexit SystemExitr no_report)r-parsergrp_grpoptsr'rrr$rtrB module_namemod_namemod_specrglobsrrRr%r&s @@rmainrUYs  $ $ &F  I{K  # #N 6 8CT9\&' T9\FHT=EFT>,78  # #K 0C  + + -DdJ|  dM,GHT8>@T<23T;|T;|=>T:l+,  # #I - /C&x!"^HbGH  </1  #.0  8+=+=+-    D $$X. )),7 # $(#5#5O#5a#))+AMOD!%N /19LA(*9L+ /NDO {{yy LL9 :!DIIF$$T\\4<<OO  DJJH I 4 5 ~~4:: OP ||DJJ JK }} JK djj$**??t7I7Iii  5A ;; --K','@'@'M $Hh((:4>>:CH& ,,'&oo$" E 77CH''//$--8CHHQKdmm,rwwy$--@-!MM&#" E ue$ iikG >>dllDLL$--H ONX-, H SXXa[#FGG    sC!-W&&3W,C6W>&W2+,W>2W;7W>> Y,X88 YYrr)__doc____all__rGrkr r/r5rrnrrrrHtimerrrrrr+r9rrrrrjrrUr!r$rrrYs<( % &    ##00d 8ll\  . #T6T6lPId ZFr