a
    )gh+                     @   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 g d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d/d$d%ZdS )0z=
Methods for detecting objects leading to pickling failures.
    N)ismethod
isfunctionistracebackisframeiscode   )parent	referenceatparentschildren)trace)baditems
badobjectsbadtypescodeerrorsfreevars	getmodule
globalvars
nestedcodenestedglobals	outermostreferredglobalsreferrednestedr   varnamesFc                 C   sZ   ddl m} || |}|s|s"|S ddl}ddlm} || dd}|t| v rV|S dS )zget the module of the objectr   )r   Nr   )getnameT)force)inspectr   builtinssourcer   varskeys)object	_filenamer   Zgetmodmoduler   r   name r'   [/mounts/lovelace/software/anaconda3/envs/metaDMG/lib/python3.9/site-packages/dill/detect.pyr      s    
r   c              	      s   t | r| jjpi }nt| r*| jp&i }ndS | }ddlm} z|| dd\}}W n tyr   g d }}Y n0 d|  fdd|D }|D ]:\}}z||||fkr|W   S W q ty   Y q0 qd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"   | ]\}}| v r||fV  qd S Nr'   ).0r&   objr   r'   r(   	<genexpr>3       zoutermost.<locals>.<genexpr>)	r   __func____globals__r   itemsr    r)   	Exceptionjoin)funcZ_globalsr)   lineslnumZ_localsr&   r-   r'   r.   r(   r       s$    
r   Tc                 C   sf   t | } t| sg S t }| jD ]<}|du r.q t |}|r || |r |tt|ddO }q t|S )zAget the code objects for any nested functions (e.g. in a closure)NTrecurse)r   r   set	co_constsaddr   list)r6   r:   nestedcor'   r'   r(   r   <   s    


r   c                 C   sH   t | r| j} t| r| j} t| r*| j} t| r8| j} t| rD| 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
    N)	r   r1   r   __code__r   tb_framer   f_coder   r6   r'   r'   r(   r   I   s    r   c                 C   s   ddl }t }t| |D ]}||D ]}t|dd}t|dd|u rR|| q&t|dd|u rn|| q&t|dd|u r|| q&t|dr&||u r&|| q&q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.
    r   Nr1   rA   rC   co_code)gcr;   r   Zget_referrersgetattrr=   hasattrr>   )r6   r:   rF   funcsr@   r-   _r'   r'   r(   r   V   s     r   c                    sF   t rjtr*jpd jjni S  fdd}t| S )zgget objects defined in enclosing code that are referred to by func

    returns a dict of {name:object}r'   c               	   3   sF   t  D ]6\} }z
|j}W n ty2   Y q
Y n0 | |jfV  q
d S r+   )zipcell_contents
ValueError)r&   crL   Zclosuresr6   r'   r(   get_cell_contents   s    

z#freevars.<locals>.get_cell_contents)r   r1   r   __closure__rA   co_freevarsdict)r6   rP   r'   rO   r(   r   u   s    

r   c           
   	   C   s  t | } | du rt S ddl}ddlm} |jdk}t }|d2}zt|  W n tyd   Y n0 W d   n1 sz0    Y  |	 
 D ]N}d|v r|dd	 d
d }|r||dddd q|| qt| dt D ]&}	|	r|rt|	r|t|	dd qt|S )z.get the names of any globals found within funcNr   r   )capturei stdoutZ_GLOBAL()zNULL + r*   z + NULLr<   Tr9   )r   r>   systemprT   
hexversionr;   dis
IndexErrorgetvalue
splitlinessplitr=   replacerG   tupler   updater   )
r6   r:   rY   rT   ZCAN_NULLnamesoutliner&   r@   r'   r'   r(   r      s*    

$r   c                 C   s   t | || S )z@get the names of objects in the global scope referred to by func)r   r"   )r6   r:   builtinr'   r'   r(   r      s    r   c           	   	      s  t | r| j} t| r|r*ttt ni  | t  }} |jpBi D ]F}z
|j	}W n t
yd   Y qD0 t|||pti }| |  | qD |jpi  |s| |jj nD| t|j |  D ]*} |}||u rq| t|d| qnt| rv|rttt ni  |s(| j} nL| j}tt| } |  D ]0}||u rTqB |}| t|d| qBn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}Tc                 3   s"   | ]}| v r| | fV  qd S r+   r'   )r,   r&   Zglobsr'   r(   r/      r0   zglobalvars.<locals>.<genexpr>)r   r1   r   r!   r   sumcopyr;   rQ   rL   rM   r   rc   r2   rA   co_namesr   getr   co_namerS   )	r6   r:   rg   Z	orig_funcr-   rL   Z_varskeyZnested_funcr'   rh   r(   r      sD    





r   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_cellvarsrD   r'   r'   r(   r      s    r   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 ur|qS r+   r'   r,   jr'   r'   r(   
<listcomp>   r0   zbaditems.<locals>.<listcomp>r   valuesNc              	      s(   g | ] }| vr  t|d qS )r   )appendr   )r,   i_objexactsafer'   r(   rt      r0   c                 S   s   g | ]}|d ur|qS r+   r'   rr   r'   r'   r(   rt      r0   )rH   r   rG   ru   )r-   rz   r{   r'   rx   r(   r      s    
r   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)rG   r   r,   attrdepthrz   r-   r}   r{   r'   r(   r/      s   zbadobjects.<locals>.<genexpr>)dillr}   rS   dirr-   r   rz   r{   r'   r   r(   r      s    r   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   r|   Nc                 3   s<   | ]4}t |s|tt | d  fV  qdS r~   )rG   r   r   r   r'   r(   r/      s   zbadtypes.<locals>.<genexpr>)r   r}   typerS   r   r   r'   r   r(   r      s    r   c              	   C   s  ddl m}m} |szR|| }|r:|| ks:J d|| f t|t| ksbJ dt|t| f W dS  ty   ddl}| d  Y S 0 i }t| D ]d}	zt| |	}
W n. ty   ddl}| d ||	< Y qY n0 ||
||st	|
|d ||||	< q|S )z*get errors for objects that fail to pickler   )r}   rj   z$Unpickling produces %s instead of %sNr   )
r   r}   rj   r   r4   rY   exc_infor   rG   r   )r-   r   rz   r{   r}   rj   ZpikrY   _dictr   Z_attrr'   r'   r(   r     s4    


r   )NF)T)T)T)TF)TF)FF)r   FF)r   FF)r   FF)__doc__r\   r   r   r   r   r   r   Zpointersr   r	   r
   r   r   loggerr   __all__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r'   r'   r(   <module>   s&   






5



	
	