
    Rhq                        d Z ddg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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Z G d d      Zd	 Zd
 Z G d d      Zd Zd ZddZd Z G d d      Zd Zedk(  r e        yy)a  program/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")
TraceCoverageResults    N)	monotonicz#pragma NO COVERc                       e Zd ZddZd Zy)_IgnoreNc                     |s
t               n
t        |      | _        |sg n,|D cg c]!  }t        j                  j	                  |      # c}| _        ddi| _        y c c}w )Nz<string>   )set_modsospathnormpath_dirs_ignore)selfmodulesdirsds       /usr/lib/python3.12/trace.py__init__z_Ignore.__init__F   sR    ")SUs7|
#R37*9./ +-''*:*:1*= *9
#Q(*9s   &Ac                    || j                   v r| j                   |   S || j                  v rd| j                   |<   y| j                  D ]'  }|j                  |dz         sd| j                   |<    y |d| j                   |<   y| j                  D ]5  }|j                  |t        j
                  z         s&d| j                   |<    y d| j                   |<   y)Nr	   .r   )r   r   
startswithr   r   sep)r   filename
modulenamemodr   s        r   namesz_Ignore.namesL   s    %<<
++ #'(DLL$ :: 	C $$S3Y/+,Z(	 '(DLL$  
	A ""1rvv:.+,Z(
	 $%Z     NN)__name__
__module____qualname__r   r    r   r   r   r   E   s    ))r   r   c                     t         j                  j                  |       }t         j                  j                  |      \  }}|S ),Return a plausible module name for the path.)r   r   basenamesplitext)r   baser   exts       r   _modnamer+   w   s5     77D!DGG$$T*MHcOr   c                    t         j                  j                  |       }d}t        j                  D ]m  }t         j                  j                  |      }|j	                  |      s4|t        |         t         j                  k(  sTt        |      t        |      kD  sl|}o |r| t        |      dz   d }n| }t         j                  j                  |      \  }}|j                  t         j                  d      }t         j                  r |j                  t         j                  d      }t         j                  j                  |      \  }}|j                  d      S )r&    r	   Nr   )r   r   normcasesysr   lenr   
splitdrivereplacealtsepr(   lstrip)r   comparepathlongestdirr)   driver   r*   s           r   _fullmodnamer9   ~   s	    ''""4(KGxx ggs#!!#&;s3x+@BFF+J3x#g,&	 CL1$%&''$$T*KE4<<$D	yy||BIIs+GG$$T*MHc??3r   c                   4    e Zd Z	 	 ddZd Zd ZddZd	dZy)
r   Nc                    || _         | j                   i | _         | j                   j                         | _        || _        | j                  i | _        | j                  j                         | _        || _        | j                  i | _        | j                  j                         | _        || _        || _        | j
                  r]	 t        | j
                  d      5 }t        j                  |      \  }}}d d d        | j                  | j                  |||             y y # 1 sw Y   .xY w# t        t        t        f$ r5}t        d| j
                  d|t         j"                         Y d }~y d }~ww xY w)Nrb)callerszSkipping counts file : file)countscopycountercalledfuncsr=   infileoutfileopenpickleloadupdate	__class__OSErrorEOFError
ValueErrorprintr/   stderr)r   rA   rD   rE   r=   rF   ferrs           r   r   zCoverageResults.__init__   sC   ;;DK{{'')&#!D++002<<DL||((*;;N$++t, B39;;q>0FKBDNN6;NPQ B B Xz2 N)-c;BE**N NNs0   D0 D$7+D0 $D-)D0 0E9+E44E9c                 J    |j                  d      xr |j                  d      S )z_Return True if the filename does not refer to a file
        we want to have reported.
        <>)r   endswith)r   r   s     r   is_ignored_filenamez#CoverageResults.is_ignored_filename   s%     ""3'BH,=,=c,BBr   c                    | j                   }| j                  }| j                  }|j                   }|j                  }|j                  }|D ]  }|j                  |d      ||   z   ||<    |D ]  }d||<   	 |D ]  }d||<   	 y)z.Merge in the data from another CoverageResultsr   r	   N)rA   rD   r=   get)	r   otherrA   rD   r=   other_countsother_calledfuncsother_callerskeys	            r   rJ   zCoverageResults.update   s    &&,,||!-- 	AC **S!,|C/@@F3K	A % 	!C K	! ! 	CGCL	r   c                    | j                   rIt                t        d       | j                   }t        |      D ]  \  }}}t        d|d|d|        | j                  rt                t        d       dx}}	t        | j                        D ]\  \  \  }
}}\  }}}|
|k7  rt                t        d|
d       |
}d}	||
k7  r|	|k7  rt        d|       |}	t        d	|d
|d|d
|       ^ i }| j                  D ]0  \  }}|j                  |i       x}||<   | j                  ||f   ||<   2 i }|j                         D ]U  \  }}| j                  |      r|j                  d      r|dd }|Ht        j                  j                  t        j                  j                  |            }t        |      }n$|}t        j                  |d       t        |      }|rt!        |      }ni }t#        j$                  |      }t        j                  j'                  ||dz         }t)        |d      5 }t+        j,                  |j.                        \  }}ddd       | j1                  ||||      \  }}|s8|s<t3        d|z  |z        }||||f||<   X |r8|r6t        d       t        |      D ]  }||   \  }}}}t        d||   z          | j4                  rY	 t)        | j4                  d      5 } t7        j8                  | j                  | j                   | j                  f| d       ddd       yy# 1 sw Y   xY w# 1 sw Y   yxY w# t:        $ r(}!t        d|!z  t<        j>                         Y d}!~!yd}!~!ww xY w)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.
        zfunctions called:z
filename: z, modulename: , funcname: zcalling relationships:r-   z***z  -->z    r   z -> z.pycNT)exist_okz.coverr<   d   zlines   cov%   module   (path)z%5d   %3d%%   %s   (%s)wbr	   z"Can't save counts files because %sr?   ) rD   rO   sortedr=   rA   rY   itemsrW   rV   r   r   dirnameabspathr+   makedirsr9   _find_executable_linenos	linecachegetlinesjoinrG   tokenizedetect_encodingreadlinewrite_results_fileintrF   rH   dumprL   r/   rP   )"r   show_missingsummarycoverdircallsr   r   funcnamelastfile	lastcfilepfilepmodpfunccfilecmodcfuncper_filelineno	lines_hitsumscountr7   lnotabsource	coverpathfpencoding_n_hitsn_linespercentmrQ   rR   s"                                     r   write_resultszCoverageResults.write_results   s|    G%&$$E28- <.*h"J: << <<G*+#%%Hydll+
I<%%u';tUH$G%.$H "IE>i5&8'5) %IdE4GH
I  $ 	@Hf-5\\(B-GGI* $Xv,> ?If	@
 '~~/ 	JOHe''1  (#CR=ggoobggooh&?@%h/
C$/)(3
 1(;''1FS*x*?@Ih% D&66r{{C!D"55i6<eXOOFG7cFlW45#*GZ#IZ ;	J@ t23D\ ;9=a6*h/$q'9:; <<S$,,- &KKd.>.> M !1&& & D D$& &  S:S@szzRRSsB   3#L;"M 89M1M ;M	MM M 	NM??Nc                    	 t        |d|      }d	}d	}	|5  t        |d
      D ]  \  }
}|
|v r"|j                  d||
   z         |	d
z  }	|d
z  }n4|
|v rt        |vr|j                  d       |d
z  }n|j                  d       |j                  |j                  d              	 ddd       |	|fS # t        $ r,}t        d|d|dt        j                         Y d}~yd}~ww xY w# 1 sw Y   |	|fS xY w)z'Return a coverage results file in path.wr   ztrace: Could not open z for writing: z - skippingr?   N)r   r   r   r	   z%5d: z>>>>>> z          )	rG   rL   rO   r/   rP   	enumeratewritePRAGMA_NOCOVER
expandtabs)r   r   linesr   r   r   rF   rR   r   r   r   lines               r   rq   z"CoverageResults.write_results_file(  s   	4x8G  	2 )% 3 2 Y&MM'If,="=>aKFqLGv%n.D MM),qLGMM),dooa012	2" w1  	26=DGJJP		2" ws#   B2 BC*2	C';"C""C'*C6)NNNNN)TFNN)r!   r"   r#   r   rW   rJ   r   rq   r$   r   r   r   r      s&    =A'+N4C$YSvr   c                 X    i }t        j                  |       D ]  \  }}||vsd||<    |S )z:Return dict where keys are lines in the line number table.r	   )disfindlinestarts)codestrslinenosr   r   s        r   _find_lines_from_coder   H  s=    G''-  	6GFO  Nr   c                     t        | |      }| j                  D ]3  }t        j                  |      s|j	                  t        ||             5 |S )z<Return lineno dict for all code objects reachable from code.)r   	co_constsinspectiscoderJ   _find_lines)r   r   r   cs       r   r   r   R  sK     $D$/G ^^ 1>>!NN;q$/01 Nr   c                 `   i }t         j                  }t        | |      5 }t        j                  |j
                        }|D ]S  \  }}}}	}
|t         j                  k(  r6|t         j                  k(  r#|\  }}|	\  }}t        ||dz         D ]  }d||<   	 |}U 	 ddd       |S # 1 sw Y   |S xY w)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.
    r   r	   N)tokenINDENTrG   rn   generate_tokensrp   STRINGrange)r   r   r   
prev_ttyperQ   tokttypetstrstartendr   slinescolelineecolis                   r   _find_stringsr   ^  s     	A J	h	* 	a&&qzz2-0 	)E4T$-"'KE4"%KE4"5%!)4 ! !!J		 H	 Hs   A8B##B-c                 L   	 t        j                  |       5 }|j                         }|j                  }ddd       t        | d      }t        |       }t        ||      S # 1 sw Y   .xY w# t        $ r-}t        d| d|t        j                         i cY d}~S d}~ww xY w)zAReturn dict where keys are line numbers in the line number table.NzNot printing coverage data for r>   r?   exec)rn   rG   readr   rL   rO   r/   rP   compiler   r   )r   rQ   progr   rR   r   r   s          r   rj   rj   u  s    ]]8$ 	"668DzzH	" 46*D8,DtT""	" 	"  !)307:zz	C	s3   A- A!A- !A*&A- -	B#6"BB#B#c                   ^    e Zd Z	 	 	 ddZd ZddZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zy)r   Nc
                    || _         || _        t        ||      | _        i | _        i | _        d| _        || _        i | _        i | _	        i | _
        d| _        |	rt               | _        |r| j                  | _        y|r| j                  | _        y|r%|r#| j                   | _        | j"                  | _        y|r#| j                   | _        | j&                  | _        y|r#| j                   | _        | j(                  | _        yd| _        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
        r   Nr	   )rE   rF   r   ignorerA   pathtobasename	donothingtrace_calledfuncs_callers_caller_cache
start_time_timeglobaltrace_trackcallersglobaltraceglobaltrace_countfuncsglobaltrace_ltlocaltrace_trace_and_count
localtracelocaltrace_tracelocaltrace_count)
r   r   r   
countfuncscountcallers
ignoremods
ignoredirsrE   rF   timings
             r   r   zTrace.__init__  s    ( j*5 
#gDO#<<D#::Du#22D"==DO#22D"33DO#22D"33DO DNr   c                 J    dd l }|j                  }| j                  |||       y )Nr   )__main____dict__runctx)r   cmdr   dicts       r   runz	Trace.run  s       Ct$r   c                    |i }|i }| j                   s>t        j                  | j                         t	        j                  | j                         	 t        |||       | j                   s+t	        j                  d        t        j                  d        y y # | j                   s+t	        j                  d        t        j                  d        w w xY wr   )r   	threadingsettracer   r/   r   )r   r   globalslocalss       r   r   zTrace.runctx  s    ?bG>B6~~t//0LL))*	)gv&>>T"""4( "4>>T"""4( "s   B 9Cc                   d }| j                   st        j                  | j                         	  ||i |}| j                   st        j                  d        |S # | j                   st        j                  d        w w xY wr   )r   r/   r   r   )r   funcargskwresults        r   runfunczTrace.runfunc  sh    ~~LL))*	#4&2&F>>T" >>T" "s   A $A>c                    |j                   }|j                  }|rt        |      }nd }|j                  }d }|| j                  v r | j                  |   | j                  |   }nd | j                  |<   t        j                  |      D cg c]  }t        j                  |      r| }}t        |      dk(  rt        j                  |d         D 	cg c]  }	t        |	t              r|	 }
}	t        |
      dk(  r]t        j                  |
d         D cg c]  }t        |d      r| }}t        |      dk(  r|d   j                  }|| j                  |<   ||d|}|||fS c c}w c c}	w c c}w )Nr	   r   	__bases__r   )f_codeco_filenamer+   co_namer   gcget_referrersr   
isfunctionr0   
isinstancer   hasattrr!   )r   framer   r   r   rx   clsnamerQ   funcsr   dictsr   classess                r   file_module_function_ofzTrace.file_module_function_of  s   ||##!(+JJ<<4%%%!!$'3,,T2'+Dt$ !# 0 0 6 31#..q1  3E 3
 5zQ$&$4$4U1X$> 5q *1d 3  5 5u:?*,*:*:58*D ?Q&-a&=  ! ?G ?7|q(")!*"5"5
 4;**40")84HX---35?s   E'E,E1c                     |dk(  r>| j                  |      }| j                  |j                        }d| j                  ||f<   yy)zkHandler for call events.

        Adds information about who called who to the self._callers dict.
        callr	   N)r   f_backr   )r   r   whyarg	this_funcparent_funcs         r   r   zTrace.globaltrace_trackcallers  sG    
 &=44U;I66u||DK67DMM;	23	 r   c                 P    |dk(  r!| j                  |      }d| j                  |<   yy)zoHandler for call events.

        Adds (filename, modulename, funcname) to the self._calledfuncs dict.
        r   r	   N)r   r   )r   r   r   r   r   s        r   r   zTrace.globaltrace_countfuncs  s0    
 &=44U;I+,Di( r   c                 $   |dk(  r|j                   }|j                  j                  dd      }|r`t        |      }|R| j                  j                  ||      }|s3| j                  rt        d|d|j                         | j                  S yyyy)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_globalsrY   r+   r   r   r   rO   r   r   )r   r   r   r   r   r   r   	ignore_its           r   r   zTrace.globaltrace_lt  s     &=<<D**:t<H &h/
) $ 1 1(J GI$::!&0$,,$@ B#.	 % *  r   c           	         |dk(  r|j                   j                  }|j                  }||f}| j                  j	                  |d      dz   | j                  |<   | j
                  r%t        dt               | j
                  z
  z  d       t        j                  j                  |      }t        d||t        j                  ||      fz  d       | j                  S )	Nr   r   r	   %.2f r   
%s(%d): %sr-   )r   r   f_linenorA   rY   r   rO   r   r   r   r'   rk   getliner   )r   r   r   r   r   r   r^   bnames           r   r   z Trace.localtrace_trace_and_count'  s    &=||//H^^FF"C#{{sA6:DKKf$// 9:DGG$$X.E,%"+"3"3Hf"E"G GLNPr   c           	      V   |dk(  r|j                   j                  }|j                  }| j                  r%t	        dt               | j                  z
  z  d       t        j                  j                  |      }t	        d||t        j                  ||      fz  d       | j                  S )Nr   r  r  r	  r
  r-   )r   r   r  r   rO   r   r   r   r'   rk   r  r   )r   r   r   r   r   r   r  s          r   r   zTrace.localtrace_trace6  s    &=||//H^^Ff$// 9:DGG$$X.E,%"+"3"3Hf"E"G GLNPr   c                     |dk(  rR|j                   j                  }|j                  }||f}| j                  j	                  |d      dz   | j                  |<   | j
                  S )Nr   r   r	   )r   r   r  rA   rY   r   )r   r   r   r   r   r   r^   s          r   r   zTrace.localtrace_countC  sW    &=||//H^^FF"C#{{sA6:DKKr   c                     t        | j                  | j                  | j                  | j                  | j
                        S )N)rE   rF   rD   r=   )r   rA   rE   rF   r   r   )r   s    r   resultszTrace.resultsK  s2    t{{4;;'+||+/+<+<'+}}6 	6r   )	r	   r	   r   r   r$   r$   NNFr    )r!   r"   r#   r   r   r   r   r   r   r   r   r   r   r   r  r$   r   r   r   r     sI    DEDH0d%
)	'.R	8-.6r   c                     dd l } | j                         }|j                  ddd       |j                  dd      }|j                  dd	d
d       |j                  ddd
d       |j                  ddd
d       |j                  ddd
d       |j                  d      }|j	                         }|j                  ddd
d       |j                  ddd
d       |j                  ddd        |j                  d!d"d#        |j                  d$d%d
d&       |j                  d'd(d
d)       |j                  d*d+d
d,       |j                  d-d.      }|j                  d/d0g d12       |j                  d3d0g d42       |j                  d5d
d6d72       |j                  d8d9d:;       |j                  d<| j
                  d=;       |j                         }|j                  r*t        j                  d>      t        j                  d?      fd@}|j                  D cg c](  }|j                  dA      D ]  }|j                          * c}}|_
        |j                  D cg c].  }|j                  t        j                        D ]
  } ||       0 c}}|_        |j                  ro|j                   s|j#                  dB       t%        |j                   |j                   C      }	|	j'                  |j(                  |j*                  |j,                        S t/        |j0                  |j2                  |j4                  |j6                  g      s|j#                  dD       |j4                  r)|j2                  s|j0                  r|j#                  dE       |j*                  r|j2                  s|j#                  dF       |j8                  |j#                  dG       t;        |j2                  |j0                  |j4                  |j6                  |j                  |j                  |j                   |j                   |j<                  H	      }
	 |j>                  rodd l }|j8                  }|jC                  |      \  }}}|jD                  g|jF                  tH        _%        dI|jD                  |jL                  |jN                  |d dJ}n|j8                  g|jF                  tH        _%        t        jP                  jS                  |j8                        tH        jP                  d<   tU        jV                  |j8                        5 }tY        |j[                         |j8                  dK      }d d d        |j8                  dId d dL}|
j]                  ||       |
je                         }	|jf                  s2|	j'                  |j(                  |j*                  |j,                         y y c c}}w c c}}w # 1 sw Y   xY w# t^        $ r6}tI        j`                  dMtH        jJ                  d   dN|       Y d }~d }~wtb        $ r Y w xY w)ONr   z	--versionversionz	trace 2.0)actionr  z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 <module>.cover for each module executed, in the module's directory. See also --coverdir, --file, --no-report below.)r  helpz-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)r  z-Cz
--coverdirzDirectory where the report files go. The coverage report for <package>.<module> will be written to file <dir>/<package>/<module>.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 tracingFilterszCan be specified multiple timesz--ignore-moduleappendzqIgnore the given module(s) and its submodules (if it is a package). Accepts comma separated list of module names.)r  defaultr  z--ignore-dirzWIgnore files in the given directory (multiple directories can be joined by os.pathsep).z--moduleFzTrace a module. progname?zfile to run as main program)nargsr  	argumentszarguments to the programstdlib
platstdlibc                     t         j                  j                  t         j                  j                  |             } | j	                  d      j	                  d      } t         j                  j                  |       S )Nz$prefixz$exec_prefix)r   r   
expanduser
expandvarsr2   r   )s_exec_prefix_prefixs    r   parse_ignore_dirzmain.<locals>.parse_ignore_dir  sX    GGrww11!45IIi)11.,Oww""r   ,z-r/--report requires -f/--file)rE   rF   zLmust 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)r   r   r   r   rE   rF   r   r   )r!   r  __package__
__loader____spec__
__cached__r   )r  r!   r)  r,  zCannot run file z
 because: )4argparseArgumentParseradd_argumentadd_argument_groupadd_mutually_exclusive_group	REMAINDER
parse_args
ignore_dir	sysconfigget_pathignore_modulesplitstripr   pathsepreportr@   errorr   r   missingru   rv   anyr   r   	listfuncs
trackcallsr  r   r   modulerunpy_get_module_detailsr   r  r/   argvparentloaderr   rg   io	open_coder   r   r   rL   exit
SystemExitr  	no_report)r-  parsergrp_grpoptsr'  r   r   r$  r  trB  module_namemod_namemod_specr   globsr   rR   r%  r&  s                      @@r   mainrU  Q  s   $$&F
I{K

#
#N68C T9\&  '
 T9\F  HT=E  F T>,7  8 
#
#K
0C++-DdJ|   
 	dM,G  H T8>  @T<2  3 T;|   T;|=  > T:l+  , 
#
#I-/C&x!  " ^HbG  H 
</  1

#.  0
8+=+=+  - D$$X. )),7# $(#5#5OO:= ))+ O+ OD !%N9LN45 (* N* NDO {{yyLL9:!DIIF$$T\\4<<OO

DJJHI 4 	5 ~~4::OP||DJJJK}}JKdjj$**??t7I7Iii	5A;;--K','@'@'M$Hh((:4>>:CH& ,,'&oo$"E 77CH''//$--8CHHQKdmm, Arwwy$--@A !MM&#"	E 	
ue$ iikG>>dllDLL$--H ONXA A  HSXXa[#FGG sC   !-W&&3W,C6W> &W2+,W> 2W;7W> >	Y,X88YYr   r   )__doc____all__rG  rk   r   r/   r5  r   rn   r   r   r   rH   timer   r   r   r   r   r+   r9   r   r   r   r   rj   r   rU  r!   r$   r   r   <module>rY     s   <( %
& 	  	 
     	 
  # #0 0d 8l l\
.#L6 L6\PId ZF r   