U
    H4fod                     @   s.  d Z ddlZddlZddlZddlZddlmZmZmZ ej	dkrPddl
mZ nddlmZ ddlmZ ddlmZmZ dd	lmZmZ dd
lmZmZ ddlmZ ddlmZmZmZmZ ddddg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$G dd de"Z%G dd de Z&dS )a@  
zeep.xsd.elements.indicators
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Indicators are a collection of elements. There are four available, these are
All, Choice, Group and Sequence.

    Indicator -> OrderIndicator -> All
                                -> Choice
                                -> Sequence
              -> Group

    N)OrderedDictdefaultdictdeque)      )cached_property)threaded_cached_property)etree)UnexpectedElementErrorValidationError)NotSet	SkipValue)AnyElement)Base)NamePrefixGeneratorUniqueNameGeneratorcreate_prefixed_namemax_occurs_iterAllChoiceGroupSequencec                       sB   e Zd ZdZ fddZedd Zedd Zdd	d
Z  Z	S )	Indicatorz#Base class for the other indicatorsc                    s   d| j jt  f S )Nz<%s(%s)>)	__class____name__super__repr__selfr    @/tmp/pip-unpacked-wheel-04z2hmy8/zeep/xsd/elements/indicators.pyr   ,   s    zIndicator.__repr__c                 C   s&   t dd | jD }| jr"d|iS |S )Nc                 S   s   g | ]\}}||j fqS r!   )default_value).0nameelementr!   r!   r"   
<listcomp>2   s     z+Indicator.default_value.<locals>.<listcomp>_value_1)r   elementsaccepts_multipler   valuesr!   r!   r"   r#   /   s    zIndicator.default_valuec                 C   s
   t  d S NNotImplementedErrorr   r!   r!   r"   r)   9   s    zIndicator.elements   c                 C   s
   t  d S r-   r.   r   r%   
min_occurs
max_occursr!   r!   r"   clone=   s    zIndicator.clone)r0   r0   )
r   
__module____qualname____doc__r   propertyr#   r)   r4   __classcell__r!   r!   r    r"   r   )   s   
	
r   c                       s   e Zd ZdZdZd fdd	ZdddZedd	 Zed
d Z	dd Z
dddZdd Zdd Zdd Zdd ZdddZ  ZS ) OrderIndicatorz0Base class for All, Choice and Sequence classes.Nr0   c                    s,   || _ || _t   |d k	r(| | d S r-   )r2   r3   r   __init__extend)r   r)   r2   r3   r    r!   r"   r;   F   s
    
zOrderIndicator.__init__c                 C   s   | j t| ||dS )N)r)   r2   r3   )r   listr1   r!   r!   r"   r4   M   s
      zOrderIndicator.clonec                 C   s<   g }| j D ],\}}|dkr(||j q
|||f q
|S z:List of tuples containing the element name and the elementN)elements_nestedr<   r)   append)r   resultr%   elmr!   r!   r"   r)   R   s    zOrderIndicator.elementsc                 C   s   g }t  }t }| D ]}t|ttttfrn|jrD||	 |f q|j
D ]\}}||}qJ|d|f qt|ttfr||	 |f q||j}|||f q|S r>   )r   r   
isinstancer   r   r   r   r*   r@   get_namer)   Zcreate_namer   	attr_name)r   rA   	generatorZgenerator_2rB   sub_nameZsub_elmr%   r!   r!   r"   r?   ]   s    zOrderIndicator.elements_nestedc                 C   s|   | j s|g}t }|D ]\}d}| jD ]B\}}t|trX|j|krf||j dk	rf|d7 }q$|||7 }q$|| qt|S )Return the number of values which are accepted by this choice.

        If not all required elements are available then 0 is returned.

        r   Nr0   )	r*   setr?   rC   r   r%   acceptaddmax)r   r,   resultsvaluenumr%   r&   r!   r!   r"   rJ   s   s    

zOrderIndicator.acceptr   c                 C   sd   | j D ]\}}t|trtdqi }| jD ],\}}|t|krD qZ|| ||< |d7 }q,|||fS )N0Choice elements only work with keyword argumentsr0   )r?   rC   r   	TypeErrorr)   len)r   argsindexr%   rB   rA   r&   r!   r!   r"   
parse_args   s    


zOrderIndicator.parse_argsc              	   C   sT  | j r|st|r
||kr i S | j s*t||}t|tsD|g}g }t| j|D ]}zt| }W n t	k
r   t
dY nX t }| jD ](\}}	|	|||}
|
dk	r||
 q|rt
d| t|d f || qT||i}ttd|s|| |S | j rtt }| jD ](\}}	|	|||}|r"|| q"|S dS )a  Apply the given kwarg to the element.

        The available_kwargs is modified in-place. Returns a dict with the
        result.

        :param kwargs: The kwargs
        :type kwargs: dict
        :param name: The name as which this type is registered in the parent
        :type name: str
        :param available_kwargs: The kwargs keys which are still available,
         modified in place
        :type available_kwargs: set
        :rtype: dict

        z3A list of dicts is expected for unbounded SequencesN+%s() got an unexpected keyword argument %r.r   )r*   AssertionErrorgetrC   r=   r   r3   rI   keysAttributeErrorrQ   r   r)   parse_kwargsupdater@   anyfilterremover?   )r   kwargsr%   available_kwargsitem_kwargsrA   Z
item_value	subresultZ	item_namer&   rN   elm_name
sub_resultr!   r!   r"   r[      sP    




zOrderIndicator.parse_kwargsc                 C   s"   t | D ]\}}| | |< q| S r-   )	enumerateresolve)r   irB   r!   r!   r"   rg      s    zOrderIndicator.resolvec           	      C   s   t |ts|g}n|}| || t| j|D ]l}| jD ]`\}}|rj||kr`|| }||g }qrt}|}n|}|}|tkr|q8|dk	s|js8|	||| q8q.dS )z.Create subelements in the given parent object.N)
rC   r=   validater   r3   r?   r   r   is_optionalrender)	r   parentrN   render_pathr,   r%   r&   Zelement_valueZ
child_pathr!   r!   r"   rk      s$    
zOrderIndicator.renderc                 C   s"   |D ]}|t krtd|dqd S )NzNo value setpath)r   r   )r   rN   rm   itemr!   r!   r"   ri     s    zOrderIndicator.validateTc                 C   sr   g }| j D ]H\}}t|tr2||j|dd q
|j|dd}|d||f  q
d|}| jrnd|f S |S )NF
standalonez%s: %sz, z[%s])r?   rC   r   r@   	signaturejoinr*   )r   schemarr   partsr%   r&   rN   partr!   r!   r"   rs     s    


zOrderIndicator.signature)Nr0   r0   )r0   r0   )r   )NT)r   r5   r6   r7   r%   r;   r4   r   r)   r?   rJ   rU   r[   rg   rk   ri   rs   r9   r!   r!   r    r"   r:   A   s   




Gr:   c                       s,   e Zd ZdZd	 fdd	Zd
ddZ  ZS )r   zlAllows the elements in the group to appear (or not appear) in any order
    in the containing element.

    Nr0   Fc                    s   t  ||| || _d S r-   )r   r;   _consume_other)r   r)   r2   r3   Zconsume_otherr    r!   r"   r;     s    zAll.__init__c                 C   s   t  }dd | jD }t }tt}t|D ],\}	}
|
j|kr,||	 ||
j |
 q,t	|ddD ]
}	||	= qf| jD ],\}}|
|j}|rx|j|||d||< qx| jr|rt||d< |  |S )  Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        c                 S   s   h | ]\}}|j qS r!   )qname)r$   __r&   r!   r!   r"   	<setcomp>0  s     z(All.parse_xmlelements.<locals>.<setcomp>T)reversecontextZ_raw_elements)r   r)   rI   r   r   rf   tagrK   r@   sortedrX   rz   parse_xmlelementsrx   r=   clear)r   xmlelementsru   r%   r   rA   Zexpected_tagsZconsumed_tagsr,   rh   rB   r&   Zsub_elementsr!   r!   r"   r   !  s,    

  
zAll.parse_xmlelements)Nr0   r0   F)NN)r   r5   r6   r7   r;   r   r9   r!   r!   r    r"   r     s   c                   @   sn   e Zd ZdZdddZedd Zedd Zdd
dZdd Z	dd Z
dd Zdd Zdd ZdddZd	S )r   z@Permits one and only one of the elements contained in the group.r   c                 C   s   |rt dd S )NrP   )rQ   r   rS   rT   r!   r!   r"   rU   M  s    zChoice.parse_argsc                 C   s   dS )NTr!   r   r!   r!   r"   rj   Q  s    zChoice.is_optionalc                 C   s   t  S r-   )r   r   r!   r!   r"   r#   U  s    zChoice.default_valueNc              
   C   s   g }t | jD ]}|s qg }| jD ]v\}}	t|}
z|	j|
|||d}W n tk
rd   Y q$Y nX t|	trx||i}t|t|
 }|r$|	||f q$|sg } qt
|tddd}|r|	|d d  t|d d D ]}|  qq qq| jr
||i}n|r|d ni }|S )ry   )r   ru   r%   r   r   Tkeyr}   r0   )r   r3   r?   copyr   r
   rC   r   rR   r@   r   operator
itemgetterrangepopleftr*   )r   r   ru   r%   r   rA   _unusedoptionsZelement_namer&   Zlocal_xmlelementsre   Znum_consumedrh   r!   r!   r"   r   Y  sD    




zChoice.parse_xmlelementsc                 C   s  |r||kr| j st|| p g }|| g }t|tr@|g}|D ]}| D ]}t|tr||krj|| n|}||r||  qDqLt|tr||  qDqL|j	|krL|
|j	}||j	|i  qDqLtd||  f qD| j s|r|d nd}n| j ri S i }d}	| jD ]j\}}
t|}|
|||}|rt| s`|| || n|	s|| || d}	q|	r| jD ]\}}
||d qni }|r| j r||i}|S )a  Processes the kwargs for this choice element.

        Returns a dict containing the values found.

        This handles two distinct initialization methods:

        1. Passing the choice elements directly to the kwargs (unnested)
        2. Passing the choice elements into the `name` kwarg (_value_1) (nested).
           This case is required when multiple choice elements are given.

        :param name: Name of the choice element (_value_1)
        :type name: str
        :param element: Choice element object
        :type element: zeep.xsd.Choice
        :param kwargs: dict (or list of dicts) of kwargs for initialization
        :type kwargs: list / dict

        zJNo complete xsd:Sequence found for the xsd:Choice %r.
The signature is: %sr   NFT)r*   rW   r_   rC   dictr:   rJ   r@   r   r%   rX   rQ   rs   r?   r   r[   r]   r,   intersection_updater\   r)   
setdefault)r   r`   r%   ra   r,   rA   rN   r&   choice_valuefoundchoiceZtemp_kwargsrc   Zchoice_namer!   r!   r"   r[     sd    













zChoice.parse_kwargsc                 C   sJ   | j s|g}| || |D ](}| |}|r|\}}|||| qdS )zRender the value to the parent element tree node.

        This is a bit more complex then the order render methods since we need
        to search for the best matching choice element.

        N)r*   ri   _find_element_to_renderrk   )r   rl   rN   rm   rp   rA   r&   r   r!   r!   r"   rk     s    
zChoice.renderc                 C   s>   d}|D ]}|  |}|r|d7 }q|s:| js:td|dd S )Nr   r0   zMissing choice valuesrn   )r   rj   r   )r   rN   rm   r   rp   rA   r!   r!   r"   ri     s    


zChoice.validatec                    s   t  }| jD ]j\ }t|trb| jrFt fdd|D r`|d qv |krv|  rv|d q||}|| q|rt|S dS )rH   c                 3   s   | ]} |ko|  V  qd S r-   r!   )r$   rp   r%   r!   r"   	<genexpr>  s     z Choice.accept.<locals>.<genexpr>r0   r   )	rI   r?   rC   r   r*   allrK   rJ   rL   )r   r,   numsr&   rO   r!   r   r"   rJ     s    

zChoice.acceptc              
   C   s   g }| j D ]\}}t|trh|j|krz||j }W n tk
rL   |}Y nX |dk	r|d||f q
|dk	rz|| }W q ttfk
r   |}Y qX n|}||}|r
||||f q
|rt|t	
ddd}|d dd S dS )zReturn a tuple (element, value) for the best matching choice.

        This is used to decide which choice child is best suitable for
        rendering the available data.

        Nr0   r   Tr   )r?   rC   r   r%   KeyErrorr@   rQ   rJ   r   r   r   )r   rN   matchesr%   r&   r   Zscorer!   r!   r"   r     s,    



zChoice._find_element_to_renderTc              	   C   sv   g }| j D ]H\}}t|tr6|d|j|dd  q
|d||j|ddf  q
dd| }| jrrd|f S |S )Nz{%s}Frq   z{%s: %s}z(%s)z | z%s[])r?   rC   r:   r@   rs   rt   r*   )r   ru   rr   rv   r%   r&   rw   r!   r!   r"   rs   ?  s    

zChoice.signature)r   )NN)NT)r   r5   r6   r7   rU   r8   rj   r#   r   r[   rk   ri   rJ   r   rs   r!   r!   r!   r"   r   J  s   



>T
$c                   @   s   e Zd ZdZdddZdS )r   zoRequires the elements in the group to appear in the specified sequence
    within the containing element.

    Nc              
   C   s   g }| j r|stt| jD ]}|s( qt }| jD ]h\}}	z|	j||||d}
W n" tk
rt   |jj	rl d}
Y nX t
|	tr||
 n|
||< |s4 qq4|r|| q| j s|r|d S dS ||iS )ry   r~   Nr   )r*   rW   r   r3   r   r)   r   r
   settingsstrictrC   r:   r\   r@   )r   r   ru   r%   r   rA   r   Zitem_resultrd   r&   Zitem_subresultr!   r!   r"   r   T  s:       


zSequence.parse_xmlelements)NN)r   r5   r6   r7   r   r!   r!   r!   r"   r   N  s   c                       s   e Zd ZdZd fdd	Zdd Zdd Zed	d
 ZdddZ	dd Z
d ddZdd Zd!ddZdd Zdd Zd"ddZ  ZS )#r   zyGroups a set of element declarations so that they can be incorporated as
    a group into complex type definitions.

    r0   c                    s6   t    || _|| _|r |jnd | _|| _|| _d S r-   )r   r;   childrz   	localnamer%   r3   r2   )r   r%   r   r3   r2   r    r!   r"   r;     s    
zGroup.__init__c                 C   s   |   S r-   )rs   r   r!   r!   r"   __str__  s    zGroup.__str__c                 o   s   | j D ]
}|V  qd S r-   )r   )r   rS   r`   rp   r!   r!   r"   __iter__  s    
zGroup.__iter__c                 C   s   | j rd| jfgS | jjS )Nr(   )r*   r   r)   r   r!   r!   r"   r)     s    zGroup.elementsc                 C   s   | j d | j||dS )N)r%   r   r2   r3   )r   r   r1   r!   r!   r"   r4     s       zGroup.clonec                 C   s   | j |S )rH   )r   rJ   r+   r!   r!   r"   rJ     s    zGroup.acceptr   c                 C   s   | j ||S r-   )r   rU   r   r!   r!   r"   rU     s    zGroup.parse_argsc           
      C   s   | j r||kri S || || }g }| jj r4dnd }t| j|D ]J}t| }| j|||}	|rtd| t	|d f |	rD|
|	 qD|r||i}n| j|||}|S )Nr(   rV   r   )r*   r_   r   r   r3   rI   rY   r[   rQ   r=   r@   )
r   r`   r%   ra   rb   rA   rG   Z
sub_kwargsZavailable_sub_kwargsrc   r!   r!   r"   r[     s4    
  
zGroup.parse_kwargsNc              	   C   sP   g }t | jD ]&}|| jj||||d |s q6q| jsH|rH|d S ||iS )ry   r~   r   )r   r3   r@   r   r   r*   )r   r   ru   r%   r   rA   r   r!   r!   r"   r     s    
zGroup.parse_xmlelementsc                 C   s4   t |ts|g}n|}|D ]}| j||| qd S r-   )rC   r=   r   rk   )r   rl   rN   rm   r,   r!   r!   r"   rk     s
    
zGroup.renderc                 C   s   | j  | _ | S r-   )r   rg   r   r!   r!   r"   rg     s    zGroup.resolveTc                 C   s<   t | j|}|r(d|| jj|ddf S | jj|ddS d S )Nz%s(%s)Frq   )r   rz   r   rs   )r   ru   rr   r%   r!   r!   r"   rs     s    zGroup.signature)r0   r0   )r0   r0   )r   )NN)NT)r   r5   r6   r7   r;   r   r   r   r)   r4   rJ   rU   r[   r   rk   rg   rs   r9   r!   r!   r    r"   r     s   



	)'r7   r   r   systypingcollectionsr   r   r   version_info	functoolsr   r   lxmlr	   Zzeep.exceptionsr
   r   Zzeep.xsd.constr   r   Zzeep.xsd.elementsr   r   Zzeep.xsd.elements.baser   Zzeep.xsd.utilsr   r   r   r   __all__r   r=   r:   r   r   r   r   r!   r!   r!   r"   <module>   s0   
 W3  8