B
    knds                 @   sf   d ddddgZ ddlZddlZddlmZ dd	lmZ ddd ZdddZ	dddZ
dddZeZdS )parent	referenceatparentschildren    N   )_proxy_helper)_locate_object c             C   s*   d}t | |||}| }|| kr&dS |S )al  
>>> listiter = iter([4,5,6,7])
>>> obj = parent(listiter, list)
>>> obj == [4,5,6,7]  # actually 'is', but don't have handle any longer
True

NOTE: objtype can be a single type (e.g. int or list) or a tuple of types.

WARNING: if obj is a sequence (e.g. list), may produce unexpected results.
Parent finds *one* parent (e.g. the last member of the sequence).
    r   N)r   pop)objobjtypeignoredepthchainr   r
   r
   1/tmp/pip-unpacked-wheel-8xtu9uov/dill/pointers.pyr      s    c                sP   t j} fdd}t|ds"|fn|}dd |D }t| |||ddd }|S )zFind the chain of referents for obj. Chain will end with obj.

    objtype: an object type or tuple of types to search for
    depth: search depth (e.g. depth=2 is 'grandparents')
    ignore: an object or tuple of objects to ignore in the search
    c                s
   t |  S )N)
isinstance)x)r   r
   r   <lambda>-       zparents.<locals>.<lambda>__len__c             s   s   | ]}t |V  qd S )N)id).0r   r
   r
   r   	<genexpr>0   s    zparents.<locals>.<genexpr>N)gcZget_referentshasattr
find_chain)r   r   r   r   	edge_func	predicater   r
   )r   r   r   %   s    c                sH   t j} fdd}t|ds"|fn|}dd |D }t| ||||}|S )a  Find the chain of referrers for obj. Chain will start with obj.

    objtype: an object type or tuple of types to search for
    depth: search depth (e.g. depth=2 is 'grandchildren')
    ignore: an object or tuple of objects to ignore in the search

    NOTE: a common thing to ignore is all globals, 'ignore=(globals(),)'

    NOTE: repeated calls may yield different results, as python stores
    the last value in the special variable '_'; thus, it is often good
    to execute something to replace '_' (e.g. >>> 1+1).
    c                s
   t |  S )N)r   )r   )r   r
   r   r   D   r   zchildren.<locals>.<lambda>r   c             s   s   | ]}t |V  qd S )N)r   )r   r   r
   r
   r   r   G   s    zchildren.<locals>.<genexpr>)r   Zget_referrersr   r   )r   r   r   r   r   r   r   r
   )r   r   r   6   s       c             C   st  | g}t | di}t | d i}t|}|t | |t | |t | |t | |t | |t t  |t td t  x|rl|d}	||	r|	g}
x*|t |	 d k	r|t |	 }	|
|	 qW |
S |t |	 }||k r||	}|t | xT|D ]L}t ||kr0qt ||kr|d |t |< |	|t |< || qW qW | gS )Nr   r   )	r   setaddsys	_getframer   Zcollectr   append)r   r   r   Z	max_depthZextra_ignorequeuer   r   r   targetr   ZtdepthZ	referrerssourcer
   r
   r   r   S   s@    

r   )r
   )r   r
   )r   r
   )r    r
   )__all__r   r#   Z_dillr   r   r	   r   r   r   r   r   Z	refobjectr
   r
   r
   r   <module>	   s   



$