
    Yfe-                        d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZmZmZ d d
lmZ d dlmZmZ  G d d      Zed   Z G d d      Z y)    )annotationsN)Path)process_time)IOAny)	renderers)AWAIT_FRAME_IDENTIFIEROUT_OF_CONTEXT_FRAME_IDENTIFIER)Session)
AsyncStateStackSamplerbuild_call_stackget_stack_sampler)
LiteralStr)file_supports_colorfile_supports_unicodec                  0    e Zd ZU ded<   	 	 	 	 	 	 	 	 ddZy)ActiveProfilerSessionzlist[tuple[list[str], float]]frame_recordsc                <    || _         || _        || _        g | _        y N)
start_timestart_process_timestart_call_stackr   )selfr   r   r   s       U/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/pyinstrument/profiler.py__init__zActiveProfilerSession.__init__   s#     %"4 0    N)r   floatr   r   r   	list[str]returnNone)__name__
__module____qualname____annotations__r    r   r   r   r      s3    00	 	  "	  $		 
 
	 r   r   )enableddisabledstrictc                  `   e Zd ZU dZded<   ded<   ded<   ded	<   dd d
Zed!d       Zed"d       Zed#d       Z	d$d%dZ
d&dZed        Zd Zd Zd'dZ	 	 	 	 	 	 d(dZej$                  fddddd	 	 	 	 	 	 	 	 	 d)dZ	 	 	 	 d*	 	 	 	 	 	 	 	 	 d+dZd,d-dZ	 d,	 	 	 	 	 d.dZd/d0dZd1dZd&dZy)2ProfilerzB
    The profiler - this is the main way to use pyinstrument.
    Session | None_last_sessionzActiveProfilerSession | None_active_sessionr   	_interval	AsyncMode_async_modec                <    || _         d| _        d| _        || _        y)z
        Note the profiling will not start until :func:`start` is called.

        :param interval: See :attr:`interval`.
        :param async_mode: See :attr:`async_mode`.
        N)r0   r.   r/   r2   )r   interval
async_modes      r   r   zProfiler.__init__2   s#     "!#%r   c                    | j                   S )z
        The minimum time, in seconds, between each stack sample. This translates into the
        resolution of the sampling.
        )r0   r   s    r   r4   zProfiler.interval>   s     ~~r   c                    | j                   S )a  
        Configures how this Profiler tracks time in a program that uses
        async/await.

        ``enabled``
            When this profiler sees an ``await``, time is logged in the function
            that awaited, rather than observing other coroutines or the event
            loop.

        ``disabled``
            This profiler doesn't attempt to track ``await``. In a program that
            uses async/await, this will interleave other coroutines and event
            loop machinery in the profile. Use this option if async support is
            causing issues in your use case, or if you want to run multiple
            profilers at once.

        ``strict``
            Instructs the profiler to only profile the current
            `async context <https://docs.python.org/3/library/contextvars.html>`_.
            Frames that are observed in an other context are ignored, tracked
            instead as ``<out-of-context>``.
        )r2   r7   s    r   r5   zProfiler.async_modeF   s    0 r   c                    | j                   S )z@
        The previous session recorded by the Profiler.
        )r.   r7   s    r   last_sessionzProfiler.last_session`   s    
 !!!r   Nc           	     L   |t        j                         j                  }	 t        t	        j                         t               t        |dd            | _        | j                  dk7  }t               j                  | j                  | j                  |       y#  d| _         xY w)a  
        Instructs the profiler to start - to begin observing the program's execution and recording
        frames.

        The normal way to invoke ``start()`` is with a new instance, but you can restart a Profiler
        that was previously running, too. The sessions are combined.

        :param caller_frame: Set this to override the default behaviour of treating the caller of
            ``start()`` as the 'start_call_stack' - the instigator of the profile. Most
            renderers will trim the 'root' from the call stack up to this frame, to
            present a simpler output.

            You might want to set this to ``inspect.currentframe().f_back`` if you are
            writing a library that wraps pyinstrument.
        Ninitial)r   r   r   r)   )inspectcurrentframef_backr   timer   r   r/   r5   r   	subscribe_sampler_saw_call_stackr4   )r   caller_frameuse_async_contexts      r   startzProfiler.startg   s    " "//188L	#899;#/>!1,	4!P$D  !%: =)),,dmm=N	#'D s   A6B 
B#c           	        | j                   st        d      	 t               j                  | j                         t               | j                   j                  z
  }t        | j                   j                  | j                   j                  t        j                         | j                   j                  z
  t        | j                   j                        dj                  t        j                         | j                   j"                  |      }d| _         | j$                   t        j&                  | j$                  |      }|| _        |S # t
        j                  $ r t        d      w xY w)z
        Stops the profiler observing, and sets :attr:`last_session`
        to the captured session.

        :return: The captured session.
        z'This profiler is not currently running.zUFailed to stop profiling. Make sure that you start/stop profiling on the same thread. )r   r   durationsample_countprogramr   cpu_timeN)r/   RuntimeErrorr   unsubscriberB   r   SubscriberNotFoundr   r   r   r   r   r@   lenjoinsysargvr   r:   combiner.   )r   rK   sessions      r   stopzProfiler.stop   s'    ##HII	++D,H,HI  >D$8$8$K$KK..<<++66YY[4#7#7#B#BBT11??@HHSXX&!11BB
  $(ood&7&7AG$1 .. 	g 	s   #E
 
E)c                    | j                   duS )zd
        Returns `True` if this profiler is running - i.e. observing the program execution.
        N)r/   r7   s    r   
is_runningzProfiler.is_running   s    
 ##4//r   c                J    | j                   r| j                          d| _        y)zC
        Resets the Profiler, clearing the `last_session`.
        N)rW   rU   r.   r7   s    r   resetzProfiler.reset   s     ??IIK!r   c                b    | j                  t        j                         j                         | S )aE  
        Context manager support.

        Profilers can be used in `with` blocks! See this example:

        .. code-block:: python

            with Profiler() as p:
                # your code here...
                do_some_work()

            # profiling has ended. let's print the output.
            p.print()
        )rC   )rE   r=   r>   r?   r7   s    r   	__enter__zProfiler.__enter__   s&     	

 4 4 6 = =
>r   c                $    | j                          y r   )rU   )r   argss     r   __exit__zProfiler.__exit__   s    		r   c                   | j                   st        d      |rY|j                  dk(  rJ| j                  dv r<|j                  }| j                   j
                  j                  |t        gz   |f       y |rZ|j                  dk(  rK| j                  dk(  r<|j                  }| j                   j
                  j                  |t        gz   |f       y | j                   j
                  j                  ||f       y )NzReceived a call stack without an active session. Please file an issue on pyinstrument Github describing how you made this happen!out_of_context_awaited)r(   r*   out_of_context_unknownr*   )	r/   rL   stater2   infor   appendr	   r
   )r   
call_stacktime_since_last_sampleasync_stateawaiting_coroutine_stackcontext_exit_frames         r   rB   z Profiler._sampler_saw_call_stack   s     ## T 
 !!%==  $99'2'7'7$  ..55,0F/GG* !!%==  H,!,!1!1  ..55&*I)JJ*   ..55zCY6Z[r   Funicodecolorshow_alltimelinec               x    |t        |      }|t        |      }t        | j                  ||||      |       y)a  print(file=sys.stdout, *, unicode=None, color=None, show_all=False, timeline=False)

        Print the captured profile to the console.

        :param file: the IO stream to write to. Could be a file descriptor or sys.stdout, sys.stderr. Defaults to sys.stdout.
        :param unicode: Override unicode support detection.
        :param color: Override ANSI color support detection.
        :param show_all: Sets the ``show_all`` parameter on the renderer.
        :param timeline: Sets the ``timeline`` parameter on the renderer.
        Nrj   )file)r   r   printoutput_text)r   rp   rk   rl   rm   rn   s         r   rq   zProfiler.print   sN    & ?+D1G='-E!!	   	
r   c                T    | j                  t        j                  ||||            S )z\
        Return the profile output as text, as rendered by :class:`ConsoleRenderer`
        rj   renderer)outputr   ConsoleRenderer)r   rk   rl   rm   rn   s        r   rr   zProfiler.output_text  s1     {{..ux(  
 	
r   c                P    | j                  t        j                  ||            S )zY
        Return the profile output as HTML, as rendered by :class:`HTMLRenderer`
        rn   rm   rt   )rv   r   HTMLRenderer)r   rn   rm   s      r   output_htmlzProfiler.output_html/  s#     {{I$:$:HW_$`{aar   c                    t        |      }|j                  | j                  t        j                  ||            d       y)zc
        Writes the profile output as HTML to a file, as rendered by :class:`HTMLRenderer`
        ry   rt   zutf-8)encodingN)r   
write_textrv   r   rz   )r   pathrn   rm   rp   s        r   
write_htmlzProfiler.write_html5  s=     DzKK!7!7T\!]K^ 	 	
r   c                l    | j                         }t        j                  |      j                  |      S )zE
        Opens the last profile session in your web browser.
        )rn   )_get_last_session_or_failr   rz   open_in_browser)r   rn   rT   s      r   r   zProfiler.open_in_browserA  s.     002%%x8HHQQr   c                D    | j                         }|j                  |      S )z
        Returns the last profile session, as rendered by ``renderer``.

        :param renderer: The renderer to use.
        )r   render)r   ru   rT   s      r   rv   zProfiler.outputI  s!     002w''r   c                v    | j                   rt        d      | j                  t        d      | j                  S )NzBcan't render profile output because this profiler is still runningzYcan't render profile output because this profiler has not completed a profile session yet)rW   	Exceptionr:   r7   s    r   r   z"Profiler._get_last_session_or_failS  s?    ??`aa$k     r   )gMbP?r(   )r4   r   r5   r1   )r!   r   )r!   r1   )r!   r-   r   )rC   ztypes.FrameType | None)r!   r   )r]   r   )re   r    rf   r   rg   zAsyncState | None)
rp   zIO[str]rk   bool | Nonerl   r   rm   boolrn   r   )FFFF)
rk   r   rl   r   rm   r   rn   r   r!   str)FF)rn   r   rm   r   r!   r   )r   zstr | os.PathLike[str]rn   r   rm   r   )F)rn   r   )ru   zrenderers.Rendererr!   r   )r#   r$   r%   __doc__r&   r   propertyr4   r5   r:   rE   rU   rW   rY   r[   r^   rB   rQ   stdoutrq   rr   r{   r   r   rv   r   r'   r   r   r,   r,   (   s    "!11
&      2 " "!F$L 0 0"$%\%\ !&%\ '	%\R 

 
  $! 
 
 	 

  
  
  
H 

 
 	

 
 

 b V[

*

6:

NR

R(	!r   r,   )!
__future__r   r=   osrQ   r@   typespathlibr   r   typingr   r   pyinstrumentr   pyinstrument.framer	   r
   pyinstrument.sessionr   pyinstrument.stack_samplerr   r   r   r   pyinstrument.typingr   pyinstrument.utilr   r   r   r1   r,   r'   r   r   <module>r      sX    "  	 
      " V ( d d * H
    67	t! t!r   