
    G@d                        d 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
 ddlmZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ ddlmZmZmZmZmZmZ dd	lm Z  dd
l!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8 ddl9m:Z:  ej;        e<          Z=e3j>        Z? G d d          Z@ G d d          ZA G d d          ZB G d d          ZC G d d          ZD G d d           ZEd! ZFd" ZG G d# d$e$          ZH G d% d&e          ZI G d' d(ee&          ZJd) ZKd* ZLe<d+k    r eL             dS dS ),zv
Profiler widget.

See the official documentation on python profiling:
https://docs.python.org/3/library/profile.html
    N)islice)PYQT5)getopenfilenamegetsavefilename)
QByteArrayQProcessQProcessEnvironmentQtSignal)QColor)QApplicationQLabelQMessageBoxQTreeWidgetQTreeWidgetItemQVBoxLayout)on_conf_change_)PluginMainWidget)SpyderWidgetMixin)get_conf_pathrunning_in_mac_app)
TextEditor)to_text_string)get_python_executablegetcwd_or_home)SpyderPaletteQStylePalette)shell_split)get_item_user_textset_item_user_text)PythonModulesComboBoxc                   .    e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
ProfilerWidgetActionsbrowse_actionclear_actioncollapse_actionexpand_actionload_data_action
run_actionsave_data_actionshow_output_actionN)__name__
__module____qualname__BrowseClearCollapseExpandLoadDataRunSaveData
ShowOutput     Klib/python3.11/site-packages/spyder/plugins/profiler/widgets/main_widget.pyr%   r%   9   s6        FE HF!H
C!H%JJJr:   r%   c                       e Zd ZdZdS )ProfilerWidgetToolbarsinformation_toolbarN)r.   r/   r0   Informationr9   r:   r;   r=   r=   E   s        'KKKr:   r=   c                       e Zd ZdZdS )!ProfilerWidgetMainToolbarSectionsmain_sectionNr.   r/   r0   Mainr9   r:   r;   rA   rA   I           DDDr:   rA   c                       e Zd ZdZdS )(ProfilerWidgetInformationToolbarSectionsrB   NrC   r9   r:   r;   rG   rG   M   rE   r:   rG   c                       e Zd ZdZdS )ProfilerWidgetMainToolbarItems
file_comboN)r.   r/   r0   	FileCombor9   r:   r;   rI   rI   Q   s        IIIr:   rI   c                       e Zd ZdZdZdZdS )%ProfilerWidgetInformationToolbarItemsstretcher_1stretcher_2
date_labelN)r.   r/   r0   
Stretcher1
Stretcher2	DateLabelr9   r:   r;   rM   rM   U   s        JJIIIr:   rM   c                  :    ddl m}   | d          o
 | d          S )Nr   is_module_installedcProfilepstats)spyder.utils.programsrV   rU   s    r;   is_profiler_installedrZ   ]   s6    999999z**L/B/B8/L/LLr:   c                 R   d}t          j        ||           }t          |          dk    rdS d}|D ]u}t          |d                   }|d         dk    r|dz  }nG|d         dk    r|d	z  }n5|d         d
k    r|dz  }n#|d         dk    r|dz  }n|d         dk    r|dz  }||z  }v|S )z
    Parse text and return a time in seconds.

    The text is of the format 0h : 0.min:0.0s:0 ms:0us:0 ns.
    Spaces are not taken into account and any of the specifiers can be ignored.
    u   ([+-]?\d+\.?\d*) ?([mμnsinh]+)r   Ng           ns&.>u   μsư>msMbP?min<   h  )refindalllenfloat)textpatternmatchestimerestmps         r;   	gettime_srp   b   s     1Gj$''G
7||qtD  CFmmq6T>>4KCCVz!!4KCCVt^^4KCCVu__2ICCVs]]4KCKr:   c                   (    e Zd ZdZdZ ed          Z eee	e          Z
	  e            Z	  e            Z	 d fd	Zd Zd Zd Zd	 Zd
 Zd ZddZ edd          d             Zd Zd Zd ZddZd dZd Zd ZddZd Zd Z ddZ! xZ"S )!ProfilerWidgetz
    Profiler widget.
    Tzprofiler.resultsNc                    t                                          |||           |                     dt                     d | _        d | _        d | _        d | _        d | _        d| _	        | 
                    d          | _        d | _        t          | t          j                  | _        t#          |           | _        t'                      | _        t*          j        | j        _        t1                      }|                    | j                   |                     |           | j        j                            | j                   d S )N
text_colorFid_)super__init__set_confMAIN_TEXT_COLOR
_last_wdir
_last_args
pythonpatherror_outputoutputrunningget_confrt   processr#   rI   rK   	filecomboProfilerDataTreedatatreer   	datelabelrM   rS   IDr   	addWidget	setLayoutsig_edit_goto_requestedconnect)selfnamepluginparentlayout	__class__s        r;   rx   zProfilerWidget.__init__   s'   vv...lO444  --55 .4>@ @ @(..AK '''v 	-55(	* 	* 	* 	* 	*r:   c                      t          d          S )NProfilerr   r   s    r;   	get_titlezProfilerWidget.get_title   s    }}r:   c                     | j         S N)r   r   s    r;   get_focus_widgetzProfilerWidget.get_focus_widget   s
    }r:   c           	                                t          j        t          d          t          d                               d           j                   _                              t          j        dt          d                               d           fd          }                      t          j        t          d          t          d	                               d
           j	                   _
                              t          j        t          d          t          d                               d          d% fd	           _                              t          j        t          d          t          d                               d          d% fd	           _                              t          j        t          d          t          d                               d           j                   _                              t          j        t          d          t          d                               d           j                   _                              t          j        t          d          t          d                               d           j                   _         j                            d            j                            d                                            } j        | j        fD ]$}                     ||t8          j                   %                     t>          j                   } j         j         !                    tD          j#                   j$         !                    tD          j%                   j
         j         j         j        f	D ]$}                     ||tL          j                   %tO                      so j(         j         j        fD ]}|)                    d           d}t          d           d!|d"t          d#          d$} j$        *                    |           d S d S )&NzRun profilerrun)rj   tipicon	triggered Select Python filefileopenc                 ,                                     S r   )select_filexr   s    r;   <lambda>z&ProfilerWidget.setup.<locals>.<lambda>   s     0 0 2 2 r:   OutputzShow program's outputlogr3   zCollapse one level upcollapsec                 8    j                             d          S )Nr   change_viewr   s    r;   r   z&ProfilerWidget.setup.<locals>.<lambda>   s    T]%>%>r%B%B r:   r4   zExpand one level downexpandc                 8    j                             d          S Nr\   r   r   s    r;   r   z&ProfilerWidget.setup.<locals>.<lambda>   s    T]%>%>q%A%A r:   z	Save datazSave profiling datafilesavez	Load dataz"Load profiling data for comparison
fileimportzClear comparison
editdeleteF)toolbarsectionru   Tz.https://docs.python.org/3/library/profile.htmlzPlease installz	 <a href=>zthe Python profiler modulesz</a>r   )+create_actionr%   r6   r   create_iconr   start_actionr1   r8   show_log
log_actionr3   r(   r4   r)   r7   	save_datasave_actionr5   compareload_actionr2   clearr'   
setEnabledget_main_toolbarr   add_item_to_toolbarrA   rD   create_toolbarr=   r?   create_stretcherrM   rQ   r   rR   rG   rZ   r   setDisabledsetText)r   r&   r   itemsecondary_toolbarwidgeturlrj   s   `       r;   setupzProfilerWidget.setup   s    ..!%>"".!!!!%((h / 
 
 **!(&''!!*--2222 + 
 
 ,,!,8)**!!%((m - 
 
  $11!*:)**!!*--BBBBB  2  
  
 "//!(8)**!!(++AAAAA 0 
 
  --!*;'((!!*--n . 
 
  --!*;677!!,//l . 
 
 !..!'%&&$%%!!,//j / 
 
 	$$U+++##E*** ''))^]D4EF 	 	D$$9> %     !//".0 0)4+=**BM + O O^**BM + O O_%t'79JL 	 	D $$)@E %     %&& 
	)  =$.,. ) )""4((((BC-./?-@-@-@-@###-./L-M-M-M-MODN""4(((((
	) 
	)r:   c                    | j         r|                     d          }n|                     d          }| j                            |           | j                            | j                     | j                            | j                     | j                            t          | j        	                                                     d S )Nstopr   )
r   r   r   setIconr   r   r'   boolr   currentText)r   r   s     r;   update_actionszProfilerWidget.update_actions'  s    < 	+##F++DD##E**D!!$'''##$4555$$%5666$$T$.*D*D*F*F%G%GHHHHHr:   c                     | j         Z| j                                         t          j        k    r3| j                                          | j                             d           |                                  dS )z,Kill the profiling process if it is running.N  )r   stater   RunningclosewaitForFinishedr   r   s    r;   _kill_if_runningzProfilerWidget._kill_if_running4  sh    <#|!!##x'777""$$$,,T222r:   c                     d| _         |                                  | j        | j        z   | _        | j                            d           |                     d           | j                            d           | 	                                 dS )z
        Parse results once the profiling process has ended.

        Parameters
        ----------
        exit_code: int
            QProcess exit code.
        exit_status: str
            QProcess exit status.
        Fr   T)justanalyzedN)
r   show_errorlogr~   r   r   r   	show_datar   r   r   )r   	exit_codeexit_statuss      r;   	_finishedzProfilerWidget._finished=  s     '$+5r"""D)))##D)))r:   Fc                     |r%| j                             t          j                   n$| j                             t          j                   t                      }| j                                         rT|r|| j                                         z  }n|| j                                         z  }| j                                         Tt          |
                                d          }|r| xj        |z  c_        dS | xj        |z  c_        dS )z
        Read otuput from QProcess.

        Parameters
        ----------
        error: bool, optional
            Process QProcess output or error channels. Default is False.
        zutf-8)encodingN)r   setReadChannelr   StandardErrorStandardOutputr   bytesAvailablereadAllStandardErrorreadAllStandardOutputr   datar~   r   )r   errorqbarj   s       r;   _read_outputzProfilerWidget._read_outputP  s     	AL''(>????L''(?@@@lll))++ 	< <t|88:::t|99;;;	 l))++ 	< chhjj7;;; 	 %KK4KKKKr:   pythonpath_managerspyder_pythonpath)r   optionc                     || _         d S r   )r}   )r   values     r;   _update_pythonpathz!ProfilerWidget._update_pythonpathk  s    r:   c                 (   t          d          }t          | |t                      t          d          dz             \  }}t          j        |          d                                         }|s|dz   }|r| j                            |           dS dS )z
Save data.zSave profiler resultProfiler result (*.Result)r\   z.ResultN)r   r   r   ospsplitextlowerr   r   )r   titlefilename
_selfilter	extensions        r;   r   zProfilerWidget.save_dataq  s    ()).  =0	 
  
* L**1-3355	 	,  )+H 	.M##H-----	. 	.r:   c                 N   t          | t          d          t                      t          d          dz             \  }}|rd| j                            |           |                                  | j                            d           | j                            d           dS dS )z)Compare previous saved run with last run.zSelect script to comparer   r   TN)	r   r   r   r   r   r   r   r   r'   r   r   r   s      r;   r   zProfilerWidget.compare  s    .())  =0	 
  
*  	/M!!(+++NN''---((.....		/ 	/r:   c                     | j                             d           | j                             d           |                                  | j                            d           dS )zClear data in tree.NTF)r   r   hide_diff_colsr   r'   r   r   s    r;   r   zProfilerWidget.clear  s[    d###$$T***$$U+++++r:   c                    t                      sdS |                                  | j        fdt                                                    D             }d}|S||vrO| j                            |           | j                            | j                                        dz
             n2| j                            | j                            |                     | j                                         | j        	                                r.|t          j        |          }|                     ||           dS dS )
        Start the profiling process.

        Parameters
        ----------
        wdir: str
            Working directory path string. Default is None.
        args: list
            Arguments to pass to the profiling process. Default is None.
        Nc                 :    g | ]}                     |          S r9   )itemText).0idxcombos     r;   
<listcomp>z*ProfilerWidget.analyze.<locals>.<listcomp>  s%    EEE$$EEEr:   r\   )rZ   r   r   rangecountaddItemsetCurrentIndexfindTextselectedis_validr   dirnamestart)r   r   wdirargsitemsindexr  s         @r;   analyzezProfilerWidget.analyze  s:    %&& 	F EEEEekkmm0D0DEEE=XU22N""8,,,N**4>+?+?+A+AA+EFFFFN**4>+B+B8+L+LMMM!!!>""$$ 	#|{8,,JJtT"""""		# 	#r:   c                     |r| j                             d           t          | t          d          t	                      t          d          dz             \  }}| j                             d           |r|                     |           dS dS )a  
        Select filename to profile.

        Parameters
        ----------
        filename: str, optional
            Path to filename to profile. default is None.

        Notes
        -----
        If no `filename` is provided an open filename dialog will be used.
        NFr   zPython filesz (*.py ; *.pyw)T)sig_redirect_stdio_requestedemitr   r   r   r  r   s      r;   r   zProfilerWidget.select_file  s     -225999#2&''  .!!$55	$ $ Hj -224888 	#LL"""""	# 	#r:   c                     | j         rQt          | j         t          d          d|           }|                    dd           |                                 dS dS )zShow process output log.Profiler outputTr   readonlyr       N)r   r   r   resizeexec_r   output_dialogs     r;   r   zProfilerWidget.show_log  sq    ; 	"&)**	  M   c***!!!!!	" 	"r:   c                     | j         rQt          | j         t          d          d|           }|                    dd           |                                 dS dS )zShow process error log.r  Tr  r  r  N)r~   r   r   r  r   r!  s     r;   r   zProfilerWidget.show_errorlog  ss     	"&!)**	  M   c***!!!!!	" 	"r:   c                 H    t           j                                                  }| j        }|t	          j        |          }| j        }|g }| _        | _         j                            t          d                     t                      _         j                            t          j                    j                            |            j        j                             j                    j        j                             fd            j        j                            t          j        f fd	            j        j                             j                   t-                      }t.          j                                        D ]\  }}|                    ||           |                    dd           |                    d           |                    d            j        [t:                              d	 j         d
           |                    dt.          j                              j                              j        !                    |            "                    dd          }tG          |          sH j        $                                }|                    d            j        !                    |           d _%        d _&        d _'         (                                 ddd j)        g}	t.          j*        dk    rF|	+                    t	          j,        |          -                    t.          j.        d                     n|	+                    |           |r"|	/                    ta          |                      j        1                    ||	            j        2                                }
|
s0tg          j4         t          d          t          d                      5                                 dS )r  NzProfiling, please wait...c                  0                          d          S )NT)r   )r   r   s   r;   r   z&ProfilerWidget.start.<locals>.<lambda>  s    D%%D%11 r:   c                 0                         | |          S r   )r   )ecesr   s     r;   r   z&ProfilerWidget.start.<locals>.<lambda>  s    t~~b"/E/E r:   PYTHONIOENCODINGutf8
PYTHONPATHPYTHONEXECUTABLEzPass Pythonpath z to process
executablemain_interpreterr   
PYTHONHOMEr   Tz-mrW   z-ont/ErrorzProcess failed to start)6r   r   r   r{   r   basenamer|   r   r   r   r   r   setProcessChannelModeSeparateChannelssetWorkingDirectoryreadyReadStandardOutputr   r   readyReadStandardErrorfinished
ExitStatusstop_spinnerr	   osenvironr  insertremover}   loggerdebugpathsepjoinsetProcessEnvironmentr   r   processEnvironmentr   r~   r   start_spinnerDATAPATHr   appendnormpathreplacesepextendr    r  waitForStartedr   criticalr   )r   r  r  r   proc_envkvr-  envp_argsr   s   `          r;   r  zProfilerWidget.start  s    "$."<"<">">??<?D||H--<?D|q!<==>>>~~**8+DEEE((...,44T5FGGG+331111	3 	3 	3%%"-EEEEE	G 	G 	G%%d&7888 '((J$$&& 	" 	"DAqOOAq!!!!*F333%%%*+++?&LLHDOHHHIIIOOL"*//$/*J*JKKK**8444]]<9K]LL
!*-- 	4,1133CJJ|$$$L..s333
D$-87d?? MM#,x0088EEFFFFMM(### 	-MM+d++,,,:v...,--// 	 '

+,,  
 	r:   c                     d| _         | j                                         | j                            d           |                                  |                                  dS )zStop the running process.Fr   N)r   r   r   r   r<  r   r   s    r;   r   zProfilerWidget.stop@  s]    $$T***r:   c                 h    | j         r|                                  dS |                                  dS )z1Toggle starting or running the profiling process.N)r   r   r  r   s    r;   r   zProfilerWidget.runH  s.    < 	IIKKKKKJJLLLLLr:   c                    |sd| _         | j                            | j         duot          | j                   dk               |                                  t          | j                                                  }|sdS | j        	                    t          d                     t          j                     | j                            | j                   | j                                         d}|| j        t%          j        dt%          j                              fz  }| j        	                    |           dS )z
        Show analyzed data on results tree.

        Parameters
        ----------
        justanalyzed: bool, optional
            Default is False.
        Nr   zSorting data, please wait...z)<span style='color: %s'><b>%s </b></span>z%Y-%m-%d %H:%M:%S)r   r   r   rh   r   r   r   r   r   r   r   r   processEventsr   	load_datarH  	show_treert   rm   strftime	localtime)r   r   r   
text_style	date_texts        r;   r   zProfilerWidget.show_dataO  s8     	DK""4;d#: $<'*4;'7'7!';	= 	= 	=!$."<"<">">?? 	Fq!?@@AAA"$$$...!!!B
$/"&-0C040@0@#B #B"C C	 	y)))))r:   )NNN)F)NNr   )#r.   r/   r0   __doc__ENABLE_SPINNERr   rH  r   strintr   sig_startedsig_finishedrx   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r  r   r   r   __classcell__r   s   @r;   rr   rr      s         N}/00H %fS#s33 &((KM688LN* * * * * *@    a) a) a)F	I 	I 	I    &       6 ^09LMMM    NM 
. . .$/ / /, , , #  #  #  #D# # # #4
" 
" 
"
" 
" 
"Q Q Q Qf    * * * * * * * *r:   rr   c                       e Zd ZddZd ZdS )TreeWidgetItemNc                 0    t          j        | |           d S r   )r   rx   r   r   s     r;   rx   zTreeWidgetItem.__init__p  s     v.....r:   c                    |                                                                  }	 |dk    s|dk    rNt          |                     |                    }t          |                    |                    }||||k    S t	          |                     |                    t	          |                    |                    k    S # t
          $ r/ |                     |          |                    |          k    cY S w xY w)Nr\      )
treeWidget
sortColumnrp   rj   ri   
ValueError)r   	otherItemcolumnt0t1s        r;   __lt__zTreeWidgetItem.__lt__s  s    ""--//		>{{fkktyy0011y~~f5566>bn7N6**++eINN64J4J.K.KKK 	> 	> 	>99V$$y~~f'='=====	>s   AC AC 6D Dr   )r.   r/   r0   rx   rt  r9   r:   r;   rh  rh  o  s7        / / / /> > > > >r:   rh  c                        e Zd ZdZdZ eeee          Zd fd	Z	d Z
d Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zed             Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZ S )r   a  
    Convenience tree widget (with built-in model)
    to store and view profiler data.

    The quantities calculated by the profiler are as follows
    (from profile.Profile):
    [0] = The number of times this function was called, not counting direct
          or indirect recursion,
    [1] = Number of times this function appears on the stack, minus one
    [2] = Total time spent internal to this function
    [3] = Cumulative time that this function was present on the stack.  In
          non-recursive functions, this is the total execution time from start
          to finish of each invocation of a function, including time spent in
          all subfunctions.
    [4] = A dictionary indicating for each function name, the number of times
          it was called by us.
    z<[=]>Nc           
         t           r$t                                          ||           n+t          j        | |           t	          j        | |           t          d          t          d          t          d          t          d          t          d          t          d          t          d          t          d          g| _        |                     d          |                     d	          |                     d          |                     d
          d| _        d | _	        d | _
        g | _        d | _        d | _        d | _        d | _        d | _        |                     t%          | j                             |                     | j                   |                                  | j                            | j                   | j                            | j                   d S )N)class_parentzFunction/Modulez
Total TimeDiffz
Local TimeCallsz	File:linepythonfunctionclass)moduler{  builtinconstructor)r   rw   rx   r   r   r   header_listr   	icon_listprofdatastatsstats1
item_depth	item_listitems_to_be_showncurrent_view_depthcompare_filesetColumnCountrh   setHeaderLabelsinitialize_viewitemActivatedr   item_activateditemExpandeditem_expanded)r   r   r   s     r;   rx   zProfilerDataTree.__init__  s    	BGGV&9999 v...&t&AAAA/00!L//1V99lOOQvYY'

AfIIkNN, &&x00((44''11++G44	
 
 
!%"& C 011222T-...""4#6777!!$"455555r:   c                 <    t          |d|| j        |fz             dS )z@Set tree item user data: filename (string) and line_number (int)z%s%s%dN)r"   SEPr   r   r   line_numbers       r;   set_item_datazProfilerDataTree.set_item_data  s&    4Xtx,M!MNNNNNr:   c                 x    t          |                              | j                  \  }}|t          |          fS )z0Get tree item user data: (filename, line_number))r!   splitr  rb  )r   r   r   line_number_strs       r;   get_item_datazProfilerDataTree.get_item_data  s7    $6t$<$<$B$B48$L$L!/_----r:   c                 f    |                                   d| _        g | _        i | _        d| _        dS )z"Clean the tree and view parametersr   N)r   r  r  r  r  r   s    r;   r  z ProfilerDataTree.initialize_view  s3    

!#"#r:   c                 X   ddl }	 |                    |          g}n# t          t          f$ r d| _        Y dS w xY w|d         | _        | j        	 |                    |                    | j                             nh# t          t          f$ rT}t          j        | t          d          t          d          
                    |                     d| _        Y d}~nd}~ww xY wt          d |           | j                                         || _        |d         j        | _        dS )z3Load profiler data saved by profile/cProfile moduler   Nr3  zMError when trying to load profiler results. The error was<br><br><tt>{0}</tt>c                 *    |                                  S r   )calc_callees)r   s    r;   r   z,ProfilerDataTree.load_data.<locals>.<lambda>  s    ann&& r:   )rX   StatsOSErrorIOErrorr  r  rI  r   rO  r   formatmapr  r  r  )r   profdatafilerX   
stats_indies        r;   rY  zProfilerDataTree.load_data  sR   	 ,,|447JJ! 	 	 	 DMFF	 #1()!!&,,t/@"A"ABBBBW% ) ) )$!G** % & &&,fQii	1 1 1
 %)!!!!!!) 	&&
333""$$$ ](


s%    99-A? ?C$A
CC$c                 >    |                      d           || _        d S )NF)r   r  r   r   s     r;   r   zProfilerDataTree.compare  s$    E"""$r:   c                 <    dD ]}|                      ||           d S )N)         )setColumnHidden)r   hideis      r;   r   zProfilerDataTree.hide_diff_cols  s4     	* 	*A  D))))	* 	*r:   c                 z    t          | j                  dk    r"| j        d                             |           dS dS )zSave profiler data.r   N)rh   r  
dump_statsr  s     r;   r   zProfilerDataTree.save_data  s?    t{aKN%%h/////  r:   c                     | j         | j                             d           ndS | j         j        D ]/}d|dd         k    r|d                             d          s|c S 0dS )z Find a function without a callerN
cumulative)~r   r   r  z<built-in method exec>)r  
sort_statsfcn_list
startswith)r   funcs     r;   	find_rootzProfilerDataTree.find_root  s     =$M$$\2222FM* 	 	D4!9$$T!W-?-?,.. ..$ 	 	r:   c                 &    | j         j        |         S )z/Find all functions called by (parent) function.)r  all_calleesrj  s     r;   find_calleeszProfilerDataTree.find_callees  s     }(00r:   c                    |                                   |                     d           |                     d           |                                 }||                     | |                     |                     |                     d           |                     d           |                     dt          j	                   | 
                    d           dS dS )z4Populate the tree with profiler data and display it.TFNr   r\   )r  setItemsExpandablesetSortingEnabledr  populate_treer  resizeColumnToContents	sortItemsr
   AscendingOrderr   )r   rootkeys     r;   rZ  zProfilerDataTree.show_tree  s    %%%u%%%..""tT%6%6w%?%?@@@''***""4(((NN1b/000Q r:   c                     d}|\  }}}|dk    r>t          j        |          \  }}d}|dk    rt          j        |          \  }}d|z   dz   }|r|dk    rd}d	}n|d
k    rd}d||fz  }|||||fS )zAReturns processed information about the function's name and file.r{  z<module>r}  z__init__.py<r   r  z
(built-in)r~  rx   r  z%s : %d)r   r  )	r   functionKey	node_typer   r  function_name
modulePath
moduleNamefile_and_lines	            r;   function_infozProfilerDataTree.function_info  s    	/:,+}J&&%(Yx%8%8"J
 I]**),:)>)>&
J*,s2M 	@8s??(M!II
**)	%;(??Mm]IMMr:   c                    t          |           } t          | t                    rt          |           S d| cxk     rdk    rn nd                    | dz            } n'd| cxk     rdk    rn nd                    | dz            } nd| cxk     rdk    rn nd                    | dz            } nd| cxk     rdk    rn nd	                    |           } nd| cxk     rd
k    rnn nkt          | d
          \  }}|dk    r;t          | d          \  }}t          |                              d          d         }d                    ||          } n4t          | d
          \  }}|dk    r|dz  }d                    ||          } | S )z8Get format and units for data coming from profiler task.r^   r_   z
{0:.2f} nsra   u   {0:.2f} μsr\   z
{0:.2f} msrc   z	{0:.2f} sre   .r   z{0:.0f}.{1:.2s} minz{0:.0f}h:{1:.0f}min)abs
isinstancerb  r   r  divmodr  )measuremsrd   s       r;   format_measurezProfilerDataTree.format_measure$  s    g,, gs## 	+!'*** 7####e######**7U?;;GGW%%%%%%%%%(//%@@GGW!!!!!!!!!#**7U?;;GGB"))'22GG'!!!!T!!!!!'4((DAq2vvgr**1"1%%++C004,33Aq99GG'4((DAq2vvR,33Aq99Gr:   c                 >   d}d}t          |          dk    rh| j        a|d         |d         z
  }|rN|dk     rt          j        dfnt          j        df\  }}d	                    ||                     |                    }|                     |d                   ||ggS )
a  Return a string formatted delta for the values in x.

        Args:
            x: 2-item list of integers (representing number of calls) or
               2-item list of floats (representing seconds of runtime).

        Returns:
            A list with [formatted x[0], [color, formatted delta]], where
            color reflects whether x[1] is lower, greater, or the same as
            x[0].
        r   blackr  Nr   r\   -+z{}{})rh   r  r   COLOR_SUCCESS_1COLOR_ERROR_1r  r  )r   r   diff_strcolor
differencesigns         r;   color_stringzProfilerDataTree.color_stringD  s     q66Q;;4,81!J P",q.. !. =sCC%2%@#$F t "==t/B/B:/N/NOO##AaD))He+<==r:   c                     fd| j         D             }t          | j        t          t	          | dd                    S )a    Formats the data.

        self.stats1 contains a list of one or two pstat.Stats() instances, with
        the first being the current run and the second, the saved run, if it
        exists.  Each Stats instance is a dictionary mapping a function to
        5 data points - cumulative calls, number of calls, total time,
        cumulative time, and callers.

        format_output() converts the number of calls, total time, and
        cumulative time to a string format for the child_key parameter.
        c           
      P    g | ]"}|j                             d d d d i g          #S )r   )r  get)r  r   	child_keys     r;   r  z2ProfilerDataTree.format_output.<locals>.<listcomp>h  s4    NNNQI1aB'788NNNr:   r\   r  )r  r  r  r   zip)r   r  r   s    ` r;   format_outputzProfilerDataTree.format_output\  sD     ONNN$+NNND%vc4j!Q'?'?@@Ar:   c           	      $	   |D ]}| xj         dz  c_         |                     |          \  }}}}}|                     |          \  \  }	}
\  }}\  }}t          |          }| j                            |           |                     |||           |                    dt          d                     |	                    dt          j        |           |                    d| j        |                    |                    dt          d                     |	                    dt          j        |           |                    dt          j                   |	                    dt          j        |d                    |                    dt#          |d                              |                    dt          j                   |                    dt          d                     |	                    dt          j        |           |                    dt          j                   |	                    dt          j        |d                    |                    dt#          |d                              |                    dt          j                   |                    d	t          d
                     |	                    d	t          j        |	           |                    d	t          j                   |	                    dt          j        |
d                    |                    dt#          |
d                              |                    dt          j                   |                    dt          d                     |	                    dt          j        |           |                     |          rG|	                    dt          j        dt          d          z             |                    d           nj|                     |          }| j         dk     r|                     ||           n3|r1|                    |j                   || j        t5          |          <   | xj         dz  c_         dS )za
        Recursive method to create each item (and associated data)
        in the tree.
        r\   r   zFunction or module namez*Time in function (including sub-functions)r  rl  z-Local time in function (not in sub-functions)r     z+Total number of calls (including recursion)r     z#File:line where function is definedz(%s)	recursionTN)r  r  r  rh  r  rI  r  
setToolTipr   setDatar
   DisplayRoler   r  setTextAlignment
AlignRightsetForegroundr   	AlignLeftis_recursiver   r  r  setChildIndicatorPolicyShowIndicatorr  id)r   
parentItemchildren_listr  r   r  r  r  r  total_callstotal_calls_difloc_timeloc_time_difcum_timecum_time_dif
child_itemcalleess                    r;   r  zProfilerDataTree.populate_treek  s`   
 ' <	! <	!IOOq OO##I..X{M=) *.););I)F)F'+k?-Eh%h'
33JN!!*---z8[AAA !!!Q'@%A%ABBBq".-@@@q$.";<<<!!!Q (C &D &D E E Eq".(;;;''2=999q".,q/BBB$$Q|A(?(?@@@''2<888!!!Q (@ &A &A B B B q".(;;;''2=999q".,q/BBB$$Q|A(?(?@@@''2<888!!!Q (? &@ &@ A A A q".+>>>''2=999q"./!2DEEE$$Qq/A(B(BCCC''2<888!!!Q (C &D &D E E Eq".-@@@  ,, 	E""1bnfq~~6MNNN&&t,,,,++I66?Q&&&&z7;;;; E66z7OPPP=DD*2j>>:OOq OOOy<	! <	!r:   c                 n    |                      |          \  }}| j                            ||d           d S )Nr   )r  r   r  r  s       r;   r  zProfilerDataTree.item_activated  s;     $ 2 24 8 8+$))(KDDDDDr:   c                     |                                 dk    rHt          |          | j        v r4| j        t          |                   }|                     ||           d S d S d S )Nr   )
childCountr  r  r  )r   r   r  s      r;   r  zProfilerDataTree.item_expanded  sg    ??!!bhh$2H&H&H,RXX6GtW----- "!&H&Hr:   c                 j   |                                 }|r|                    dt          j                  |                    dt          j                  k    rD|                    dt          j                  |                    dt          j                  k    rdS |                                 }|dS )z5Returns True is a function is a descendant of itself.r   r  TF)r   r   r
   r  )r   r  ancestors      r;   r  zProfilerDataTree.is_recursive  s    $$&& 	-2> " "%-]]1bn%E%EF F2> " "%-]]1bn%E%EF Ft#??,,  	- ur:   c                 ^      fdt                                                     D             S )zIterate over top level itemsc                 :    g | ]}                     |          S r9   )topLevelItem)r  _ir   s     r;   r  z8ProfilerDataTree.get_top_level_items.<locals>.<listcomp>  s7     ; ; ; !!"%% ; ; ;r:   )r  topLevelItemCountr   s   `r;   get_top_level_itemsz$ProfilerDataTree.get_top_level_items  sB    ; ; ; ; 6 6 8 899; ; ; 	;r:   c                     g dfd	|                                  D ]*}                    |           |dk    r ||           +S )z+Return all items with a level <= `maxlevel`r\   c                     |dz  }t          |                                           D ]?}|                     |          }                    |           ||k    r |||           @d S r   )r  r  childrI  )r   maxlevellevelr  citemadd_to_itemlistitemlists        r;   r  z3ProfilerDataTree.get_items.<locals>.add_to_itemlist  sz    QJEt0011 < <

5))&&&H$$#OE8U;;;	< <r:   r   r  )r\   )r
  rI  )r   r  tlitemr  r  s      @@r;   	get_itemszProfilerDataTree.get_items  s    	< 	< 	< 	< 	< 	< 	< ..00 	; 	;FOOF###!||::::r:   c                     | xj         |z  c_         | j         dk     rd| _         |                                  | j         dk    r6|                     | j         dz
            D ]}|                    d           dS dS )zAChange view depth by expanding or collapsing all same-level nodesr   r\   r  TN)r  collapseAllr  setExpanded)r   change_in_depthr   s      r;   r   zProfilerDataTree.change_view  s    ?2"Q&&&'D#"Q&&0G!0KLL ' '  &&&& '&' 'r:   r   )!r.   r/   r0   r_  r  r   ra  rb  r   rx   r  r  r  rY  r   r   r   r  r  rZ  r  staticmethodr  r  r  r  r  r  r  r
  r  r   re  rf  s   @r;   r   r     s        " C %fS#s336 6 6 6 6 6<O O O. . .
$ $ $) ) )6% % %* * *0 0 0
  1 1 1     N N N&   \>> > >0B B BA! A! A!FE E E. . .
  ; ; ;
  $' ' ' ' ' ' 'r:   r   c                 <   | dk    rdgS | dk     rg S t          t          d| dz   d                    }| dz  }| dz   dz  dz
  }d}d}||k    rA||         r&||z  dz
  dz  }d||<   ||k     rd||<   ||z  }||k     |dz   }d|z  dz   }||k    Adgd |D             z   S )ze
    Simple test function
    Taken from http://www.huyng.com/posts/python-performance-analysis/
    r  rl  r\   g      ?r   c                     g | ]}||S r9   r9   )r  r   s     r;   r  zprimes.<locals>.<listcomp>  s    $$$!$!$$$r:   )listr  )nr  mroothalfr  r  js          r;   primesr"    s    
 	Avvs
	
Q	U1a!eQ  AHEEa<!D	A	A
u**Q4 	Qq AAaDd((!Q d(( EEAI u** 3$$Q$$$$$r:   c                  0   ddl m}  ddl}ddl}ddlm} |                    t                    }|                    d          \  }}t          j
        |d          5 }|                    d           |                    |d	z              |                    d
           ddd           n# 1 swxY w Y    |            }d|_         | d          }	t          d|          }
|
                                 |
                                 |
                    dt#                      d           |
                    dd           |
                                 |
                    |           t+          j        |	                                           dS )zRun widget testr   )qapplicationN)	MagicMockz.py)suffixwz# -*- coding: utf-8 -*-

z

zprimes(100000)profilerr  )	test_timetest)r   r-  r.  r/  i   iX  )spyder.utils.qthelpersr$  inspecttempfileunittest.mockr%  	getsourcer"  mkstempr=  fdopenwriteCONF_SECTIONrr   _setupr   r   r   r  showr  sysexitr   )r$  r,  r-  r%  	primes_scfdscriptfplugin_mockappr   s              r;   r*  r*    s   333333NNNOOO''''''!!&))I!!!//JB	2s		 "q	2333		F"###	 !!!" " " " " " " " " " " " " " "
 )++K)K
,
#
#
#CF;777F
MMOOO
LLNNN
OOL"7"9"9.  0 0 0
MM#s
KKMMM
NN6HSYY[[s   AB,,B03B0__main__)Mr_  loggingr=  os.pathpathr   rf   r6  rm   	itertoolsr   qtpyr   qtpy.compatr   r   qtpy.QtCorer   r   r	   r
   r   
qtpy.QtGuir   qtpy.QtWidgetsr   r   r   r   r   r   spyder.api.config.decoratorsr   spyder.api.translationsr   spyder.api.widgets.main_widgetr   spyder.api.widgets.mixinsr   spyder.config.baser   r   2spyder.plugins.variableexplorer.widgets.texteditorr   spyder.py3compatr   spyder.utils.miscr   r   spyder.utils.paletter   r   rY   r    r+  r!   r"   spyder.widgets.comboboxesr#   	getLoggerr.   rA  COLOR_TEXT_1rz   r%   r=   rA   rG   rI   rM   rZ   rp   rr   rh  r   r"  r*  r9   r:   r;   <module>rT     s     				       				 



              8 8 8 8 8 8 8 8 M M M M M M M M M M M M M M      : : : : : : : : : : : : : : : : 8 7 7 7 7 7 % % % % % % ; ; ; ; ; ; 7 7 7 7 7 7 @ @ @ @ @ @ @ @ I I I I I I + + + + + + C C C C C C C C = = = = = = = = - - - - - - I I I I I I I I ; ; ; ; ; ; 
	8	$	$
  ,	& 	& 	& 	& 	& 	& 	& 	&( ( ( ( ( ( ( (                            M M M
  <l* l* l* l* l*% l* l* l*^> > > > >_ > > >$c' c' c' c' c'{$5 c' c' c'R% % %4  : zDFFFFF r:   