B
    knd..                 @   s  d Z ddlZddlmZmZmZ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 dd	d
ddddddddddddgZd'ddZdd Zd(ddZdd Zd)ddZdd Zd*ddZd+d dZd,d!dZd"d Zd-d#dZd.d$d	Zd/d%d
Zd0d&dZ dS )1z=
Methods for detecting objects leading to pickling failures.
    N)ismethod
isfunctionistracebackisframeiscode   )parent	referenceatparentschildren)_trace)PY3baditems
badobjectsbadtypescodeerrorsfreevars	getmodule
globalvars
nestedcodenestedglobals	outermostreferredglobalsreferrednestedtracevarnamesFc             C   sh   ddl m} || |}|s|s"|S tr,d}nd}t|}ddlm} || dd}|t| krd|S d	S )
zget the module of the objectr   )r   builtins__builtin__r   )getnameT)forceN)inspectr   r   
__import__sourcer    varskeys)object	_filenamer!   Zgetmodmoduler   r    name r+   //tmp/pip-unpacked-wheel-8xtu9uov/dill/detect.pyr      s    
  c                s  t r<t| r| jjpi }nt| r.| jp*i }ndS | }n6t| rR| jjpNi }nt| rf| jpbi }ndS | }ddl	m
} y|| dd\}}W n   g d }}Y nX d|  fdd|D }x6|D ].\}}y||||fkr|S W q   Y qX qW dS )	zget outermost enclosing object (i.e. the outer function in a closure)

    NOTE: this is the object-equivalent of getsource(func, enclosing=True)
    Nr   )getsourcelinesT)Z	enclosing c             3   s"   | ]\}}| kr||fV  qd S )Nr+   ).0r*   obj)r   r+   r,   	<genexpr>?   s    zoutermost.<locals>.<genexpr>)r   r   __func____globals__r   itemsim_funcfunc_globals	iteritemsr$   r-   join)funcZ_globalsr-   lineslnumZ_localsr*   r0   r+   )r   r,   r   #   s6    
 
 
Tc             C   sj   t | } t| sg S t }xF| jD ]<}|dkr0q"t |}|r"|| |r"|tt|ddO }q"W t|S )zAget the code objects for any nested functions (e.g. in a closure)NT)recurse)r   r   set	co_constsaddr   list)r9   r<   nestedcor+   r+   r,   r   H   s      
 c             C   sf   t rd}d}nd}d}t| r(t| |} t| r:t| |} t| rH| j} t| rV| j} t| rb| S dS )z~get the code object for the given function or method

    NOTE: use dill.source.getsource(CODEOBJ) to get the source code
    r2   __code__r5   	func_codeN)	r   r   getattrr   r   tb_framer   f_coder   )r9   r5   rD   r+   r+   r,   r   U   s      
 
   c       	      C   s   t rd}d}nd}d}ddl}t }xt| |D ]}x||D ]}t||d}t||d|krl|| q@t||d|kr|| q@t|dd|kr|| q@t|dr@||kr@|| q@W q0W t|S )	aJ  get functions defined inside of func (e.g. inner functions in a closure)

    NOTE: results may differ if the function has been executed or not.
    If len(nestedcode(func)) > len(referrednested(func)), try calling func().
    If possible, python builds code objects, but delays building functions
    until func() is called.
    rC   r2   rD   r5   r   NrG   co_code)	r   gcr=   r   Zget_referrersrE   r?   hasattrr@   )	r9   r<   Zatt1Zatt0rI   funcsrB   r0   _r+   r+   r,   r   h   s&        c             C   sp   t rd}d}d}nd}d}d}t| r0t| |} t| rTt| |pDd}t| |j} ni S tdd	 t| |D S )
zgget objects defined in enclosing code that are referred to by func

    returns a dict of {name:object}r2   rC   __closure__r5   rD   func_closurer+   c             s   s   | ]\}}||j fV  qd S )N)cell_contents)r/   r*   cr+   r+   r,   r1      s    zfreevars.<locals>.<genexpr>)r   r   rE   r   co_freevarsdictzip)r9   r5   rD   rN   Zclosuresr+   r+   r,   r      s     
c          	   C   s   t | } | dkrt S ddlm} t }|d}t|  W dQ R X x>|  D ].}d|krT|dd dd	 }|	| qTW x8t
| d
t D ]&}|r|rt|r|t|dd qW t|S )z.get the names of any globals found within funcNr   )capturestdoutZ_GLOBAL()r   r>   T)r<   )r   r@   temprT   r=   disgetvalue
splitlinessplitr?   rE   tupler   updater   )r9   r<   rT   namesoutliner*   rB   r+   r+   r,   r      s     
c             C   s   t | || S )z@get the names of objects in the global scope referred to by func)r   r&   )r9   r<   builtinr+   r+   r,   r      s    c                s  t rd}d}d}d}nd}d}d}d}t| r8t| |} t| r |rVttt ni  | t  }} x<t||pti D ]*}t	|j
||pi }	| |	  |	 qvW  t||pi  |s| t||j nN| tt|| x|  D ],}
 |
}||krq| t	|d	| qW nt| r|r@ttt ni  |sR| j} nP| j}tt| } xB|  D ]0}
|
|krqn |
}| t	|d	| qnW ni S t fd
d| D S )zdget objects defined in global scope that are referred to by func

    return a dict of {name:object}r2   rC   r3   rM   r5   rD   r6   rN   Tc             3   s"   | ]}| kr| | fV  qd S )Nr+   )r/   r*   )globsr+   r,   r1      s    zglobalvars.<locals>.<genexpr>)r   r   rE   r   r%   r   sumcopyr=   r   rO   r_   co_namesr   getr   co_namerR   )r9   r<   rc   r5   rD   r6   rN   Z	orig_funcr0   Z_varskeyZnested_funcr+   )rd   r,   r      sP     







c             C   s    t | } t| sdS | j| jfS )ztget names of variables defined by func

    returns a tuple (local vars, local vars referrenced by nested functions)r+   )r   r   co_varnamesco_cellvars)r9   r+   r+   r,   r      s    c                sd   t | ds$dd t| dfD S t| ddr8|  n| } g   fdd| D  dd  D S )	z'get items in object that fail to pickle__iter__c             S   s   g | ]}|d k	r|qS )Nr+   )r/   jr+   r+   r,   
<listcomp>   s    zbaditems.<locals>.<listcomp>r   valuesNc          	      s(   g | ] }| kr  t|d qS )r   )appendr   )r/   i)_objexactsafer+   r,   ro     s    c             S   s   g | ]}|d k	r|qS )Nr+   )r/   rn   r+   r+   r,   ro     s    )rJ   r   rE   rp   )r0   rt   ru   r+   )rs   rt   ru   r,   r      s    
c                sF   ddl m  s$r dS S t fddtD S )zget objects that fail to pickler   )picklesNc             3   s<   | ]4}t |s|tt | d  fV  qdS )r   N)rE   r   )r/   attr)depthrt   r0   rv   ru   r+   r,   r1     s   zbadobjects.<locals>.<genexpr>)dillrv   rR   dir)r0   rx   rt   ru   r+   )rx   rt   r0   rv   ru   r,   r     s     c                sJ   ddl m  s(r dS tS t fddtD S )z)get types for objects that fail to pickler   )rv   Nc             3   s<   | ]4}t |s|tt | d  fV  qdS )r   N)rE   r   )r/   rw   )rx   rt   r0   rv   ru   r+   r,   r1     s   zbadtypes.<locals>.<genexpr>)ry   rv   typerR   rz   )r0   rx   rt   ru   r+   )rx   rt   r0   rv   ru   r,   r     s     c          	   C   s  ddl m}m} |syP|| }|r:|| ks:td|| f t|t| ksbtdt|t| f dS  tk
r   ddl}| d S X i }xpt| D ]d}	yt	| |	}
W n. tk
r   ddl}| d ||	< wY nX ||
||st
|
|d ||||	< qW |S )z*get errors for objects that fail to pickler   )rv   rf   z$Unpickling produces %s instead of %sNr   )ry   rv   rf   AssertionErrorr{   	Exceptionsysexc_inforz   rE   r   )r0   rx   rt   ru   rv   rf   Zpikr~   _dictrw   Z_attrr+   r+   r,   r     s0    
)NF)T)T)T)TF)TF)FF)r   FF)r   FF)r   FF)!__doc__rZ   r"   r   r   r   r   r   Zpointersr   r	   r
   r   r   Z_dillr   r   r   __all__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r+   r+   r+   r,   <module>
   s,   

%

&


:



	
	