U
     T‚gÏG  ã                
   @   sš  d Z ddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZ ddlmZ G dd	„ d	ƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZG dd„ dƒZeƒ Zeeeeeeedƒeeeƒg	ZG dd„ dƒZ G dd„ dƒZ!G dd„ dƒZ"G dd„ dƒZ#dd„ Z$G dd„ de%ƒZ&e 'd ¡Z(d!d"„ Z)d#d$„ Z*d%d&„ Z+d'd(„ Z,d)d*„ Z-G d+d,„ d,ƒZ.d-d.„ Z/d9d/d0„Z0d1d2„ Z1d3d4„ Z2d5d6„ Z3G d7d8„ d8ƒZ4dS ):z|
AOT: Abstract Object Trees
The source-code-marshallin'est abstract-object-serializin'est persister
this side of Marmalade!
é    N)Úcrefutil)ÚlogÚreflect)Ú_constructMethodé   )Úgenerate_tokensc                   @   s   e Zd Zdd„ ZdS )ÚNamedc                 C   s
   || _ d S ©N©Úname)Úselfr   © r   ú9/tmp/pip-unpacked-wheel-1_7di8ic/twisted/persisted/aot.pyÚ__init__"   s    zNamed.__init__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   !   s   r   c                   @   s   e Zd Zdd„ ZdS )ÚClassc                 C   s
   d| j  S )Nz	Class(%r)r
   ©r   r   r   r   Ú	getSource'   s    zClass.getSourceN©r   r   r   r   r   r   r   r   r   &   s   r   c                   @   s   e Zd Zdd„ ZdS )ÚFunctionc                 C   s
   d| j  S )NzFunction(%r)r
   r   r   r   r   r   ,   s    zFunction.getSourceNr   r   r   r   r   r   +   s   r   c                   @   s   e Zd Zdd„ ZdS )ÚModulec                 C   s
   d| j  S )Nz
Module(%r)r
   r   r   r   r   r   1   s    zModule.getSourceNr   r   r   r   r   r   0   s   r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚInstanceMethodc                 C   s@   t |tƒs*t |tƒs*t |tƒs*td| ƒ‚|| _|| _|| _d S )Nz$%s isn't an Instance, Ref, or Deref!)Ú
isinstanceÚRefÚInstanceÚDerefÚ	TypeErrorr   ÚklassÚinstance)r   r   r   Úinstr   r   r   r   6   s    ÿþýzInstanceMethod.__init__c                 C   s   d  | j| jt| jƒ¡S )Nz InstanceMethod({!r}, {!r}, 
 {}))Úformatr   r   Úprettifyr    r   r   r   r   r   A   s
    ýzInstanceMethod.getSourceN©r   r   r   r   r   r   r   r   r   r   5   s   r   c                   @   s   e Zd ZdS )Ú_NoStateObjN)r   r   r   r   r   r   r   r%   I   s   r%   c                   @   s    e Zd Zefdd„Zdd„ ZdS )r   c                 K   sB   t |tƒstd| ƒ‚|| _|tk	r2|| _d| _n|| _d| _d S )Nz%s isn't a string!r   r   )r   Ústrr   r   Ú
NoStateObjÚstateÚstateIsDict)r   Z	classNameZ__stateObj__r(   r   r   r   r   ]   s    
zInstance.__init__c                 C   s    | j r| j}n(t| jtƒr2t| jjtƒr2| jj}nd }|d k	r†zd| j›dt|ƒ› d�W S  tk
r„   d| j›dt	|ƒ› d� Y S X d| j›dt	| jƒ› d�S )Nz	Instance(ú, ú))
r)   r(   r   r   ÚobjÚdictr   ÚdictToKWÚNonFormattableDictr#   )r   Z	stateDictr   r   r   r   h   s    
zInstance.getSourceN)r   r   r   r'   r   r   r   r   r   r   r   \   s   r   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
r   c                 G   s6   t |ƒdkr"|d | _|d | _n|s2d | _d | _d S )Né   r   r   )ÚlenÚrefnumr,   )r   Úargsr   r   r   r   y   s    
zRef.__init__c                 C   s&   | j rtd|› d| j › �ƒ‚|| _ d S )NzError setting id ú, I already have )r2   Ú
ValueError©r   Únumr   r   r   ÚsetRef‚   s    z
Ref.setRefc                 C   s&   | j rtd|› d| j › �ƒ‚|| _ d S )NzError setting obj r4   )r,   r5   )r   r,   r   r   r   ÚsetObj‡   s    z
Ref.setObjc                 C   s6   | j d krtdƒ‚| jr,d| jt| j ƒf S t| j ƒS )Nz7Don't try to display me before setting an object on me!zRef(%d, 
 %s))r,   ÚRuntimeErrorr2   r#   r   r   r   r   r   Œ   s    
ÿzRef.getSourceN)r   r   r   r   r8   r9   r   r   r   r   r   r   x   s   	r   c                   @   s    e Zd Zdd„ Zdd„ ZeZdS )r   c                 C   s
   || _ d S r	   ©r2   r6   r   r   r   r   —   s    zDeref.__init__c                 C   s
   d| j  S )Nz	Deref(%d)r;   r   r   r   r   r   š   s    zDeref.getSourceN)r   r   r   r   r   Ú__repr__r   r   r   r   r   –   s   r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚCopyregc                 C   s   || _ || _d S r	   )Úloadfuncr(   )r   r>   r(   r   r   r   r   ¡   s    zCopyreg.__init__c                 C   s   d| j ›dt| jƒ› d�S )NzCopyreg(r*   r+   )r>   r#   r(   r   r   r   r   r   ¥   s    zCopyreg.getSourceNr$   r   r   r   r   r=       s   r=   c                 C   s   t dt| ƒ ƒS )zDPass me an AO, I'll return a nicely-formatted source representation.zapp = )Ú	indentifyr#   )Úaor   r   r   r   ®   s    r   c                   @   s   e Zd ZdZdS )r/   z!A dictionary was not formattable.N)r   r   r   Ú__doc__r   r   r   r   r/   ³   s   r/   z[a-zA-Z_][a-zA-Z0-9_]*$c                 C   sx   g }t |  ¡ ƒ}| ¡  |D ]P\}}t|tƒs:td| ƒ‚t |¡sPtd| ƒ‚| d|› dt	|ƒ› d�¡ qd 
|¡S )Nz%r ain't a stringz%r ain't an identifierú
 ú=ú,Ú )ÚlistÚitemsÚsortr   r&   r/   ÚrÚmatchÚappendr#   Újoin)ÚdÚoutrG   ÚkÚvr   r   r   r.   º   s    

r.   c                 C   s>  t | dƒr|  ¡ S t| ƒ}|tkr*t| ƒS |tkrŠdg}|  ¡ D ](\}}| dt|ƒ› dt|ƒ› d�¡ q@| t	| ƒrzdp|d¡ d 
|¡S |tkrÔd	g}| D ]}| d
t|ƒ ¡ qœ| t	| ƒrÄdpÆd¡ d 
|¡S |tk�r$dg}| D ]}| d
t|ƒ ¡ qè| t	| ƒ�rd�pd¡ d 
|¡S td|› d| › d�ƒ‚d S )Nr   Ú{rB   z: rD   z
 }Ú}rE   ú[z
 %s,z
 ]ú]ú(z
 )r+   zUnsupported type z when trying to prettify Ú.)Úhasattrr   ÚtypeÚ_SIMPLE_BUILTINSÚreprr-   rG   rK   r#   r1   rL   rF   Útupler   )r,   ÚtrN   rO   rP   Úxr   r   r   r#   Ç   s0    
"



r#   c                 C   s†   g }g }d| g}t |jƒD ]`\}}\}}\}}	}
|dkrD| |¡ n|dkrT| ¡  |dkrp| dt|ƒ ¡ q| |¡ qd |¡S )NrE   )rS   rU   rQ   )rT   r+   rR   ú z  )ÚtokenizeÚpoprK   r1   rL   )ÚsrN   ÚstackÚlÚ	tokenTypeZtokenStringZstartRowZstartColumnZendRowZ	endColumnZlogicalLiner   r   r   r?   é   s$    úr?   c                 C   s   t ƒ  | ¡S )zG
    Pass me an Abstract Object Tree, and I'll unjelly it for you.
    )ÚAOTUnjellierÚunjelly)Úaotr   r   r   ÚunjellyFromAOT  s    rh   c              	   C   sj   t tttttttdœ}t| dƒr*|  	¡ }n| }t
|ddƒ}t|||ƒ d|krZt|d ƒS td|  ƒ‚dS )zå
    Pass me a string of code or a filename that defines an 'app' variable (in
    terms of Abstract Objects!), and I'll execute it and unjelly the resulting
    AOT for you, returning a newly unpersisted Application object!
    )r   r   r   r   r   r   r   r=   Úreadz<source>ÚexecZappz'%s needs to define an 'app', it didn't!N)r   r   r   r   r   r   r   r=   rW   ri   ÚcompileÚevalrh   r5   )ZstringOrFileÚnsÚsourceÚcoder   r   r   ÚunjellyFromSource  s"    ø

rp   c                   @   sH   e 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S )re   zWI handle the unjellying of an Abstract Object Tree.
    See AOTUnjellier.unjellyAO
    c                 C   s   i | _ g | _g | _d S r	   )Ú
referencesrb   ÚafterUnjellyr   r   r   r   r   /  s    zAOTUnjellier.__init__c                 C   s   t  ¡ }|  |d|¡ |S )zUnjelly a node, later.r   )r   Z_DeferÚunjellyInto)r   ÚnoderM   r   r   r   ÚunjellyLater7  s    zAOTUnjellier.unjellyLaterc                 C   s.   |   |¡}|||< t|tjƒr*| ||¡ |S )zvUtility method for unjellying one object into another.
        This automates the handling of backreferences.
        )Ú	unjellyAOr   r   ÚNotKnownÚaddDependant)r   r,   Úlocr@   Úor   r   r   rs   =  s
    
zAOTUnjellier.unjellyIntoc                 C   s:   t |tjƒr d g}| |d¡ n|g}| j ||f¡ d S )Nr   )r   r   rw   rx   rr   rK   )r   ÚcallableÚresultZ
listResultr   r   r   Ú	callAfterG  s
    zAOTUnjellier.callAfterc                 C   s   |   |j||¡ dS )zÙUtility method for unjellying into instances of attributes.

        Use this rather than unjellyAO unless you like surprising bugs!
        Alternatively, you can use unjellyInto on your instance's __dict__.
        N)rs   Ú__dict__)r   r    ÚattrNamer@   r   r   r   ÚunjellyAttributeO  s    zAOTUnjellier.unjellyAttributec                 C   s&  | j  |¡ t|ƒ}|tkr |S |tkrZg }|D ]$}| d¡ |  |t|ƒd |¡ q0|S |tkrªg }t}|D ]2}| d¡ t|  |t|ƒd |¡t	j
ƒrnt	j}qn||ƒS |tk� rôi }| ¡ D ].\}}t	 |¡}	|  |	d|¡ |  |	d|¡ qÀ|S |j}
|
tk�rt |j¡S |
ttfk�s*t|
tƒ�r6t |j¡S |
tk�r´|j}t |j¡}|  |j¡}||jk�r¨|dk�r~t||ƒS t|t	j
ƒ�ršt	 |||¡S t|||ƒS nt dƒ‚�nn|
t!k�rt |j¡}|  |j"¡}| #|¡}t$|dƒ�rü|  %|j&|¡ nt|tƒ�r||_n
| '¡ |_|S |
t(k�r¢|  |j)¡}|j*}| j+ ,|¡}|dk�r\|| j+|< nBt|t	j
ƒ�r€| -|¡ || j+|< n|dk�rŒnt.d|||f ƒ‚|S |
t/k�rä|j*}| j+ ,|¡}|dk�ràt	 0|¡}|| j+|< |S |S |
t1k�rt |j2¡}|  3|j"¡ 4dd„ |¡}|S t d	| ƒ‚dS )
zaUnjelly an Abstract Object and everything it contains.
        I return the real object.
        Nr   r   zinstance method changedÚ__setstate__z1Multiple references with the same ID: %s, %s, %s!c                 S   s   || Ž S r	   r   )r|   Z_lr   r   r   Ú<lambda>º  ó    z(AOTUnjellier.unjellyAO.<locals>.<lambda>zUnsupported AOT type: %s)5rb   rK   rX   rY   rF   rs   r1   r[   r   r   rw   Z_Tupler-   rG   Z_DictKeyAndValueÚ	__class__r   r   ZnamedModuler   r   r   Ú
issubclassZnamedObjectr   r   rv   r    r~   ÚgetattrZ_InstanceMethodr   r   r   r(   Ú__new__rW   r}   r�   Ú__getstate__r   r,   r2   rq   ÚgetZresolveDependantsr5   r   Z_Dereferencer=   r>   ru   ZaddCallback)r   r@   r\   rc   r]   Útuple_rM   rO   rP   ZkvdÚcZim_nameZim_classZim_selfr   r(   r!   rz   ZrefkeyÚrefr7   Zderr>   r   r   r   rv   X  s¨    














ÿÿ




 ÿzAOTUnjellier.unjellyAOc              
   C   sx   z:d g}|   |d|¡ | jD ]\}}||d ƒ q|d W S  tk
rr   t d¡ t d tt| jƒ¡¡ ‚ Y nX d S )Nr   ú+Error jellying object! Stacktrace follows::Ú
)	rs   rr   ÚBaseExceptionr   ÚmsgrL   ÚmaprZ   rb   )r   r@   rc   ÚfuncrP   r   r   r   rf   À  s    

zAOTUnjellier.unjellyN)r   r   r   rA   r   ru   rs   r}   r€   rv   rf   r   r   r   r   re   *  s   
	hre   c                 C   s   t ƒ  | ¡S )z-Convert an object to an Abstract Object Tree.)Ú
AOTJellierÚjelly)r,   r   r   r   Ú
jellyToAOTÒ  s    r•   c                 C   s.   t | ƒ}|r"| t|ƒ d¡¡ nt|ƒS dS )zª
    Pass me an object and, optionally, a file object.
    I'll convert the object to an AOT either return it (if no file was
    specified) or write it to the file.
    zutf-8N)r•   Úwriter   Úencode)r,   Úfilerg   r   r   r   ÚjellyToSource×  s    r™   c                 C   s   | j jS )z½
    Get the associated class of the given method object.

    @param methodObject: a bound method
    @type methodObject: L{types.MethodType}

    @return: a class
    @rtype: L{type}
    )Ú__self__r„   ©ZmethodObjectr   r   r   Ú_classOfMethodå  s    
rœ   c                 C   s   | j S )zð
    Get the associated function of the given method object.

    @param methodObject: a bound method
    @type methodObject: L{types.MethodType}

    @return: the function implementing C{methodObject}
    @rtype: L{types.FunctionType}
    )Ú__func__r›   r   r   r   Ú_funcOfMethodò  s    
rž   c                 C   s   | j S )zØ
    Get the object that a bound method is bound to.

    @param methodObject: a bound method
    @type methodObject: L{types.MethodType}

    @return: the C{self} passed to C{methodObject}
    @rtype: L{object}
    )rš   r›   r   r   r   Ú_selfOfMethodÿ  s    
rŸ   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
r“   c                 C   s   i | _ d| _g | _d S )Nr   )ÚpreparedÚ_ref_idrb   r   r   r   r   r     s    zAOTJellier.__init__c                 C   s   || j t|ƒ< dS )zaI prepare an object for later referencing, by storing its id()
        and its _AORef in a cache.N)r    Úid)r   ZaorefÚobjectr   r   r   ÚprepareForRef  s    zAOTJellier.prepareForRefc                    s0  t ˆ ƒ}ˆj tˆ ƒ¡ |tkr(ˆ ‰�nüt|tjƒr^tt	ˆ ƒj
t tˆ ƒ¡ˆ tˆ ƒ¡ƒ‰�nÆt|tjƒrxtˆ j
ƒ‰�n¬t|t ƒr”tt ˆ ¡ƒ‰�n�|tjkr°tt ˆ ¡ƒ‰�nttˆ ƒˆjkrþˆjtˆ ƒ }|jrÚ|j}nˆjd ˆ_ˆj}| |¡ t|ƒS tƒ ‰‡ ‡‡fdd„}ˆ ˆˆ ¡ |tk�rDˆ ‡fdd„ˆ D ƒ¡ nà|t k�rfˆ t t!ˆjˆ ƒƒ¡ n¾|t"k�r¨i }ˆ  #¡ D ]\}}ˆ |¡|ˆ |¡< �q|ˆ |¡ n||t$j%k�rät$j%| ˆ ƒ\}	}
ˆ t&t |	¡ˆ |
¡ƒ¡ n@t'ˆ dƒ�rþ|ˆ  (¡ ƒ n&t'ˆ dƒ�r|ˆ j)ƒ nt*d|j
 ƒ‚ˆjd	= ˆS )
z+I turn an object into an AOT and return it.r   c                    s"   ˆ  tt ˆ j¡ˆ | ¡ƒ¡ d S r	   )r9   r   r   Úqualr„   Ú	jellyToAO)r(   ©r,   Úretvalr   r   r   Ú
_stateFromL  s    ÿz(AOTJellier.jellyToAO.<locals>._stateFromc                    s   g | ]}ˆ   |¡‘qS r   )r¦   )Ú.0rz   r   r   r   Ú
<listcomp>T  s     z(AOTJellier.jellyToAO.<locals>.<listcomp>rˆ   r~   zUnsupported type: %séÿÿÿÿ)+rX   rb   rK   rZ   rY   r…   ÚtypesÚ
MethodTyper   rž   r   r   r¥   rœ   r¦   rŸ   Ú
ModuleTyper   r   ÚFunctionTyper   ZfullFuncNamer¢   r    r2   r¡   r8   r   r   r¤   rF   r9   r[   r‘   r-   rG   Úcopy_regÚdispatch_tabler=   rW   rˆ   r~   r   )r   r,   ZobjTypeZoldRefÚkeyr©   rM   rO   rP   ZunpickleFuncr(   r   r§   r   r¦     s`    ý





ÿzAOTJellier.jellyToAOc                 C   sH   z|   |¡}|W S  tk
rB   t d¡ t d | j¡¡ ‚ Y nX d S )Nr�   rŽ   )r¦   r�   r   r�   rL   rb   )r   r,   r@   r   r   r   r”   p  s    

zAOTJellier.jellyN)r   r   r   r   r¤   r¦   r”   r   r   r   r   r“     s   Xr“   )N)5rA   Úcopyregr±   Úrer­   Ztwisted.persistedr   Ztwisted.pythonr   r   Ztwisted.python.compatr   Ú	_tokenizer   r_   r   r   r   r   r   r%   r'   ÚboolÚbytesr&   ÚintÚfloatÚcomplexrX   ÚsliceÚEllipsisrY   r   r   r   r=   r   Ú	Exceptionr/   rk   rI   r.   r#   r?   rh   rp   re   r•   r™   rœ   rž   rŸ   r“   r   r   r   r   Ú<module>   sX   
÷

" )
