
    Je                     v   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jv                  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        yy),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
y	)
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     M/usr/lib/python3/dist-packages/spyder/plugins/profiler/widgets/main_widget.pyr%   r%   9   s*    FE HF!H
C!H%Jr:   r%   c                       e Zd ZdZy)ProfilerWidgetToolbarsinformation_toolbarN)r.   r/   r0   Informationr9   r:   r;   r=   r=   E   s    'Kr:   r=   c                       e Zd ZdZy)!ProfilerWidgetMainToolbarSectionsmain_sectionNr.   r/   r0   Mainr9   r:   r;   rA   rA   I       Dr:   rA   c                       e Zd ZdZy)(ProfilerWidgetInformationToolbarSectionsrB   NrC   r9   r:   r;   rG   rG   M   rE   r:   rG   c                       e Zd ZdZy)ProfilerWidgetMainToolbarItems
file_comboN)r.   r/   r0   	FileCombor9   r:   r;   rI   rI   Q   s    Ir:   rI   c                       e Zd ZdZdZdZy)%ProfilerWidgetInformationToolbarItemsstretcher_1stretcher_2
date_labelN)r.   r/   r0   
Stretcher1
Stretcher2	DateLabelr9   r:   r;   rM   rM   U   s    JJIr:   rM   c                  2    ddl m}   | d      xr  | d      S )Nr   is_module_installedcProfilepstats)spyder.utils.programsrV   rU   s    r;   is_profiler_installedrZ   ]   s    9z*L/B8/LLr:   c                    d}t        j                  ||       }t        |      dk(  ryd}|D ]Z  }t        |d         }|d   dk(  r|dz  }n7|d   dk(  r|d	z  }n)|d   d
k(  r|dz  }n|d   dk(  r|dz  }n|d   dk(  r|dz  }||z  }\ |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jj$'G
7|qD CFmq6T>4KCVz!4KCVt^4KCVu_2IC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.resultsc                 h   t         |   |||       | j                  dt               d | _        d | _        d | _        d | _        d | _        d| _	        | j                  d      | _        d | _        t        | t        j                        | _        t#        |       | _        t'               | _        t*        j,                  | j(                  _        t1               }|j3                  | j$                         | j5                  |       | j$                  j6                  j9                  | j6                         y )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  --5 .4>>@(.AK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           	           j                  t        j                  t        d      t        d       j	                  d       j
                         _         j                  t        j                  dt        d       j	                  d       fd      } j                  t        j                  t        d      t        d	       j	                  d
       j                         _
         j                  t        j                  t        d      t        d       j	                  d      d% fd	       _         j                  t        j                  t        d      t        d       j	                  d      d% fd	       _         j                  t        j                  t        d      t        d       j	                  d       j                          _         j                  t        j$                  t        d      t        d       j	                  d       j&                         _         j                  t        j*                  t        d      t        d       j	                  d       j,                         _         j.                  j1                  d        j"                  j1                  d        j3                         } j4                  | j                  fD ]$  } j7                  ||t8        j:                         &  j=                  t>        j@                        } j                   j                   jC                  tD        jF                         jH                   jC                  tD        jJ                         j                   j"                   j(                   j.                  f	D ]$  } j7                  ||tL        j:                         & tO               st jP                   j4                   j                  fD ]  }|jS                  d        d}t        d       d!|d"t        d#      d$} jH                  jU                  |       y y )&NzRun profilerrun)rj   tipicon	triggered Select Python filefileopenc                 $    j                         S r   )select_filexr   s    r;   <lambda>z&ProfilerWidget.setup.<locals>.<lambda>   s     0 0 2 r:   OutputzShow program's outputlogr3   zCollapse one level upcollapsec                 :    j                   j                  d      S )Nr   change_viewr   s    r;   r   z&ProfilerWidget.setup.<locals>.<lambda>   s    T]]%>%>r%B r:   r4   zExpand one level downexpandc                 :    j                   j                  d      S Nr\   r   r   s    r;   r   z&ProfilerWidget.setup.<locals>.<lambda>   s    T]]%>%>q%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    ..!%%>".!!!%(hh / 
 **!((&'!!*-2 + 
 ,,!,,8)*!!%(mm - 
  $11!**:)*!!*-B  2  
 "//!((8)*!!(+A 0 
  --!**;'(!!*-nn . 
  --!**;67!!,/ll . 
 !..!''%&$%!!,/jj / 
 	$$U+##E* '')^^]D4E4EF 	D$$9>> % 	 !//"..0))4+=+=**BMM + O^^**BMM + O__%%t'7'79J9JL 	D $$)@EE % 	 %&  ==$..,,. )""4() CC-./?-@#-./L-MODNN""4( 'r:   c                    | j                   r| j                  d      }n| j                  d      }| j                  j                  |       | j                  j                  | j                           | j                  j                  | j                           | j                  j                  t        | j                  j                                      y )Nstopr   )
r   r   r   setIconr   r   r'   boolr   currentText)r   r   s     r;   update_actionszProfilerWidget.update_actions'  s    <<##F+D##E*D!!$'##$45$$%56$$T$..*D*D*F%GHr:   c                     | j                   `| j                   j                         t        j                  k(  r5| j                   j	                          | j                   j                  d       | j                          y)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  sU    <<#||!!#x'7'77""$,,T2r:   c                    d| _         | j                          | j                  | j                  z   | _        | j                  j                  d       | j                  d       | j                  j                  d       | j                          y)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=  sm     ''$++5r"D)##D)r:   c                 6   |r*| j                   j                  t        j                         n)| j                   j                  t        j                         t               }| j                   j                         rX|r|| j                   j                         z  }n|| j                   j                         z  }| j                   j                         rXt        |j                         d      }|r| xj                  |z  c_        y| xj                  |z  c_        y)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     LL''(>(>?LL''(?(?@lll))+t||88::t||99;;	 ll))+ chhj7;%KK4Kr:   pythonpath_managerspyder_pythonpath)r   optionc                     || _         y r   )r}   )r   values     r;   _update_pythonpathz!ProfilerWidget._update_pythonpathk  s	    r:   c                     t        d      }t        | |t               t        d      dz         \  }}t        j                  |      d   j                         }|s|dz   }|r| j                  j                  |       yy)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	 
* LL*1-335	  )+HMM##H- r:   c                 (   t        | t        d      t               t        d      dz         \  }}|rb| j                  j	                  |       | j                          | j                  j                  d       | j                  j                  d       yy)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	 
* MM!!(+NN''-((.	 r:   c                     | j                   j                  d       | j                   j                  d       | j                          | j                  j                  d       y)zClear data in tree.NTF)r   r   hide_diff_colsr   r'   r   r   s    r;   r   zProfilerWidget.clear  sD    d#$$T*$$U+r:   c                    t               sy| j                          | j                  }t        |j	                               D cg c]  }|j                  |       }}d}|V||vrR| j                  j                  |       | j                  j                  | j                  j	                         dz
         n4| j                  j                  | j                  j                  |             | j                  j                          | j                  j                         r*|t        j                  |      }| j                  ||       yyc c}w )
        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.
        Nr\   )rZ   r   r   rangecountitemTextaddItemsetCurrentIndexfindTextselectedis_validr   dirnamestart)r   r   wdirargscomboidxitemsindexs           r;   analyzezProfilerWidget.analyze  s     %& 05ekkm0DE$EE=XU2NN""8,NN**4>>+?+?+AA+EFNN**4>>+B+B8+LM!>>""$|{{8,JJtT"	 % Fs   E
c                     |d| j                   j                  d       t        | t        d      t	               t        d      dz         \  }}| j                   j                  d       |r| j                  |       yy)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  sw     --2259#2&' .!$55	$ Hj --2248LL" r:   c                     | j                   rEt        | j                   t        d      d|       }|j                  dd       |j	                          yy)zShow process output log.Profiler outputTr   readonlyr       N)r   r   r   resizeexec_r   output_dialogs     r;   r   zProfilerWidget.show_log  sL    ;;&)*	M   c*! r:   c                     | j                   rEt        | j                   t        d      d|       }|j                  dd       |j	                          yy)zShow process error log.r  Tr  r  r  N)r~   r   r   r  r  r  s     r;   r   zProfilerWidget.show_errorlog  sP    &!!)*	M   c*! r:   c                 N    t         j                  j                               }|# j                  }|t	        j
                  |      }| j                  }|g }| _        | _         j                  j                  t        d             t                _         j                  j                  t        j                          j                  j                  |        j                  j                  j!                   j"                          j                  j$                  j!                   fd        j                  j&                  j!                  t        j(                  f fd	        j                  j&                  j!                   j*                         t-               }t.        j0                  j3                         D ]  \  }}|j5                  ||        |j5                  dd       |j7                  d       |j7                  d        j8                  \t:        j=                  d	 j8                   d
       |j5                  dt.        j>                  jA                   j8                                j                  jC                  |        jE                  dd      }tG        |      sF j                  jI                         }|j7                  d        j                  jC                  |       d _%        d _&        d _'         jQ                          ddd jR                  g}	t.        jT                  dk(  rC|	jW                  t	        jX                  |      j[                  t.        j\                  d             n|	jW                  |       |r|	j_                  ta        |              j                  jc                  ||	        j                  je                         }
|
s)tg        jh                   t        d      t        d              jk                          y)r  NzProfiling, please wait...c                  (     j                  d      S )NT)r   )r   r   s   r;   r   z&ProfilerWidget.start.<locals>.<lambda>  s    D%%D%1 r:   c                 (    j                  | |      S r   )r   )ecesr   s     r;   r   z&ProfilerWidget.start.<locals>.<lambda>  s    t~~b"/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+DE((.,,44T5F5FG++331	3%%"--E	G%%d&7&78 '(JJ$$& 	"DAqOOAq!	"*F3%*+??&LL+DOO+<KHIOOL"**//$//*JK**84]]<9K]L
!*-,,113CJJ|$LL..s3
D$--877d? MM#,,x088EFMM(#MM+d+,:v.,,--/  '
+,
 	r:   c                     d| _         | j                  j                          | j                  j                  d       | j	                          | j                          y)zStop the running process.Fr   N)r   r   r   r   r9  r   r   s    r;   r   zProfilerWidget.stop@  sC    $$T*r:   c                 ^    | j                   r| j                          y| j                          y)z1Toggle starting or running the profiling process.N)r   r   r  r   s    r;   r   zProfilerWidget.runH  s    <<IIKJJLr:   c                    |sd| _         | j                  j                  | j                   duxr t        | j                         dkD         | j	                          t        | j                  j                               }|sy| j                  j                  t        d             t        j                          | j                  j                  | j                         | j                  j!                          d}|| j"                  t%        j&                  dt%        j(                               fz  }| j                  j                  |       y)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_datarE  	show_treert   rm   strftime	localtime)r   r   r   
text_style	date_texts        r;   r   zProfilerWidget.show_dataO  s     DK""4;;d#: $<'*4;;'7!';	=!$.."<"<">?q!?@A""$.!B
$//"&--0C040@#B"C C	 	y)r:   )NNN)F)NNr   )#r.   r/   r0   __doc__ENABLE_SPINNERr   rE  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/0H %S#s3 (KM8LN*@a)F	I& 6 09LM  N 
.$/, #D#4
"
"Qf*r:   rr   c                       e Zd ZddZd Zy)TreeWidgetItemNc                 0    t        j                  | |       y r   )r   rx   r   r   s     r;   rx   zTreeWidgetItem.__init__p  s      v.r:   c                    | j                         j                         }	 |dk(  s|dk(  r=t        | j                  |            }t        |j                  |            }||||kD  S t	        | j                  |            t	        |j                  |            kD  S # t
        $ r& | j                  |      |j                  |      kD  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ktyy01y~~f56>bn7N6*+eINN64J.KKK 	>99V$y~~f'===	>s   AB '4B ,C
Cr   )r.   r/   r0   rx   rq  r9   r:   r;   re  re  o  s    />r:   re  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<[=]>c           
      p   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| _        | j                  d      | j                  d	      | j                  d      | j                  d
      d| _        d | _	        d | _
        g | _        d | _        d | _        d | _        d | _        d | _        | j#                  t%        | j                               | j'                  | j                         | j)                          | j*                  j-                  | j.                         | j0                  j-                  | j2                         y )N)class_parentzFunction/Modulez
Total TimeDiffz
Local TimeCallsz	File:linepythonfunctionclass)modulerx  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__  sd   GV&9  v.&&t&A/0!L/1V9lOQvY'
AfIkN, &&x0((4''1++G4	
 
!%"& C 0 012T--.""4#6#67!!$"4"45r:   c                 <    t        |d|| j                  |fz         y)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Xtxx,M!MNr:   c                 j    t        |      j                  | j                        \  }}|t        |      fS )z0Get tree item user data: (filename, line_number))r!   splitr  r_  )r   r   r   line_number_strs       r;   get_item_datazProfilerDataTree.get_item_data  s0    $6t$<$B$B488$L!/_---r:   c                 \    | j                          d| _        g | _        i | _        d| _        y)z"Clean the tree and view parametersr   N)r   r  r  r  r  r   s    r;   r  z ProfilerDataTree.initialize_view  s)    

!#"#r:   c                 &   ddl }	 |j                  |      g}|d   | _        | j
                  +	 |j                  |j                  | j
                               t        d |       | j                  j                          || _        |d   j                  | _        y# t        t        f$ r
 d| _        Y yw xY w# t        t        f$ rI}t        j                  | t        d      t        d      j                  |             d| _        Y d}~d}~ww xY w)z3Load profiler data saved by profile/cProfile moduler   Nr0  zMError when trying to load profiler results. The error was<br><br><tt>{0}</tt>c                 "    | j                         S r   )calc_callees)r   s    r;   r   z,ProfilerDataTree.load_data.<locals>.<lambda>  s    ann& r:   )rX   StatsOSErrorIOErrorr  r  rF  r   rL  r   formatmapr  r  r  )r   profdatafilerX   
stats_indies        r;   rV  zProfilerDataTree.load_data  s    	 ,,|47J #1()!!&,,t/@/@"AB 	&
3""$ ]((
' ! 	 DM	 W% )$$!G* % &&,fQi	1
 %)!!)s(   B *B8 B54B58D?DDc                 4    | j                  d       || _        y )NF)r   r  r   r   s     r;   r   zProfilerDataTree.compare  s    E"$r:   c                 6    dD ]  }| j                  ||        y )N)         )setColumnHidden)r   hideis      r;   r   zProfilerDataTree.hide_diff_cols  s!     	*A  D)	*r:   c                 r    t        | j                        dkD  r| j                  d   j                  |       yy)zSave profiler data.r   N)rh   r  
dump_statsr  s     r;   r   zProfilerDataTree.save_data  s.    t{{aKKN%%h/  r:   c                     | j                   | j                   j                  d       ny| j                   j                  D ]#  }d|dd k7  s|d   j                  d      r!|c S  y)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  se     ==$MM$$\2MM** 	D4!9$T!W-?-?,.. 	r:   c                 4    | j                   j                  |   S )z/Find all functions called by (parent) function.)r  all_calleesrg  s     r;   find_calleeszProfilerDataTree.find_callees  s     }}((00r:   c                 v   | j                          | j                  d       | j                  d       | j                         }|u| j	                  | | j                  |             | j                  d       | j                  d       | j                  dt        j                         | j                  d       yy)z4Populate the tree with profiler data and display it.TFNr   r\   )r  setItemsExpandablesetSortingEnabledr  populate_treer  resizeColumnToContents	sortItemsr
   AscendingOrderr   )r   rootkeys     r;   rW  zProfilerDataTree.show_tree  s    %u%.."tT%6%6w%?@''*""4(NN1b//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.rx  z<module>rz  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&%(YYx%8"J
 I]*),:)>&
J*,s2M8s?(M!I
*)	%;(??Mm]IMMr:   c                    t        |       } t        | t              rt        |       S d| cxk  rdk  rn ndj	                  | dz        } | S d| cxk  rdk  rn ndj	                  | dz        } | S d| cxk  rdk  rn ndj	                  | dz        } | S d| cxk  rdk  rn nd	j	                  |       } | S d| cxk  rd
k  rWn nTt        | d
      \  }}|dkD  r,t        | d      \  }}t        |      j                  d      d   }dj	                  ||      } | S t        | d
      \  }}|dkD  r|dz  }dj	                  ||      } | 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
isinstancer_  r   r  divmodr  )measuremsrd   s       r;   format_measurezProfilerDataTree.format_measure$  sj    g, gs#!'** 7#e##**7U?;G$ # W%%(//%@G   W!!#**7U?;G  B"))'2G  '!T!'4(DAq2vgr*1"1%++C04,33Aq9G 	 '4(DAq2vR,33Aq9Gr:   c                 "   d}d}t        |      dk(  rf| j                  Z|d   |d   z
  }|rM|dk  rt        j                  dfnt        j                  df\  }}dj                  || j                  |            }| j                  |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  r   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     q6Q;4,,81!J",q. !. = =sC%2%@%@#$F t "==t/B/B:/NO##AaD)He+<==r:   c                     | j                   D cg c]#  }|j                  j                  |ddddi g      % }}t        | j                  t        t        | dd            S c c}w )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.
        r   r\   r  )r  r  getr  r  r   zip)r   	child_keyr   r   s       r;   format_outputzProfilerDataTree.format_output\  s]     CG++NQI1aB'78NND%%vc4j!Q'?@A Os   (A c           	      X   |D ]$  }| xj                   dz  c_         | j                  |      \  }}}}}| j                  |      \  \  }	}
\  }}\  }}t        |      }| j                  j                  |       | j                  |||       |j                  dt        d             |j                  dt        j                  |       |j                  d| j                  |          |j                  dt        d             |j                  dt        j                  |       |j                  dt        j                         |j                  dt        j                  |d          |j!                  dt#        |d                |j                  dt        j$                         |j                  dt        d             |j                  dt        j                  |       |j                  dt        j                         |j                  dt        j                  |d          |j!                  dt#        |d                |j                  dt        j$                         |j                  d	t        d
             |j                  d	t        j                  |	       |j                  d	t        j                         |j                  dt        j                  |
d          |j!                  dt#        |
d                |j                  dt        j$                         |j                  dt        d             |j                  dt        j                  |       | j'                  |      r?|j                  dt        j                  dt        d      z         |j)                  d       nh| j+                  |      }| j                   dk  r| j-                  ||       n5|r3|j/                  |j0                         || j2                  t5        |      <   | xj                   dz  c_         ' y)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  ri  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  re  r  rF  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  sh   
 ' <	!IOOq O##I.X{M=) *.););I)F'+k?-Eh%h'
3JNN!!*-z8[A !!!Q'@%ABq"..-@q$..";<!!!Q (C &D Eq"..(;''2==9q"..,q/B$$Q|A(?@''2<<8!!!Q (@ &A B q"..(;''2==9q"..,q/B$$Q|A(?@''2<<8!!!Q (? &@ A q"..+>''2==9q"../!2DE$$Qq/A(BC''2<<8!!!Q (C &D Eq"..-@  ,""1bnnfq~6MN&&t,++I6??Q&&&z7;66z7O7OP=DD**2j>:OOq Oy<	!r:   c                 f    | j                  |      \  }}| j                  j                  ||d       y )Nr   )r  r   r  r  s       r;   r  zProfilerDataTree.item_activated  s/     $ 2 24 8+$$))(KDr:   c                     |j                         dk(  rCt        |      | j                  v r+| j                  t        |         }| j                  ||       y y y )Nr   )
childCountr  r  r  )r   r   r  s      r;   r  zProfilerDataTree.item_expanded  sO    ??!bh$2H2H&H,,RX6GtW- 'I!r:   c                 T   |j                         }|r|j                  dt        j                        |j                  dt        j                        k(  rB|j                  dt        j                        |j                  dt        j                        k(  ry|j                         }|ry)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>> "%-]]1bnn%EF2>> "%-]]1bnn%EF#??,  r:   c                 x    t        | j                               D cg c]  }| j                  |       c}S c c}w )zIterate over top level items)r  topLevelItemCounttopLevelItem)r   _is     r;   get_top_level_itemsz$ProfilerDataTree.get_top_level_items  s=       6 6 89; !!"% ; 	; ;s   7c                     g dfd	| j                         D ]#  }j                  |       |dkD  s ||       % S )z+Return all items with a level <= `maxlevel`c                     |dz  }t        | j                               D ]4  }| j                  |      }j                  |       ||k  s+ |||       6 y r   )r  r  childrF  )r   maxlevellevelr  citemadd_to_itemlistitemlists        r;   r  z3ProfilerDataTree.get_items.<locals>.add_to_itemlist  sU    QJEt01 <

5)&H$#E8U;	<r:   r   r	  )r\   )r  rF  )r   r	  tlitemr  r  s      @@r;   	get_itemszProfilerDataTree.get_items  sK    	< ..0 	;FOOF#!|:	; r:   c                    | xj                   |z  c_         | j                   dk  rd| _         | j                          | j                   dkD  r6| j                  | j                   dz
        D ]  }|j                  d        yy)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&0G0G!0KL '  &' 'r:   r   )!r.   r/   r0   r\  r  r   r^  r_  r   rx   r  r  r  rV  r   r   r   r  r  rW  r  staticmethodr  r  r  r  r  r  r  r  r  r   rb  rc  s   @r;   r   r     s    " C %S#s36<O.
$)6%*0
1 N&  >>0BA!FE.
;
$'r:   r   c                 6   | 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  r=||   r%||z  dz
  dz  }d||<   ||k  rd||<   ||z  }||k  r|dz   }d|z  dz   }||k  r=dg|D cg c]  }|s|	 c}z   S c c}w )ze
    Simple test function
    Taken from http://www.huyng.com/posts/python-performance-analysis/
    r  ri  r\   g      ?r   )listr  )nr  mroothalfr  r  jr   s           r;   primesr    s    
 	Avs
	
Q	U1a!eQ AHEEa<!D	A	A
u*Q4Qq AAaDd(!Q d( EEAI u* 3Q$!!$$$$s   BBc                     ddl m}  ddl}ddl}ddlm} |j                  t              }|j                  d      \  }}t        j                  |d      5 }|j                  d       |j                  |d	z          |j                  d
       ddd        |       }d|_         | d      }	t        d|      }
|
j                          |
j                          |
j!                  dt#               d       |
j%                  dd       |
j'                          |
j)                  |       t+        j,                  |	j/                                y# 1 sw Y   xY w)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'!!&)I!!!/JB	2s	 "q	23		F"#	 !"
 +K)K

#CF;7F
MMO
LLN
OOL"7"9.  0
MM#s
KKM
NN6HHSYY[#" "s   7EE__main__)Mr\  loggingr:  os.pathpathr   rf   r0  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.   r>  COLOR_TEXT_1rz   r%   r=   rA   rG   rI   rM   rZ   rp   rr   re  r   r  r$  r9   r:   r;   <module>rN     s    	  	 
    8 M M : : 8 % ; 7 @ I + C = - I ; 
		8	$
  ,,	& 	&( (    M
<l*% l*^>_ >$c'{$5 c'R%4: zF r:   