B
    ] cB                 @   s  d dl mZmZ d dlmZ d dlZd dlZd dlZd dl	Z	d dl
T d dl
mZmZ dd ZG dd	 d	ZG d
d dZdd ZeG dd dZeG dd deZdd ZG dd dZG dd deZdd ZG dd dZG dd deZG dd deZG d d! d!Zd"d# ZdS )$    )SequenceIterable)total_orderingN)*)_get_object_traceback_get_tracesc             C   sz   xtdD ]l}t | dk r:|dkr:|r.d| |f S d| |f S t | dk sN|dkrj|r^d| |f S d	| |f S | d
 } qW d S )N)BZKiBZMiBZGiBTiBd   r   z%+.1f %sz%.1f %si (  r	   z%+.0f %sz%.0f %si   )abs)sizeZsignZunit r   lib/python3.7/tracemalloc.py_format_size   s    
r   c               @   sD   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dS )	StatisticzS
    Statistic difference on memory allocations between two Snapshot instance.
    )	tracebackr   countc             C   s   || _ || _|| _d S )N)r   r   r   )selfr   r   r   r   r   r   __init__%   s    zStatistic.__init__c             C   s   t | j| j| jfS )N)hashr   r   r   )r   r   r   r   __hash__*   s    zStatistic.__hash__c             C   s$   | j |j ko"| j|jko"| j|jkS )N)r   r   r   )r   otherr   r   r   __eq__-   s    zStatistic.__eq__c             C   sB   d| j t| jd| jf }| jr>| j| j }|dt|d 7 }|S )Nz%s: size=%s, count=%iFz, average=%s)r   r   r   r   )r   textaverager   r   r   __str__2   s    

zStatistic.__str__c             C   s   d| j | j| jf S )Nz)<Statistic traceback=%r size=%i count=%i>)r   r   r   )r   r   r   r   __repr__<   s    zStatistic.__repr__c             C   s   | j | j| jfS )N)r   r   r   )r   r   r   r   	_sort_key@   s    zStatistic._sort_keyN)__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   r   r   r   r   r      s   
r   c               @   sD   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dS )StatisticDiffzd
    Statistic difference on memory allocations between an old and a new
    Snapshot instance.
    )r   r   	size_diffr   
count_diffc             C   s"   || _ || _|| _|| _|| _d S )N)r   r   r$   r   r%   )r   r   r   r$   r   r%   r   r   r   r   K   s
    zStatisticDiff.__init__c             C   s   t | j| j| j| j| jfS )N)r   r   r   r$   r   r%   )r   r   r   r   r   R   s    zStatisticDiff.__hash__c             C   s<   | j |j ko:| j|jko:| j|jko:| j|jko:| j|jkS )N)r   r   r$   r   r%   )r   r   r   r   r   r   V   s
    zStatisticDiff.__eq__c             C   sP   d| j t| jdt| jd| j| jf }| jrL| j| j }|dt|d 7 }|S )Nz %s: size=%s (%s), count=%i (%+i)FTz, average=%s)r   r   r   r$   r   r%   )r   r   r   r   r   r   r   ]   s    


zStatisticDiff.__str__c             C   s   d| j | j| j| j| jf S )Nz9<StatisticDiff traceback=%r size=%i (%+i) count=%i (%+i)>)r   r   r$   r   r%   )r   r   r   r   r   i   s    zStatisticDiff.__repr__c             C   s    t | j| jt | j| j| jfS )N)r   r$   r   r%   r   r   )r   r   r   r   r   n   s    zStatisticDiff._sort_keyN)r   r   r    r!   r"   r   r   r   r   r   r   r   r   r   r   r#   D   s   r#   c             C   s   g }xp|  D ]d\}}| |d }|d k	rPt||j|j|j |j|j|j }nt||j|j|j|j}|| qW x6|   D ]*\}}t|d|j d|j }|| qW |S )Nr   )itemspopr#   r   r   append)	old_group	new_group
statisticsr   statZpreviousr   r   r   _compare_grouped_statst   s    r-   c               @   s\   e Zd ZdZdZdd Zedd Zedd Zd	d
 Z	dd Z
dd Zdd Zdd ZdS )Framez
    Frame of a traceback.
    )_framec             C   s
   || _ d S )N)r/   )r   framer   r   r   r      s    zFrame.__init__c             C   s
   | j d S )Nr   )r/   )r   r   r   r   filename   s    zFrame.filenamec             C   s
   | j d S )N   )r/   )r   r   r   r   lineno   s    zFrame.linenoc             C   s   | j |j kS )N)r/   )r   r   r   r   r   r      s    zFrame.__eq__c             C   s   | j |j k S )N)r/   )r   r   r   r   r   __lt__   s    zFrame.__lt__c             C   s
   t | jS )N)r   r/   )r   r   r   r   r      s    zFrame.__hash__c             C   s   d| j | jf S )Nz%s:%s)r1   r3   )r   r   r   r   r      s    zFrame.__str__c             C   s   d| j | jf S )Nz<Frame filename=%r lineno=%r>)r1   r3   )r   r   r   r   r      s    zFrame.__repr__N)r   r   r    r!   r"   r   propertyr1   r3   r   r4   r   r   r   r   r   r   r   r.      s   r.   c               @   sf   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd ZdddZdS )	Tracebackz`
    Sequence of Frame instances sorted from the oldest frame
    to the most recent frame.
    )_framesc             C   s   t |  tt|| _d S )N)r   r   tuplereversedr7   )r   framesr   r   r   r      s    
zTraceback.__init__c             C   s
   t | jS )N)lenr7   )r   r   r   r   __len__   s    zTraceback.__len__c             C   s4   t |tr"tdd | j| D S t| j| S d S )Nc             s   s   | ]}t |V  qd S )N)r.   ).0tracer   r   r   	<genexpr>   s    z(Traceback.__getitem__.<locals>.<genexpr>)
isinstanceslicer8   r7   r.   )r   indexr   r   r   __getitem__   s    
zTraceback.__getitem__c             C   s   |j | jkS )N)r/   r7   )r   r0   r   r   r   __contains__   s    zTraceback.__contains__c             C   s
   t | jS )N)r   r7   )r   r   r   r   r      s    zTraceback.__hash__c             C   s   | j |j kS )N)r7   )r   r   r   r   r   r      s    zTraceback.__eq__c             C   s   | j |j k S )N)r7   )r   r   r   r   r   r4      s    zTraceback.__lt__c             C   s   t | d S )Nr   )str)r   r   r   r   r      s    zTraceback.__str__c             C   s   dt | f S )Nz<Traceback %r>)r8   )r   r   r   r   r      s    zTraceback.__repr__NFc             C   s   g }|d k	r2|dkr$| | d  }q6| d | }n| }|rBt |}xH|D ]@}|d|j|jf  t|j|j }|rH|d|  qHW |S )Nr   z  File "%s", line %sz    %s)r9   r(   r1   r3   	linecachegetlinestrip)r   limitZmost_recent_firstlinesZframe_slicer0   liner   r   r   format   s    
zTraceback.format)NF)r   r   r    r!   r"   r   r<   rC   rD   r   r   r4   r   r   rL   r   r   r   r   r6      s   r6   c             C   s    t | }|dk	rt|S dS dS )z
    Get the traceback where the Python object *obj* was allocated.
    Return a Traceback instance.

    Return None if the tracemalloc module is not tracing memory allocations or
    did not trace the allocation of the object.
    N)r   r6   )objr:   r   r   r   get_object_traceback   s    rN   c               @   s`   e Zd ZdZdZdd Zedd Zedd Zed	d
 Z	dd Z
dd Zdd Zdd ZdS )Tracez"
    Trace of a memory block.
    )_tracec             C   s
   || _ d S )N)rP   )r   r>   r   r   r   r      s    zTrace.__init__c             C   s
   | j d S )Nr   )rP   )r   r   r   r   domain  s    zTrace.domainc             C   s
   | j d S )Nr2   )rP   )r   r   r   r   r   	  s    z
Trace.sizec             C   s   t | jd S )N   )r6   rP   )r   r   r   r   r     s    zTrace.tracebackc             C   s   | j |j kS )N)rP   )r   r   r   r   r   r     s    zTrace.__eq__c             C   s
   t | jS )N)r   rP   )r   r   r   r   r     s    zTrace.__hash__c             C   s   d| j t| jdf S )Nz%s: %sF)r   r   r   )r   r   r   r   r     s    zTrace.__str__c             C   s   d| j t| jd| jf S )Nz'<Trace domain=%s size=%s, traceback=%r>F)rQ   r   r   r   )r   r   r   r   r     s    zTrace.__repr__N)r   r   r    r!   r"   r   r5   rQ   r   r   r   r   r   r   r   r   r   r   rO      s   rO   c               @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )_Tracesc             C   s   t |  || _d S )N)r   r   _traces)r   tracesr   r   r   r      s    
z_Traces.__init__c             C   s
   t | jS )N)r;   rT   )r   r   r   r   r<   %  s    z_Traces.__len__c             C   s4   t |tr"tdd | j| D S t| j| S d S )Nc             s   s   | ]}t |V  qd S )N)rO   )r=   r>   r   r   r   r?   *  s    z&_Traces.__getitem__.<locals>.<genexpr>)r@   rA   r8   rT   rO   )r   rB   r   r   r   rC   (  s    
z_Traces.__getitem__c             C   s   |j | jkS )N)rP   rT   )r   r>   r   r   r   rD   .  s    z_Traces.__contains__c             C   s   | j |j kS )N)rT   )r   r   r   r   r   r   1  s    z_Traces.__eq__c             C   s   dt |  S )Nz<Traces len=%s>)r;   )r   r   r   r   r   4  s    z_Traces.__repr__N)	r   r   r    r   r<   rC   rD   r   r   r   r   r   r   rS     s   rS   c             C   s&   t j| } | dr"| d d } | S )Nz.pyc)ospathnormcaseendswith)r1   r   r   r   _normalize_filename8  s    
r[   c               @   s   e Zd Zdd Zdd ZdS )
BaseFilterc             C   s
   || _ d S )N)	inclusive)r   r]   r   r   r   r   @  s    zBaseFilter.__init__c             C   s   t d S )N)NotImplementedError)r   r>   r   r   r   _matchC  s    zBaseFilter._matchN)r   r   r    r   r_   r   r   r   r   r\   ?  s   r\   c                   sJ   e Zd Zd fdd	Zedd Zdd Zd	d
 Zdd Zdd Z	  Z
S )FilterNFc                s2   t  | || _t|| _|| _|| _|| _d S )N)superr   r]   r[   _filename_patternr3   
all_framesrQ   )r   r]   filename_patternr3   rc   rQ   )	__class__r   r   r   H  s    
zFilter.__init__c             C   s   | j S )N)rb   )r   r   r   r   rd   Q  s    zFilter.filename_patternc             C   s6   t |}t|| jsdS | jd kr(dS || jkS d S )NFT)r[   fnmatchrb   r3   )r   r1   r3   r   r   r   _match_frame_implU  s    
zFilter._match_frame_implc             C   s   |  ||| j A S )N)rg   r]   )r   r1   r3   r   r   r   _match_frame^  s    zFilter._match_framec                sH    j r,t fdd|D r" jS  j S n|d \}} ||S d S )Nc             3   s   | ]\}}  ||V  qd S )N)rg   )r=   r1   r3   )r   r   r   r?   c  s   z*Filter._match_traceback.<locals>.<genexpr>r   )rc   anyr]   rh   )r   r   r1   r3   r   )r   r   _match_tracebacka  s    

zFilter._match_tracebackc             C   sD   |\}}}|  |}| jd k	r@| jr2|o0|| jkS |p>|| jkS |S )N)rj   rQ   r]   )r   r>   rQ   r   r   Zresr   r   r   r_   l  s    


zFilter._match)NFN)r   r   r    r   r5   rd   rg   rh   rj   r_   __classcell__r   r   )re   r   r`   G  s   	r`   c                   s0   e Zd Z fddZedd Zdd Z  ZS )DomainFilterc                s   t  | || _d S )N)ra   r   _domain)r   r]   rQ   )re   r   r   r   x  s    zDomainFilter.__init__c             C   s   | j S )N)rm   )r   r   r   r   rQ   |  s    zDomainFilter.domainc             C   s   |\}}}|| j k| j A S )N)rQ   r]   )r   r>   rQ   r   r   r   r   r   r_     s    
zDomainFilter._match)r   r   r    r   r5   rQ   r_   rk   r   r   )re   r   rl   w  s   rl   c               @   sX   e Zd ZdZdd Zdd Zedd Zdd	 Zd
d Z	dd Z
dddZdddZdS )SnapshotzB
    Snapshot of traces of memory blocks allocated by Python.
    c             C   s   t || _|| _d S )N)rS   rU   traceback_limit)r   rU   ro   r   r   r   r     s    
zSnapshot.__init__c          	   C   s*   t |d}t| |tj W dQ R X dS )z1
        Write the snapshot into a file.
        wbN)openpickledumpZHIGHEST_PROTOCOL)r   r1   fpr   r   r   rs     s    zSnapshot.dumpc          	   C   s    t | d}t|S Q R X dS )z.
        Load a snapshot from a file.
        rbN)rq   rr   load)r1   rt   r   r   r   rv     s    zSnapshot.loadc                s@   |rt  fdd|D sdS |r<t  fdd|D r<dS dS )Nc             3   s   | ]}|  V  qd S )N)r_   )r=   trace_filter)r>   r   r   r?     s   z)Snapshot._filter_trace.<locals>.<genexpr>Fc             3   s   | ]}|   V  qd S )N)r_   )r=   rw   )r>   r   r   r?     s   T)ri   )r   include_filtersexclude_filtersr>   r   )r>   r   _filter_trace  s    

zSnapshot._filter_tracec                s   t |tstdt|j |rng g  x(|D ] }|jrD| q. | q.W  fddjjD }njj	 }t
|jS )z
        Create a new Snapshot instance with a filtered traces sequence, filters
        is a list of Filter or DomainFilter instances.  If filters is an empty
        list, return a new Snapshot instance with a copy of the traces.
        z)filters must be a list of filters, not %sc                s   g | ]}  |r|qS r   )rz   )r=   r>   )ry   rx   r   r   r   
<listcomp>  s    z*Snapshot.filter_traces.<locals>.<listcomp>)r@   r   	TypeErrortyper   r]   r(   rU   rT   copyrn   ro   )r   filtersrw   Z
new_tracesr   )ry   rx   r   r   filter_traces  s    

zSnapshot.filter_tracesc          
   C   s  |dkrt d|f |r.|dkr.t d| i }i }|sx| jjD ]}|\}}}y|| }	W nZ tk
r   |dkr~|}
n(|dkr|d d }
n|d d dff}
t|
}	|	||< Y nX y(||	 }| j|7  _| jd7  _W qF tk
r
   t|	|d||	< Y qFX qFW nx| jjD ]}|\}}}x|D ]}y|| }	W nF tk
r   |dkrd|f}
n|d dff}
t|
}	|	||< Y nX y(||	 }| j|7  _| jd7  _W n& tk
r   t|	|d||	< Y nX q0W qW |S )	N)r   r1   r3   zunknown key_type: %r)r3   r1   z/cumulative mode cannot by used with key type %rr   r3   r2   r   )
ValueErrorrU   rT   KeyErrorr6   r   r   r   )r   key_type
cumulativeZstatsZ
tracebacksr>   rQ   r   Ztrace_tracebackr   r:   r,   r0   r   r   r   	_group_by  sX    



"zSnapshot._group_byFc             C   s,   |  ||}t| }|jdtjd |S )zd
        Group statistics by key_type. Return a sorted list of Statistic
        instances.
        T)reversekey)r   listvaluessortr   r   )r   r   r   Zgroupedr+   r   r   r   r+     s    zSnapshot.statisticsc             C   s6   |  ||}| ||}t||}|jdtjd |S )z
        Compute the differences with an old snapshot old_snapshot. Get
        statistics as a sorted list of StatisticDiff instances, grouped by
        group_by.
        T)r   r   )r   r-   r   r#   r   )r   Zold_snapshotr   r   r*   r)   r+   r   r   r   
compare_to   s
    
zSnapshot.compare_toN)F)F)r   r   r    r!   r   rs   staticmethodrv   rz   r   r   r+   r   r   r   r   r   rn     s   3

rn   c              C   s$   t  stdt } t }t| |S )zI
    Take a snapshot of traces of memory blocks allocated by Python.
    zLthe tracemalloc module must be tracing memory allocations to take a snapshot)
is_tracingRuntimeErrorr   Zget_traceback_limitrn   )rU   ro   r   r   r   take_snapshot  s
    r   )Zcollections.abcr   r   	functoolsr   rf   rF   os.pathrW   rr   Z_tracemallocr   r   r   r   r#   r-   r.   r6   rN   rO   rS   r[   r\   r`   rl   rn   r   r   r   r   r   <module>   s0   &0#?%0 	