U
    祡ca#                     @   sr  d dl mZmZmZmZmZmZm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 eedd	d
Zd+eeee dddZee edddZee ee eeee f dddZee ee dddZd,ee ee eeee dddZd-eeee dddZeeee d d!d"Zeed#d$d%Z ee ee dd&d'Z!dd(d)d*Z"dS ).    )AnyCallableDictListOptionalSetTupleN)summary)compat)isframestack	getsizeof)_Py_TPFLAGS_HAVE_GC)objreturnc                 C   s&   z
t | W S  tk
r    Y dS X d S )NT)r   ReferenceError)r    r   1/tmp/pip-unpacked-wheel-8ad_c8mj/pympler/muppy.pyignore_object   s    
r   TF)remove_dupsinclude_framesr   c                 C   s   t   t  }dd |D }g }|D ]*}t|}|D ]}t |s6|| q6q&|| | rht|}|rt dd D ]}||d  qz|S )a9  Return a list of all known objects excluding frame objects.

    If (outer) frame objects shall be included, pass `include_frames=True`.  In
    order to prevent building reference cycles, the current frame object (of
    the caller of get_objects) is ignored. This will not prevent creating
    reference cycles if the object list is passed up the call-stack. Therefore,
    frame objects are not included by default.

    Keyword arguments:
    remove_dups -- if True, all duplicate objects will be removed.
    include_frames -- if True, includes frame objects.
    c                 S   s   g | ]}t |s|qS r   )r   .0or   r   r   
<listcomp>*   s      zget_objects.<locals>.<listcomp>   Nr   )	gcZcollectget_objectsget_referentsZ
is_trackedappendextend_remove_duplicatesr   )r   r   tmpresr   refsrefZsfr   r   r   r      s     

r   objectsr   c              	   C   sT   d}| D ]F}z|t |7 }W q tk
rL   tdtt|t|f  Y qX q|S )z2Compute the total size of all elements in objects.r   zIGNORING: type=%s; o=%s)r   AttributeErrorprintstrtype)r(   r$   r   r   r   r   get_size@   s    $r-   )leftrightr   c                 C   s   g g d}t t ttt t f ddd}t t ttt t f t t ddd}|| }||}||||d< || ||d	< |S )
zGet the difference of both lists.

    The result will be a dict with this form {'+': [], '-': []}.
    Items listed in '+' exist only in the right list,
    items listed in '-' exist only in the left list.

    )+-r'   c                 S   s<   i }| D ].}t |}t ||kr(g ||< || | q|S )z!Partition the passed object list.)r,   r    )r(   r$   r   tr   r   r   	partitionU   s    zget_diff.<locals>.partition)foobarr   c                 S   sL   g }| D ]>}t t||s(|| qt ||t| s|| q|S )zCompare objects from foo with objects defined in the values of
        bar (set of partitions).
        Returns a list of all objects included in list, but not dict values.
        )r
   Zobject_in_listr,   r    )r4   r5   r$   r   r   r   r   get_not_included_   s    z"get_diff.<locals>.get_not_includedr0   r1   )r   r   r   r,   )r.   r/   r$   r3   r6   Zleft_objectsZright_objectsr   r   r   get_diffK   s    
 
r7   c                 C   s   t | td} | S )zSort objects by size in bytes.)key)sortedr   )r(   r   r   r   sortw   s    r:   )r(   Typeminmaxr   c                    sn   g }krdkrt d dk	r6 fdd| D } dkrPfdd| D } dkrjfdd| D } | S )zFilter objects.

    The filter can be by type, minimum size, and/or maximum size.

    Keyword arguments:
    Type -- object type to filter by
    min -- minimum object size
    max -- maximum object size

    r;   z$minimum must be smaller than maximumNc                    s   g | ]}t | r|qS r   )
isinstancer   )r<   r   r   r      s     
 zfilter.<locals>.<listcomp>c                    s   g | ]}t | kr|qS r   r   r   )r=   r   r   r      s      c                    s   g | ]}t | k r|qS r   r   r   )r>   r   r   r      s      )
ValueError)r(   r<   r=   r>   r$   r   )r<   r>   r=   r   filter}   s    rA      )objectlevelr   c                 C   s@   t | }|d8 }|dkr4|D ]}|t|| qt|}|S )a@  Get all referents of an object up to a certain level.

    The referents will not be returned in a specific order and
    will not contain duplicate objects. Duplicate objects will be removed.

    Keyword arguments:
    level -- level of indirection to which referents considered.

    This function is recursive.

    rB   r   )r   r   r!   r"   )rC   rD   r$   r   r   r   r   r      s    
r   functionargsr   c                    s   d}t ttddd t ttd fdd}dddd	}||}||}|| f| }|| f| }t||}t|}t|d
kr|}|S )a7  Test if more memory is used after the function has been called.

    The function will be invoked twice and only the second measurement will be
    considered. Thus, memory used in initialisation (e.g. loading modules)
    will not be included in the result. The goal is to identify memory leaks
    caused by functions which use more and more memory.

    Any arguments next to the function will be passed on to the function
    on invocation.

    Note that this function is currently experimental, because it is not
    tested thoroughly and performs poorly.

    NrE   c                 W   s(   t t }| |  t t }||fS )z}Get a 2-tuple containing one summary from before, and one summary
        from after the function has been invoked.

        )r	   	summarizer   )rF   rG   s_befores_afterr   r   r   _get_summaries   s    z"_get_usage.<locals>._get_summariesc           	         s    | f| \}}g }||kr(| | |D ]F}tt|dkrL| | |D ] }tt|dkrP| | qPq,|D ]}t||}qxt||}t|S )zGet the usage of a function call.
        This function is to be used only internally. The 'real' get_usage
        function is a wrapper around _get_usage, but the workload is done
        here.

        r   )r    lenr   Zget_referrersr	   Z	_subtractr7   _sweep)	rF   rG   rI   rJ   ignorerowitemr   r$   rK   r   r   
_get_usage   s    

z_get_usage.<locals>._get_usager   c                   S   s   d S )Nr   r   r   r   r   noop   s    z_get_usage.<locals>.noopr   )r   r   r   r   r	   r7   rM   rL   )rF   rG   r$   rR   rT   offsetr#   r   rQ   r   rR      s    

rR   )r   r   c                 C   s   t tt| ddt@ S )z(Is the passed object a container object.	__flags__r   )boolgetattrr,   r   )r   r   r   r   _is_containerobject   s    rY   c                 C   s>   t  }g }| D ]*}t|}||kr$q|| || q|S )zaRemove duplicate objects.

    Inspired by http://www.peterbe.com/plog/uniqifiers-benchmark

    )setidaddr    )r(   seenresultrP   markerr   r   r   r"      s    
r"   rS   c                   C   s   t t t  dS )z%Print a summary of all known objects.N)r	   print_rH   r   r   r   r   r   print_summary  s    ra   )TF)Nr;   r;   )rB   )#typingr   r   r   r   r   r   r   r   Zpymplerr	   Zpympler.utilr
   inspectr   r   sysr   Zpympler.asizeofr   rW   r   r   intr-   r+   r7   r:   r,   rA   r   rR   rY   r"   ra   r   r   r   r   <module>   s0   $*&,   P