U
    dRf3                     @   s  d Z ddlmZ ddlZddlZddlZddlmZ dd Zd$ddZ	d	d
 Z
G dd deZG dd deZG dd deZd%ddZG dd de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eZG d d! d!eZG d"d# d#eZdS )&zE
    thriftpy2.thrift
    ~~~~~~~~~~~~~~~~~~

    Thrift simplified.
    )absolute_importN)zip_longestc                 O   sd   t t|  |D ]L\}}|d d }|d d }|d k	rJ|||d d < |r||krt|q|S )N   )r   sorteditems
ValueError)thrift_specargskwargsitemvalueZarg_namerequired r   4/tmp/pip-unpacked-wheel-jqs7l_7o/thriftpy2/thrift.pyargs_to_kwargs   s    
r   c                    s   t j  fdd}|d kr" |  S | t jkr2|jS | t jt jfkrVd |  ||f S | t jkr|d||d ||d f S d S )Nc                    s   t | trt|  S  |  S N)
isinstancetuple
parse_spec)sZname_mapr   r   _type    s    zparse_spec.<locals>._typez%s<%s>zMAP<%s, %s>r   r   )TType_VALUES_TO_NAMESSTRUCT__name__LISTSETMAP)ttypespecr   r   r   r   r      s    

r   c           
      C   s   |sdd }|S t | \}}dtdj|}d|}|dtdj|7 }d| j}t||d	}td
d |jD }	t|d|	d|ft
j|< tj|	i |dS )a=  Generate `__init__` function based on TPayload.default_spec

    For example::

        spec = [('name', 'Alice'), ('number', None)]

    will generate a types.FunctionType object representing::

        def __init__(self, name='Alice', number=None):
            self.name = name
            self.number = number
    c                 S   s   d S r   r   selfr   r   r   __init__>   s    z%init_func_generator.<locals>.__init__, z{0[0]}={0[1]!r}zdef __init__(self, {}):

z    self.{0} = {0}z<generated {}.__init__>execc                 s   s   | ]}t |tjr|V  qd S r   )r   typesCodeType).0cr   r   r   	<genexpr>J   s      z&init_func_generator.<locals>.<genexpr>NT)Zargdefs)zipjoinmapformatr   compilenext	co_constslen
splitlines	linecachecacher(   FunctionType)
clsr!   r$   varnamesdefaultsr
   initnamecodefuncr   r   r   init_func_generator0   s    
r@   c                $   @   s   e Zd ZdZdZdZdZdZdZdZ	dZ
dZd	Zd	Zd
ZdZdZdZdZdZdZedededededede	de
dedededededededededed iZd!S )"r   r   r                  
                           STOPVOIDBOOLBYTEDOUBLEI16I32I64STRINGr   r   r   r   UTF8UTF16BINARYN)r   
__module____qualname__rO   rP   rQ   rR   ZI08rS   rT   rU   rV   rW   ZUTF7r   r   r   r   rX   rY   rZ   r   r   r   r   r   r   S   sn                     r   c                   @   s   e Zd ZdZdZdZdZdS )TMessageTyper   rA   rB   rC   N)r   r[   r\   CALLREPLY	EXCEPTIONONEWAYr   r   r   r   r]   }   s   r]   c                       s   e Zd Z fddZ  ZS )TPayloadMetac                    s6   d|kr | d}t| ||d< tt| | |||S )Ndefault_specr$   )popr@   superrb   __new__)r9   r=   basesattrsr!   	__class__r   r   rf      s    
zTPayloadMeta.__new__)r   r[   r\   rf   __classcell__r   r   ri   r   rb      s   rb   c                 C   s&   |d k	r|| _ |d k	r"t| || _| S r   )r	   r@   r$   )r9   r	   rc   r   r   r   gen_init   s
    rl   c                   @   s@   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S )TPayloadNc                 C   s   | |  d S r   )Zread_struct)r#   iprotr   r   r   read   s    zTPayload.readc                 C   s   | |  d S r   )Zwrite_struct)r#   oprotr   r   r   write   s    zTPayload.writec                 C   s*   dd | j  D }d| jjd|f S )Nc                 S   s   g | ]\}}d ||f qS )z%s=%rr   )r*   keyr   r   r   r   
<listcomp>   s     z%TPayload.__repr__.<locals>.<listcomp>z%s(%s)r%   )__dict__r   rj   r   r.   )r#   lr   r   r   __repr__   s    zTPayload.__repr__c                 C   s   t | S r   )reprr"   r   r   r   __str__   s    zTPayload.__str__c                 C   s   t || jo| j|jkS r   )r   rj   rt   r#   otherr   r   r   __eq__   s    
zTPayload.__eq__c                 C   s   |  | S r   )r{   ry   r   r   r   __ne__   s    zTPayload.__ne__)
r   r[   r\   __hash__ro   rq   rv   rx   r{   r|   r   r   r   r   rm      s   rm   )	metaclassc                   @   sF   e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd Zdd Z	dS )TClientNc                 C   s*   || _ | | _| _|d k	r || _d| _d S )Nr   )_service_iprot_oprot_seqid)r#   servicern   rp   r   r   r   r$      s
    zTClient.__init__c                 C   sH   || j jkrt| j|S |dkr0t| jdS td| jj|d S )NZtcloseclosez!{} instance has no attribute '{}')	r   thrift_services	functoolspartial_reqAttributeErrorr0   rj   r   )r#   _apir   r   r   __getattr__   s     zTClient.__getattr__c                 C   s   | j jS r   )r   r   r"   r   r   r   __dir__   s    zTClient.__dir__c              
   O   s   z&t | j|d }t|jf||}W nD tk
rj } z&ttjdj|jd | jj	|dW 5 d }~X Y nX t | j|d }| j
|f| t |ds| |S d S )N_argsz.{arg} is required argument for {service}.{api}r   )argr   api_resultoneway)getattrr   r   r	   r   TApplicationExceptionUNKNOWN_METHODr0   r
   r   _send_recv)r#   r   r
   r   Zservice_argseZ
result_clsr   r   r   r      s       
zTClient._reqc                 K   s   t t | j|d d}|r tjntj}| j||| j t | j|d  }| D ]\}}t	||| qR|
| j | j  | jj  d S )Nr   r   r   )r   r   r]   ra   r^   r   write_message_beginr   r   setattrrq   write_message_endtransflush)r#   r   r   r   msg_typer
   kvr   r   r   r      s    
zTClient._sendc           	      C   s   | j  \}}}|tjkr:t }|| j  | j   |t| j|d  }|| j  | j   t	|dr||j
d k	r||j
S t|jdkrd S |j D ]\}}|dkr|r|qt	|drttjd S )Nr   successr   )r   read_message_beginr]   r`   r   ro   read_message_endr   r   hasattrr   r4   r	   rt   r   MISSING_RESULT)	r#   r   fnamemtypeZrseqidxresultr   r   r   r   r   r      s$    



zTClient._recvc                 C   s(   | j j  | j | jkr$| jj  d S r   )r   r   r   r   r"   r   r   r   r      s    zTClient.close)N)
r   r[   r\   r$   r   r   r   r   r   r   r   r   r   r   r      s   
r   c                   @   s@   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S )
TProcessorz5Base class for processor, which works on two streams.c                 C   s   || _ || _d S r   )r   _handler)r#   r   handlerr   r   r   r$     s    zTProcessor.__init__c                    s   |  \ }} jjkr@|tj |   |ttjd fS t	j d  
| |  t	j d  }fddtjD  fdd} |||fS )Nr   r   c                    s   g | ]} j | d  qS r   r	   r*   r   r
   r   r   rs     s     z)TProcessor.process_in.<locals>.<listcomp>c                     s"   t j } | fddD  S )Nc                 3   s   | ]} j | V  qd S r   rt   r   r   r   r   r,     s     z6TProcessor.process_in.<locals>.call.<locals>.<genexpr>r   r   fr   api_argsr
   r#   r   r   call  s    z#TProcessor.process_in.<locals>.call)r   r   r   skipr   r   r   r   r   r   ro   r   r	   )r#   rn   typeseqidr   r   r   r   r   
process_in  s    
zTProcessor.process_inc                 C   s0   | |tj| || |  |j  d S r   )r   r]   r`   rq   r   r   r   )r#   rp   r   excr   r   r   r   send_exception   s    
zTProcessor.send_exceptionc                 C   s0   | |tj| || |  |j  d S r   )r   r]   r_   rq   r   r   r   )r#   rp   r   r   r   r   r   r   send_result&  s    
zTProcessor.send_resultc                 C   sV   t |jD ]F}|j| d dkr"q
|j| \}}}}t||r
t|||  dS q
dS )Nr   r   TF)r   r	   r   r   )r#   r   r   r   _Zexc_nameZexc_clsr   r   r   handle_exception,  s    
zTProcessor.handle_exceptionc              
   C   s   |  |\}}}}t|tr,| ||||S z| |_W nd tk
rn } z| |||| W Y S d }~X Y n0 tk
r } z| ||s W 5 d }~X Y nX |js| |||| d S r   )	r   r   r   r   r   	Exceptionr   r   r   )r#   rn   rp   r   r   r   r   r   r   r   r   process7  s    
$zTProcessor.processN)
r   r[   r\   __doc__r$   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	TMultiplexedProcessor:c                 C   s
   i | _ d S r   )
processorsr"   r   r   r   r$   M  s    zTMultiplexedProcessor.__init__c                 C   s,   || j krttjd|d|| j |< d S )Nz%processor for `{}` already registered)r   message)r   r   INTERNAL_ERRORr0   )r#   service_name	processorr   r   r   register_processorP  s    
z(TMultiplexedProcessor.register_processorc                    s   |  \ }}|tjtjfkr&tdtj kr8td tj\} || jkr||	t
j |  ttj} ||d fS | j| tj d  | |  tj d  }fddtjD  fdd} |||fS )	Nz1TMultiplexed protocol only supports CALL & ONEWAYzQService name not found in message. You should use TMultiplexedProtocol in client.r   r   c                    s   g | ]} j | d  qS r   r   r   r   r   r   rs   n  s     z4TMultiplexedProcessor.process_in.<locals>.<listcomp>c                     s"   t j } | fddD  S )Nc                 3   s   | ]} j | V  qd S r   r   r   r   r   r   r,   r  s     zATMultiplexedProcessor.process_in.<locals>.call.<locals>.<genexpr>r   r   r   r   r
   procr   r   r   p  s    z.TMultiplexedProcessor.process_in.<locals>.call)r   r]   r^   ra   
TExceptionr   	SEPARATORsplitr   r   r   r   r   r   r   r   r   ro   r   r	   )r#   rn   r   r   r   r   r   r   r   r   r   r   X  s&    




z TMultiplexedProcessor.process_inN)r   r[   r\   r   r$   r   r   r   r   r   r   r   J  s   r   c                   @   s   e Zd Zdd Zdd ZdS )TProcessorFactoryc                 O   s   || _ || _|| _d S r   )r
   r   processor_class)r#   r   r
   r   r   r   r   r$   y  s    zTProcessorFactory.__init__c                 C   s   | j | j| jS r   )r   r
   r   r"   r   r   r   get_processor  s    zTProcessorFactory.get_processorN)r   r[   r\   r$   r   r   r   r   r   r   w  s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )r   z%Base class for all thrift exceptions.c                 C   s   t | S r   idr"   r   r   r   r}     s    zTException.__hash__c                 C   s   t | t |kS r   r   ry   r   r   r   r{     s    zTException.__eq__N)r   r[   r\   r   r}   r{   r   r   r   r   r     s   r   c                   @   s   e Zd ZdddZdd ZdS )TDecodeExceptionNc                 C   s(   || _ || _|| _|| _t||| _d S r   )struct_namefidfieldr   r   	type_repr)r#   r=   r   r   r   r    r!   r   r   r   r$     s
    zTDecodeException.__init__c                 C   s   d| j | j| j| j| jf S )Nz=Field '%s(%s)' of '%s' needs type '%s', but the value is `%r`)r   r   r   r   r   r"   r   r   r   rx     s
    zTDecodeException.__str__)N)r   r[   r\   r$   rx   r   r   r   r   r     s   
r   c                       sh   e Zd ZdZejddfejddfdZdZdZ	dZ
d	Zd
ZdZdZdZedf fdd	Zdd Z  ZS )r   z$Application level thrift exceptions.r   Fr   )r   rA   r   r   rA   rB   rC      rD      Nc                    s   t t|   || _|| _d S r   )re   r   r$   r   r   )r#   r   r   ri   r   r   r$     s    zTApplicationException.__init__c                 C   sd   | j r| j S | j| jkrdS | j| jkr,dS | j| jkr<dS | j| jkrLdS | j| jkr\dS dS d S )NzUnknown methodzInvalid message typezWrong method namezBad sequence IDzMissing resultz'Default (unknown) TApplicationException)r   r   r   INVALID_MESSAGE_TYPEWRONG_METHOD_NAMEBAD_SEQUENCE_IDr   r"   r   r   r   rx     s    zTApplicationException.__str__)r   r[   r\   r   r   rW   rU   r	   UNKNOWNr   r   r   r   r   r   ZPROTOCOL_ERRORr$   rx   rk   r   r   ri   r   r     s   

r   )N)NN)r   
__future__r   r   r6   r(   	itertoolsr   r   r   r@   objectr   r]   r   rb   rl   rm   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s(   
#*	
	UF-
