a
    CgF1                     @   s4  d dl mZ d dlmZ d dlmZmZ g dZdZG dd de	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eZG dd deZG dd dZG dd deZG dd deZG dd deedZG dd deZG dd  d ZG d!d" d"ZG d#d$ d$Ze ZejZejZd%S )&    )forms)MediaDefiningClass)cached_propertyPromise)_type_args_dict_list_val_id_ref   c                   @   s   e Zd ZdS )UnpackableTypeErrorN)__name__
__module____qualname__ r   r   P/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/telepath/__init__.pyr   
   s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )Nodeao  
    Intermediate representation of a packed value. Subclasses represent a particular value
    type, and implement emit_verbose (returns a dict representation of a value that can have
    an _id attached) and emit_compact (returns a compact representation of the value, in any
    JSON-serialisable type).

    If this node is assigned an id, emit() will return the verbose representation with the
    id attached on first call, and a reference on subsequent calls. To disable this behaviour
    (e.g. for small primitive values where the reference representation adds unwanted overhead),
    set self.use_id = False.
    c                 C   s   d | _ d| _d| _d S )NFT)idseenuse_idselfr   r   r   __init__   s    zNode.__init__c                 C   sX   | j r | jr | jd ur d| jiS d| _| j rL| jd urL|  }| j|d< |S |  S d S )Nr   Tr   )r   r   r   emit_verboseemit_compact)r   resultr   r   r   emit   s    

z	Node.emitN)r   r   r   __doc__r   r   r   r   r   r   r      s   r   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )	ValueNodez+Represents a primitive value; int, bool etcc                    s   t    || _d| _d S )NF)superr   valuer   r   r"   	__class__r   r   r   0   s    
zValueNode.__init__c                 C   s
   d| j iS Nr
   r"   r   r   r   r   r   5   s    zValueNode.emit_verbosec                 C   s   | j S Nr'   r   r   r   r   r   8   s    zValueNode.emit_compact)r   r   r   r   r   r   r   __classcell__r   r   r$   r   r    .   s   r    c                       s,   e Zd Z fddZdd Zdd Z  ZS )
StringNodec                    s"   t    || _t|tk| _d S r(   )r!   r   r"   lenSTRING_REF_MIN_LENGTHr   r#   r$   r   r   r   =   s    
zStringNode.__init__c                 C   s
   d| j iS r&   r'   r   r   r   r   r   B   s    zStringNode.emit_verbosec                 C   s   | j S r(   r'   r   r   r   r   r   E   s    zStringNode.emit_compactr   r   r   r   r   r   r)   r   r   r$   r   r*   <   s   r*   c                       s,   e Zd Z fddZdd Zdd Z  ZS )ListNodec                    s   t    || _d S r(   r!   r   r"   r#   r$   r   r   r   J   s    
zListNode.__init__c                 C   s   ddd | j D iS )Nr	   c                 S   s   g | ]}|  qS r   r   .0itemr   r   r   
<listcomp>O       z)ListNode.emit_verbose.<locals>.<listcomp>r'   r   r   r   r   r   N   s    zListNode.emit_verbosec                 C   s   dd | j D S )Nc                 S   s   g | ]}|  qS r   r0   r1   r   r   r   r4   R   r5   z)ListNode.emit_compact.<locals>.<listcomp>r'   r   r   r   r   r   Q   s    zListNode.emit_compactr-   r   r   r$   r   r.   I   s   r.   c                       s,   e Zd Z fddZdd Zdd Z  ZS )DictNodec                    s   t    || _d S r(   r/   r#   r$   r   r   r   V   s    
zDictNode.__init__c                 C   s   ddd | j  D iS )Nr   c                 S   s   i | ]\}}||  qS r   r0   r2   keyvalr   r   r   
<dictcomp>[   r5   z)DictNode.emit_verbose.<locals>.<dictcomp>)r"   itemsr   r   r   r   r   Z   s    zDictNode.emit_verbosec                    s6   t  fddtD r  S dd  j D S d S )Nc                 3   s   | ]}| j v V  qd S r(   r'   )r2   Zreserved_keyr   r   r   	<genexpr>^   r5   z(DictNode.emit_compact.<locals>.<genexpr>c                 S   s   i | ]\}}||  qS r   r0   r7   r   r   r   r:   c   r5   z)DictNode.emit_compact.<locals>.<dictcomp>)anyDICT_RESERVED_KEYSr   r"   r;   r   r   r   r   r   ]   s    zDictNode.emit_compactr-   r   r   r$   r   r6   U   s   r6   c                       s,   e Zd Z fddZdd Zdd Z  ZS )
ObjectNodec                    s   t    || _|| _d S r(   )r!   r   constructorargs)r   r@   rA   r$   r   r   r   g   s    
zObjectNode.__init__c                 C   s   | j dd | jD dS )Nc                 S   s   g | ]}|  qS r   r0   r2   argr   r   r   r4   o   r5   z+ObjectNode.emit_verbose.<locals>.<listcomp>)r   r   )r@   rA   r   r   r   r   r   l   s    zObjectNode.emit_verbosec                 C   s   |   S r(   )r   r   r   r   r   r   r   s    zObjectNode.emit_compactr-   r   r   r$   r   r?   f   s   r?   c                   @   s   e Zd ZdZdd ZdS )BaseAdapterz/Handles serialisation of a specific object typec                 C   s   t |S )ay  
        Translates obj into a node that we can call emit() on to obtain the final serialisable
        form. Any media declarations that will be required for deserialisation of the object should
        be passed to context.add_media().

        This base implementation handles simple JSON-serialisable values such as integers, and
        wraps them as a ValueNode.
        )r    r   objcontextr   r   r   
build_nodey   s    	zBaseAdapter.build_nodeNr   r   r   r   rH   r   r   r   r   rD   w   s   rD   c                   @   s   e Zd Zdd ZdS )StringAdapterc                 C   s   t |S r(   )r*   rE   r   r   r   rH      s    zStringAdapter.build_nodeN)r   r   r   rH   r   r   r   r   rJ      s   rJ   c                   @   s   e Zd ZdZdd ZdS )DictAdapterzHandles serialisation of dictsc                    s   t  fdd| D S )Nc                    s    i | ]\}}t | |qS r   )strrH   r7   rG   r   r   r:      s   z*DictAdapter.build_node.<locals>.<dictcomp>)r6   r;   rE   r   rM   r   rH      s    zDictAdapter.build_nodeNrI   r   r   r   r   rK      s   rK   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	Adaptera  
    Handles serialisation of custom types.
    Subclasses should define:
    - js_constructor: namespaced identifier for the JS constructor function that will unpack this
        object
    - js_args(obj): returns a list of (telepath-packable) arguments to be passed to the constructor
    - get_media(obj) or class Media: media definitions necessary for unpacking

    The adapter should then be registered with register(adapter, cls).
    c                 C   s   | j S r(   )mediar   rF   r   r   r   	get_media   s    zAdapter.get_mediac                 C   s    | | | | j| |fS r(   )	add_mediarQ   Zjs_constructorZjs_argsrE   r   r   r   pack   s    zAdapter.packc                    s(   |  | \}}t| fdd|D S )Nc                    s   g | ]}  |qS r   rH   rB   rM   r   r   r4      r5   z&Adapter.build_node.<locals>.<listcomp>)rS   r?   )r   rF   rG   r@   rA   r   rM   r   rH      s    zAdapter.build_nodeN)r   r   r   r   rQ   rS   rH   r   r   r   r   rN      s   rN   )	metaclassc                   @   s   e Zd ZdZdd ZdS )AutoAdapterzh
    Adapter for objects that define their own telepath_pack method that we can simply delegate to.
    c                 C   s
   | |S r(   )Ztelepath_packrE   r   r   r   rS      s    zAutoAdapter.packN)r   r   r   r   rS   r   r   r   r   rV      s   rV   c                   @   s6   e Zd ZdZdd Zedd ZdddZd	d
 ZdS )JSContextBasea6  
    Base class for JSContext classes obtained through AdapterRegistry.js_context_class.
    Subclasses of this are assigned the following class attributes:
    registry - points to the associated AdapterRegistry
    telepath_js_path - path to telepath.js (as per standard Django staticfiles conventions)

    A JSContext handles packing a set of values to be used in the same request; calls to
    JSContext.pack will return the packed representation and also update the JSContext's media
    property to include all JS needed to unpack the values seen so far.
    c                 C   s   | j | _tt| jg| _d S r(   )
base_mediarO   setrL   media_fragmentsr   r   r   r   r      s    zJSContextBase.__init__c                 C   s   t j| jgdS )N)js)r   Mediatelepath_js_pathr   r   r   r   rX      s    zJSContextBase.base_mediaNc                 C   sx   g }|r| | |s|r>t|tr*|g}| tj||d |D ]0}t|}|| jvrB|  j|7  _| j| qBd S )N)r[   css)append
isinstancerL   r   r\   rZ   rO   add)r   rO   r[   r^   Zmedia_objectsZ	media_objZ	media_strr   r   r   rR      s    


zJSContextBase.add_mediac                 C   s   t | | S r(   )ValueContextrH   r   rP   r   r   r   rS      s    zJSContextBase.pack)NNN)	r   r   r   r   r   propertyrX   rR   rS   r   r   r   r   rW      s   


rW   c                   @   s:   e Zd ZdZeZdddZdd Zdd Ze	d	d
 Z
dS )AdapterRegistryz]
    Manages the mapping of Python types to their corresponding adapter implementations.
    telepath/js/telepath.jsc                 C   s8   || _ td t tt tt tt tt tt	 i| _
d S r(   )r]   typerD   boolintfloatrL   rJ   dictrK   adapters)r   r]   r   r   r   r      s    
zAdapterRegistry.__init__c                    s   t |dkr:|s:|\ }t ts.td   j|< nv|sv|dpLt  t tsdtd   fdd}|S t |dkrt|d tr|d }t j|< |S tdd S )	N   z0register expected a BaseAdapter instance, got %radapterc                    s    j | < | S r(   )rk   )clsrm   r   r   r   wrapper  s    
z)AdapterRegistry.register.<locals>.wrapper   r   zwregister must be called as register(adapter, cls) or as a class decorator - @register or @register(adapter=MyAdapter()))r+   r`   rD   	TypeErrorrk   getrV   rf   )r   rA   kwargsrn   rp   r   ro   r   register   s$    

zAdapterRegistry.registerc                 C   s,   |j D ] }| j|}|d ur|  S qd S r(   )__mro__rk   rs   )r   rn   baserm   r   r   r   find_adapter  s    
zAdapterRegistry.find_adapterc                 C   s   t d| jf| | jdS )N	JSContext)registryr]   )rf   js_context_base_classr]   r   r   r   r   js_context_class   s    
z AdapterRegistry.js_context_classN)re   )r   r   r   r   rW   r{   r   ru   rx   r   r|   r   r   r   r   rd      s   
%rd   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )rb   a  
    A context instantiated for each top-level value that JSContext.pack is called on. Results from
    this context's build_node method will be kept in a lookup table. If, over the course of
    building the node tree for the top level value, we encounter multiple references to the same
    value, a reference to the existing node will be generated rather than building it again. Calls
    to add_media are passed back to the parent context so that multiple calls to pack() will have
    their media combined in a single bundle.
    c                 C   s$   || _ |j| _i | _i | _d| _d S )Nr   )parent_contextrz   
raw_valuesnodesnext_id)r   r}   r   r   r   r   1  s
    zValueContext.__init__c                 O   s   | j j|i | d S r(   )r}   rR   )r   rA   rt   r   r   r   rR   8  s    zValueContext.add_mediac                 C   sp   t |}z| j| }W n4 tyJ   | |}|| j|< || j|< | Y S 0 |j d u rl| j|_ |  jd7  _|S )Nrq   )r   r   KeyError_build_new_noder~   r   )r   r9   Zobj_idZexisting_nodenoder   r   r   rH   ;  s    




zValueContext.build_nodec                    s|    j t|}|r || S t|tr6tt|S zt|}W n t	y`   t
d| Y n0 t fdd|D S d S )Nz!don't know how to pack object: %rc                    s   g | ]}  |qS r   rT   r1   r   r   r   r4   b  r5   z0ValueContext._build_new_node.<locals>.<listcomp>)rz   rx   rf   rH   r`   r   r*   rL   iterrr   r   r.   )r   rF   rm   r;   r   r   r   r   P  s    
zValueContext._build_new_nodeN)r   r   r   r   r   rR   rH   r   r   r   r   r   rb   (  s
   rb   N)Zdjangor   Zdjango.formsr   Zdjango.utils.functionalr   r   r>   r,   rr   r   r   r    r*   r.   r6   r?   rD   rJ   rK   rN   rV   rW   rd   rb   rz   r|   ry   ru   r   r   r   r   <module>   s,    	*IA