o
    bF                  
   @   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 ddl	m
Z
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.d8d.d/Z/d0d1 Z0d2d3 Z1d4d5 Z2G d6d7 d7Z3dS )9z|
AOT: Abstract Object Trees
The source-code-marshallin'est abstract-object-serializin'est persister
this side of Marmalade!
    N)generate_tokens)crefutil)logreflect)_constructMethodc                   @      e Zd Zdd ZdS )Namedc                 C   
   || _ d S Nname)selfr    r   7/usr/lib/python3/dist-packages/twisted/persisted/aot.py__init__      
zNamed.__init__N)__name__
__module____qualname__r   r   r   r   r   r          r   c                   @   r   )Classc                 C   
   d| j  S )Nz	Class(%r)r   r   r   r   r   	getSource$   r   zClass.getSourceNr   r   r   r   r   r   r   r   r   #   r   r   c                   @   r   )Functionc                 C   r   )NzFunction(%r)r   r   r   r   r   r   )   r   zFunction.getSourceNr   r   r   r   r   r   (   r   r   c                   @   r   )Modulec                 C   r   )Nz
Module(%r)r   r   r   r   r   r   .   r   zModule.getSourceNr   r   r   r   r   r   -   r   r   c                   @      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   3   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   >   s
   zInstanceMethod.getSourceNr   r   r   r   r   r   r   r   r   r   2   s    r   c                   @   s   e Zd ZdS )_NoStateObjN)r   r   r   r   r   r   r   r*   F   s    r*   c                   @   s    e Zd ZefddZdd ZdS )r!   c                 K   sD   t |tstd| || _|tur|| _d| _d S || _d| _d S )Nz%s isn't a string!r      )r   strr#   r$   
NoStateObjstatestateIsDict)r   	className__stateObj__r.   r   r   r   r   Z   s   


zInstance.__init__c                 C   s   | j r| j}nt| jtrt| jjtr| jj}nd }|d urBzd| jdt| dW S  tyA   d| jdt	| d Y S w d| jdt	| j dS )Nz	Instance(, ))
r/   r.   r   r    objdictr$   dictToKWNonFormattableDictr(   )r   	stateDictr   r   r   r   e   s   
zInstance.getSourceN)r   r   r   r-   r   r   r   r   r   r   r!   Y   s    r!   c                   @   ,   e Zd Zdd Zdd Zdd Zdd Zd	S )
r    c                 G   s<   t |dkr|d | _|d | _d S |sd | _d | _d S d S )N   r   r+   )lenrefnumr4   )r   argsr   r   r   r   v   s   

zRef.__init__c                 C   &   | j rtd| d| j  || _ d S )NzError setting id , I already have )r<   
ValueErrorr   numr   r   r   setRef      
z
Ref.setRefc                 C   r>   )NzError setting obj r?   )r4   r@   )r   r4   r   r   r   setObj   rD   z
Ref.setObjc                 C   s6   | j d u 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))r4   RuntimeErrorr<   r(   r   r   r   r   r      s   

zRef.getSourceN)r   r   r   r   rC   rE   r   r   r   r   r   r    u   s
    	r    c                   @   s    e Zd Zdd Zdd ZeZdS )r"   c                 C   r	   r
   r<   rA   r   r   r   r      r   zDeref.__init__c                 C   r   )Nz	Deref(%d)rG   r   r   r   r   r      r   zDeref.getSourceN)r   r   r   r   r   __repr__r   r   r   r   r"      s    r"   c                   @   r   )Copyregc                 C   s   || _ || _d S r
   )loadfuncr.   )r   rJ   r.   r   r   r   r      s   
zCopyreg.__init__c                 C   s   d| j dt| j dS )NzCopyreg(r2   r3   )rJ   r(   r.   r   r   r   r   r      s   zCopyreg.getSourceNr)   r   r   r   r   rI      s    rI   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 )r7   z!A dictionary was not formattable.N)r   r   r   __doc__r   r   r   r   r7      s    r7   z[a-zA-Z_][a-zA-Z0-9_]*$c                 C   sx   g }t |  }|  |D ](\}}t|tstd| t|s(td| |d| dt	| d qd
|S )Nz%r ain't a stringz%r ain't an identifier
 =, )listitemssortr   r,   r7   rmatchappendr(   join)doutrS   kvr   r   r   r6      s   


r6   c                 C   s4  t | dr	|  S t| }|tv rt| S |tu rEdg}|  D ]\}}|dt| dt| d q |t	| r=dp>d d
|S |tu rjd	g}| D ]}|d
t|  qN|t	| rbdpcd d
|S |tu rdg}| D ]}|d
t|  qs|t	| rdpd d
|S td| d|  d)Nr   {rN   z: rP   z
 }}rQ   [z
 %s,z
 ]](z
 )r3   zUnsupported type z when trying to prettify .)hasattrr   type_SIMPLE_BUILTINSreprr5   rS   rW   r(   r;   rX   rR   tupler#   )r4   trZ   r[   r\   xr   r   r   r(      s0   
"


r(   c                 C   s   g }g }d| g}t |jD ]0\}}\}}\}}	}
|dv r"|| n|dv r*|  |dkr8|dt|  q|| qd|S )NrQ   )r_   ra   r]   )r`   r3   r^    z  )tokenizepoprW   r;   rX   )srZ   stackl	tokenTypetokenStringstartRowstartColumnendRow	endColumnlogicalLiner   r   r   rK      s$   
rK   c                 C      t  | S )zG
    Pass me an Abstract Object Tree, and I'll unjelly it for you.
    )AOTUnjellierunjelly)aotr   r   r   unjellyFromAOT  s   r{   c              	   C   sf   t tttttttd}t| dr| 	 }n| }t
|dd}t||| d|v r-t|d S td|  )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"   rI   readz<source>execappz'%s needs to define an 'app', it didn't!)r!   r   r   r   r   r    r"   rI   rc   r|   compileevalr{   r@   )stringOrFilenssourcecoder   r   r   unjellyFromSource  s"   

r   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 )rx   zWI handle the unjellying of an Abstract Object Tree.
    See AOTUnjellier.unjellyAO
    c                 C   s   i | _ g | _g | _d S r
   )
referencesrn   afterUnjellyr   r   r   r   r   ,  s   
zAOTUnjellier.__init__c                 C   s   t  }| |d| |S )zUnjelly a node, later.r   )r   _DeferunjellyInto)r   noderY   r   r   r   unjellyLater4  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   r4   locrL   or   r   r   r   :  s
   
zAOTUnjellier.unjellyIntoc                 C   s:   t |tjrd g}||d n|g}| j||f d S )Nr+   )r   r   r   r   r   rW   )r   callableresult
listResultr   r   r   	callAfterD  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)r   __dict__)r   r%   attrNamerL   r   r   r   unjellyAttributeL  s   zAOTUnjellier.unjellyAttributec                 C   s  | j | t|}|tv r|S |tu r-g }|D ]}|d | |t|d | q|S |tu rUg }t}|D ]}|d t| |t|d |t	j
rPt	j}q7||S |tu ryi }| D ]\}}t	|}	| |	d| | |	d| q_|S |j}
|
tu rt|jS |
ttfv st|
trt|jS |
tu r|j}t|j}| |j}||jv r|du rt||S t|t	j
rt	|||S t|||S t d|
t!u rt|j}| |j"}|#|}t$|dr| %|j&| |S ||_|S |
t'u r;| |j(}|j)}| j*+|}|du r|| j*|< |S t|t	j
r*|,| || j*|< |S |du r2	 |S t-d|||f |
t.u r\|j)}| j*+|}|du rZt	/|}|| j*|< |S |S |
t0u rut|j1}| 2|j"3dd |}|S t d	| )
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   _lr   r   r   <lambda>  s    z(AOTUnjellier.unjellyAO.<locals>.<lambda>zUnsupported AOT type: %s)4rn   rW   rd   re   rR   r   r;   rg   r   r   r   _Tupler5   rS   _DictKeyAndValue	__class__r   r   namedModuler   r   r   
issubclassnamedObjectr   r$   r   r%   r   getattr_InstanceMethodr   r#   r!   r.   __new__rc   r   r   r    r4   r<   r   getresolveDependantsr@   r"   _DereferencerI   rJ   r   addCallback)r   rL   rh   ro   ri   tuple_rY   r[   r\   kvdcim_nameim_classim_selfr$   r.   r&   r   refkeyrefrB   derrJ   r   r   r   r   U  s   











	





zAOTUnjellier.unjellyAOc              
   C   sn   zd g}|  |d| | jD ]
\}}||d  q|d W S  ty6   td tdtt| j  w )Nr   +Error jellying object! Stacktrace follows::
)	r   r   BaseExceptionr   msgrX   maprf   rn   )r   rL   ro   funcr\   r   r   r   ry     s   

zAOTUnjellier.unjellyN)r   r   r   rM   r   r   r   r   r   r   ry   r   r   r   r   rx   '  s    
	frx   c                 C   rw   )z-Convert an object to an Abstract Object Tree.)
AOTJellierjelly)r4   r   r   r   
jellyToAOT  s   r   c                 C   s,   t | }|r|t|d dS t|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)r4   filerz   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   methodObjectr   r   r   _classOfMethod  s   
r   c                 C      | 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     
r   c                 C   r   )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  r   r   c                   @   r9   )
r   c                 C   s   i | _ d| _g | _d S )Nr   )prepared_ref_idrn   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   aorefobjectr   r   r   prepareForRef  s   zAOTJellier.prepareForRefc                    s   t  }jt  |tv r nt|tjr-tt	 j
tt t nt|tjr9t j
nt|t rFtt n|tju rStt nt jv r}jt  }|jrk|j}t|S jd _j}|| t|S t  fdd}  |tu rfdd D  nk|t u rt t!j  n[|t"u ri } # D ]\}}|||< q| n<|t$j%v 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
   )rE   r!   r   qualr   	jellyToAO)r.   r4   retvalr   r   r   
_stateFromH  s   z(AOTJellier.jellyToAO.<locals>._stateFromc                    s   g | ]}  |qS r   )r   ).0r   r   r   r   
<listcomp>P  s    z(AOTJellier.jellyToAO.<locals>.<listcomp>__getstate__r   zUnsupported type: %s)+rd   rn   rW   rf   re   r   types
MethodTyper   r   r   r   r   r   r   r   
ModuleTyper   r   FunctionTyper   fullFuncNamer   r   r<   r   rC   r"   r    r   rR   rE   rg   r   r5   rS   copy_regdispatch_tablerI   rc   r   r   r#   )r   r4   objTypeoldRefkeyr   rY   r[   r\   unpickleFuncr.   r   r   r   r     sb   




zAOTJellier.jellyToAOc                 C   s>   z|  |}|W S  ty   td td| j  w )Nr   r   )r   r   r   r   rX   rn   )r   r4   rL   r   r   r   r   l  s   

zAOTJellier.jellyN)r   r   r   r   r   r   r   r   r   r   r   r     s
    Yr   r
   )4rM   copyregr   rer   rk   r   twisted.persistedr   twisted.pythonr   r   twisted.python.compatr   r   r   r   r   r   r*   r-   boolbytesr,   intfloatcomplexrd   sliceEllipsisre   r!   r    r"   rI   r   	Exceptionr7   r   rU   r6   r(   rK   r{   r   rx   r   r   r   r   r   r   r   r   r   r   <module>   sZ   


" '
