U
    W[H                  
   @   sL  d Z ddlmZmZ ddlZddlZzddlmZ W n  ek
rT   ddlmZ Y nX zddl	Z	W n   ddl
Z	Y nX ddlmZmZ ddlmZ ddlmZmZ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#ze#$e% W n e&k
rJ   Y nX 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# Z0d$d% Z1d&d' Z2d(d) Z3d*d+ Z4G d,d- d-Z5d.d/ Z6d;d0d1Z7zdd2lm8Z9m:Z; W n ek
r    dZ9dZ;Y nX d3d4 Z<d5d6 Z=d7d8 Z>G d9d: d:Z?dS )<z|
AOT: Abstract Object Trees
The source-code-marshallin'est abstract-object-serializin'est persister
this side of Marmalade!
    )divisionabsolute_importN)generate_tokens)tokenize)reflectlog)crefutil)unicode_PY3_constructMethodc                   @   s   e Zd Zdd ZdS )Namedc                 C   s
   || _ d S Nname)selfr    r   7/usr/lib/python3/dist-packages/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   3   s    zModule.getSourceNr   r   r   r   r   r   2   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   8   s
    zInstanceMethod.__init__c                 C   s   d| j | jt| jf S )NzInstanceMethod(%r, %r, 
 %s))r   r#   prettifyr$   r   r   r   r   r   ?   s    zInstanceMethod.getSourceNr   r   r   r   r   r   r   r   r   r   7   s   r   c                   @   s   e Zd ZdS )_NoStateObjN)r   r   r   r   r   r   r   r(   C   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   strr"   r#   
NoStateObjstatestateIsDict)r   Z	classNameZ__stateObj__r,   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	rzzd| jt|f W S  tk
rx   d| jt	|f  Y S X d| jt	| jf S )NzInstance(%r, %s))
r-   r,   r   r   objdictr#   dictToKWNonFormattableDictr&   )r   Z	stateDictr   r   r   r   ]   s    
zInstance.getSourceN)r   r   r   r+   r   r   r   r   r   r   r    Q   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   n   s    
zRef.__init__c                 C   s"   | j rtd|| j f || _ d S )Nz&Error setting id %s, I already have %s)r4   
ValueErrorr   numr   r   r   setRefw   s    z
Ref.setRefc                 C   s"   | j rtd|| j f || _ d S )Nz'Error setting obj %s, I already have %s)r.   r6   )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.   RuntimeErrorr4   r&   r   r   r   r   r      s
    
zRef.getSourceN)r   r   r   r   r9   r:   r   r   r   r   r   r   l   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   r4   r7   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 t| jf S )NzCopyreg(%r, %s))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 )r1   z&A dictionary was not formattable.
    N)r   r   r   __doc__r   r   r   r   r1      s   r1   z[a-zA-Z_][a-zA-Z0-9_]*$c                 C   sr   g }t |  }|  |D ]J\}}t|ts:td| t|sPtd| |d|t	|f  qd
|S )Nz%r ain't a stringz%r ain't an identifierz
 %s=%s, )listitemssortr   r*   r1   rmatchappendr&   join)doutrE   kvr   r   r   r0      s    

r0   c                 C   s2  t | dr|  S t| }|tkr*t| S |tkrdg}|  D ]"\}}|dt|t|f  q@|t	| rtdpvd d
|S |tkrdg}| D ]}|dt|  q|t	| rd	pd
 d
|S |tkrdg}| D ]}|dt|  q|t	| rdpd d
|S td|| f d S )Nr   {z	
 %s: %s,z
 }}rC   [z
 %s,z
 ]](z
 ))z/Unsupported type %s when trying to prettify %s.)hasattrr   type_SIMPLE_BUILTINSreprr/   rE   rI   r&   r3   rJ   rD   tupler"   )r.   trL   rM   rN   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 )NrC   )rQ   rS   rO   )rR   rT   rP    z  )r   poprI   r3   rJ   )srL   stacklZ	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    rd   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>   rU   re   compileevalrd   r6   )ZstringOrFilenssourcecoder   r   r   unjellyFromSource   s"    


rl   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 )ra   zWI handle the unjellying of an Abstract Object Tree.
    See AOTUnjellier.unjellyAO
    c                 C   s   i | _ g | _g | _d S r   )
referencesr_   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   ZnoderK   r   r   r   unjellyLater#  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.   ZlocrA   or   r   r   ro   *  s
    
zAOTUnjellier.unjellyIntoc                 C   s:   t |tjr d g}||d n|g}| j||f d S )Nr)   )r   r   rr   rs   rn   rI   )r   callableresultr`   r   r   r   	callAfter4  s
    zAOTUnjellier.callAfterc                 C   s   |  |j|| dS )zUtility 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)ro   __dict__)r   r$   ZattrNamerA   r   r   r   unjellyAttribute<  s    zAOTUnjellier.unjellyAttributec                 C   s,  | j | t|}|tkr |S |tkrZg }|D ]$}|d | |t|d | q0|S |tkrg }t}|D ]2}|d t| |t|d |t	j
rnt	j}qn||S |tk ri }| 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
rt	|||S t|||S nt dnl|
t!krt|j}| |j"}t#|dr|$|}nt%|}t#|dr| &|j'| n||_|S |
t(kr| |j)}|j*}| j+,|}|dkrZ|| j+|< nBt|t	j
r~|-| || j+|< n|dkrnt.d|||f |S |
t/kr|j*}| j+,|}|dkrt	0|}|| j+|< |S |S |
t1krt|j2}| 3|j"4dd	 |}|S t d
| | j d= dS )zaUnjelly an Abstract Object and everything it contains.
        I return the real object.
        Nr)   r   zinstance method changed__new____setstate__z1Multiple references with the same ID: %s, %s, %s!c                 S   s   ||  S r   r   )rv   Z_lr   r   r   <lambda>      z(AOTUnjellier.unjellyAO.<locals>.<lambda>zUnsupported AOT type: %s)5r_   rI   rV   rW   rD   ro   r3   rY   r   r   rr   Z_Tupler/   rE   Z_DictKeyAndValue	__class__r   r   ZnamedModuler   r   r   
issubclassZnamedObjectr   r#   rq   r$   rx   getattrZ_InstanceMethodr   r"   r    r,   rU   rz   _OldStyleInstancerw   r{   r   r.   r4   rm   getZresolveDependantsr6   r!   Z_Dereferencer>   r?   rp   ZaddCallback)r   rA   rZ   r`   r[   Ztuple_rK   rM   rN   ZkvdcZim_nameim_classim_selfr#   r,   r%   rt   Zrefkeyrefr8   Zderr?   r   r   r   rq   E  s    

















 zAOTUnjellier.unjellyAOc              
   C   sp   z:d g}|  |d| | jD ]\}}||d  q|d W S    td tdtt| j  Y nX d S )Nr   +Error jellying object! Stacktrace follows::
)ro   rn   r   msgrJ   maprX   r_   )r   rA   r`   funcrN   r   r   r   rb     s    

zAOTUnjellier.unjellyN)r   r   r   rB   r   rp   ro   rw   ry   rq   rb   r   r   r   r   ra     s   
	hra   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.   filerc   r   r   r   jellyToSource  s    r   )	ClassTypeInstanceTypec                 C   s   t r| jjS | 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{types.ClassType} or L{type}
    )r
   __self__r   r   ZmethodObjectr   r   r   _classOfMethod  s    
r   c                 C   s   t r
| j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}
    )r
   __func__Zim_funcr   r   r   r   _funcOfMethod  s    
r   c                 C   s   t r
| j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   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_idr_   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                    sH  t  }jt  |tkr( n|tjkr\tt j	t
t t n|tjkrtt j	n|tkrtt
 nt|t rtt
 n|tjkrtt
 nvt jkrjt  }|jr|j}njd _j}|| t|S t  fdd}  |tkr\ fdd D  n|t!kr~ t!t"j  n|t#kri } $ D ]\}}|||< q | n||t%j&krt%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   )r:   r    r   qualr   	jellyToAO)r,   r.   Zretvalr   r   r   
_stateFromI  s    z(AOTJellier.jellyToAO.<locals>._stateFromc                    s   g | ]}  |qS r   )r   ).0rt   r   r   r   
<listcomp>O  s     z(AOTJellier.jellyToAO.<locals>.<listcomp>__getstate__rx   zUnsupported type: %sr~   ),rV   r_   rI   rX   rW   types
MethodTyper   r   r   r   r   r   r   r   
ModuleTyper   _OldStyleClassr   r   FunctionTyper   ZfullFuncNamer   r   r4   r   r9   r!   r   r   rD   r:   rY   r   r/   rE   copy_regdispatch_tabler>   rU   r   rx   r"   )r   r.   ZobjTypeZoldRefkeyr   rK   rM   rN   ZunpickleFuncr,   r   r   r   r     sb    








zAOTJellier.jellyToAOc                 C   s@   z|  |}|W S    td td| j  Y nX d S )Nr   r   )r   r   r   rJ   r_   )r   r.   rA   r   r   r   r   j  s    

zAOTJellier.jellyN)r   r   r   r   r   r   r   r   r   r   r   r     s   Vr   )N)@rB   Z
__future__r   r   r   rer   r   ImportErrorr   copyregZtwisted.pythonr   r   Ztwisted.persistedr   Ztwisted.python.compatr	   r
   r   r   r   r   r   r   r(   r+   boolbytesintfloatcomplexrV   sliceEllipsisrW   rI   Zlong	NameErrorr    r   r!   r>   r   	Exceptionr1   rg   rG   r0   r&   r@   rd   rl   ra   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sv   	       

! '

