U
    cc@                     @   s  d Z ddlmZ ddlZddlmZ ddlmZ ddlmZ dd	lm	Z	 dd
l
mZ ddlmZ eeZdd ZdZdZG dd deZG dd deZe e_G dd dej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G dd deeZdS ) z@Path tracking utilities, representing mapper graph traversals.

    )chainN   )base   )exc)
inspection)util)visitors)HasCacheKeyc                 C   s
   t | S N)PathRegistrydeserializepath r   @/tmp/pip-unpacked-wheel-8u86ls_i/sqlalchemy/orm/path_registry.py_unreduce_path   s    r   *Z_sa_defaultc                   @   s  e Zd ZdZdZdZdZdejj	fgZ
dd Zdd Zed	d
 Zdd Zdd Zd6ddZdd Zdd Zedd Zdd Zdd Zdd Zdd Zed d! Zed"d# Zed$d% Zed&d' Zd(d) Zed*d+ Zed,d- Z ed.d/ Z!d0d1 Z"d2d3 Z#d4d5 Z$dS )7r   a  Represent query load paths and registry functions.

    Basically represents structures like:

    (<User mapper>, "orders", <Order mapper>, "items", <Item mapper>)

    These structures are generated by things like
    query options (joinedload(), subqueryload(), etc.) and are
    used to compose keys stored in the query._attributes dictionary
    for various options.

    They are then re-composed at query compile/result row time as
    the query is formed and as rows are fetched, where they again
    serve to compose keys to look up options in the context.attributes
    dictionary, which is copied from query._attributes.

    The path structure has a limited amount of caching, where each
    "root" ultimately pulls from a fixed registry associated with
    the first mapper, that also contains elements for each of its
    property keys.  However paths longer than two elements, which
    are the exception rather than the rule, are generated on an
    as-needed basis.

    r   Fr   c                 C   sD   z|d k	o| j |jkW S  tk
r>   tdt|  Y dS X d S )N1Comparison of PathRegistry to %r is not supportedFr   _path_for_compareAttributeErrorr   warntypeselfotherr   r   r   __eq__C   s    zPathRegistry.__eq__c                 C   sD   z|d kp| j |jkW S  tk
r>   tdt|  Y dS X d S )Nr   Tr   r   r   r   r   __ne__M   s    zPathRegistry.__ne__c                 C   s   | j S r   r   r   r   r   r   r   W   s    zPathRegistry._path_for_comparec                 C   s"   t d|| | |||| jf< d S )Nzset '%s' on path '%s' to '%s')logdebugnatural_pathr   
attributeskeyvaluer   r   r   set[   s    zPathRegistry.setc                 C   s&   t d|| | ||| jf| d S )Nz$setdefault '%s' on path '%s' to '%s')r    r!   
setdefaultr"   r#   r   r   r   r(   _   s    zPathRegistry.setdefaultNc                 C   s"   || j f}||kr|| S |S d S r   )r"   r#   r   r   r   getc   s    
zPathRegistry.getc                 C   s
   t | jS r   lenr   r   r   r   r   __len__j   s    zPathRegistry.__len__c                 C   s   t | S r   )idr   r   r   r   __hash__m   s    zPathRegistry.__hash__c                 C   s
   t | jS r   r*   r   r   r   r   lengthp   s    zPathRegistry.lengthc                 c   s6   | j }tdt|dD ]}|| ||d  fV  qd S )Nr   r   r   )r   ranger+   )r   r   ir   r   r   pairst   s    zPathRegistry.pairsc                    s@    fddt dt jdD D ]}|jr ||r  dS q dS )Nc                    s   g | ]} j | qS r   r   .0r1   r   r   r   
<listcomp>z   s     z0PathRegistry.contains_mapper.<locals>.<listcomp>r   r   TF)r0   r+   r   	is_mapperisa)r   mapperZpath_mapperr   r   r   contains_mappery   s    $zPathRegistry.contains_mapperc                 C   s   || j f|kS r   r   )r   r$   r%   r   r   r   contains   s    zPathRegistry.containsc                 C   s   t |  ffS r   )r   	serializer   r   r   r   
__reduce__   s    zPathRegistry.__reduce__c                    sR   t tdd  fddtdt dD D  fddtdt dD d g S )Nc                 S   s&   g | ]}|j s|jr|jnt|qS r   )r6   is_aliased_classclass_str)r4   mr   r   r   r5      s   z0PathRegistry._serialize_path.<locals>.<listcomp>c                    s   g | ]} | qS r   r   r3   r   r   r   r5      s     r   r   c                    s,   g | ]$} | j r | jn
t | qS r   )Zis_propertyr%   r?   r3   r   r   r   r5      s   r   )listzipr0   r+   )clsr   r   r   r   _serialize_path   s    
zPathRegistry._serialize_pathc                    sL   dd dd  t t fdd|D  }|rH|d d krH|dd }|S )	Nc                 S   s"   | t jkrtj| ddS t j|  S NT)	configure)	PathToken_internorm_base_inspect_mapped_class)mclsr   r   r   _deserialize_mapper_token   s    zAPathRegistry._deserialize_path.<locals>._deserialize_mapper_tokenc                 S   s8   |d krd S |t jkr t j| S tj| ddj| S d S rE   )rG   rH   rI   rJ   attrs)rK   r%   r   r   r   _deserialize_key_token   s    

 z>PathRegistry._deserialize_path.<locals>._deserialize_key_tokenc                    s"   g | ]\}}| ||fqS r   r   )r4   rK   r%   rN   rL   r   r   r5      s   z2PathRegistry._deserialize_path.<locals>.<listcomp>r   )tupler   rC   r   pr   rO   r   _deserialize_path   s    	
zPathRegistry._deserialize_pathc                    s$    fddfdd|  D D S )Nc                    s&   g | ]\\}}}|  |f|fqS r   )rD   r4   r%   r   r&   rC   r   r   r5      s   
z7PathRegistry.serialize_context_dict.<locals>.<listcomp>c                    s.   g | ]&\}}t |tr|d   kr||fqS )r   )
isinstancerQ   )r4   kv)tokensr   r   r5      s   
 )items)rC   Zdict_rZ   r   )rC   rZ   r   serialize_context_dict   s
    

z#PathRegistry.serialize_context_dictc                    s   t  fdd|D S )Nc                 3   s,   | ]$\\}}}|t  |f|fV  qd S r   )rQ   rT   rU   rV   r   r   	<genexpr>   s   
z8PathRegistry.deserialize_context_dict.<locals>.<genexpr>)r   OrderedDict)rC   Z
serializedr   rV   r   deserialize_context_dict   s    z%PathRegistry.deserialize_context_dictc                 C   s   | j }| |S r   )r   rD   )r   r   r   r   r   r;      s    zPathRegistry.serializec                 C   s    |d krd S |  |}| |S r   )rT   coercerR   r   r   r   r      s    
zPathRegistry.deserializec                 C   s"   |j rt| j|S t| j|S d S r   )r6   CachingEntityRegistryrootSlotsEntityRegistry)rC   r8   r   r   r   
per_mapper   s    zPathRegistry.per_mapperc                 C   s   t dd || jS )Nc                 S   s   | | S r   r   prevnextr   r   r   <lambda>       z%PathRegistry.coerce.<locals>.<lambda>)r   reducerb   )rC   rawr   r   r   r`      s    zPathRegistry.coercec                 C   sD   | dt rt| |S | dt r2t| j|S td| d S )N:zinvalid token: %s)endswith_WILDCARD_TOKENTokenRegistry_DEFAULT_TOKENrb   r   ArgumentError)r   tokenr   r   r   rr      s
    
zPathRegistry.tokenc                 C   s   t dd |j| S )Nc                 S   s   | | S r   r   re   r   r   r   rh      ri   z&PathRegistry.__add__.<locals>.<lambda>)r   rj   r   r   r   r   r   __add__   s    zPathRegistry.__add__c                 C   s   d| j j| jf S )Nz%s(%r))	__class____name__r   r   r   r   r   __repr__   s    zPathRegistry.__repr__)N)%ru   
__module____qualname____doc__	__slots__is_tokenis_rootr	   ZExtendedInternalTraversalZdp_has_cache_key_listZ_cache_key_traversalr   r   propertyr   r'   r(   r)   r,   r.   r/   r2   r9   r:   r<   classmethodrD   rT   r\   r_   r;   r   rd   r`   rr   rs   rv   r   r   r   r   r       sN   







#





r   c                   @   s0   e Zd ZdZdZd ZZdZdZdZ	dd Z
dS )RootRegistryzXRoot registry, defers to mappers so that
    paths are maintained per-root-mapper.

    Tr   Fc                 C   s   |t jkrt j| S |jS d S r   )rG   rH   Z_path_registryr   entityr   r   r   __getitem__   s    

zRootRegistry.__getitem__N)ru   rw   rx   ry   inherit_cacher   r"   
has_entityr=   r|   r   r   r   r   r   r      s   r   c                   @   s4   e Zd ZdZi Zdd Zedd Zedd Z	dS )	rG   zcacheable string tokenc                 C   s
   t | fS r   r?   )r   Zanon_mapZ
bindparamsr   r   r   _gen_cache_key  s    zPathToken._gen_cache_keyc                 C   s   d S r   r   r   r   r   r   r     s    zPathToken._path_for_comparec                 C   s.   || j kr| j | S t| | j |< }|S d S r   )rH   rG   )rC   Zstrvalueresultr   r   r   intern  s    

zPathToken.internN)
ru   rw   rx   ry   rH   r   r}   r   r~   r   r   r   r   r   rG     s   
rG   c                   @   s4   e Zd ZdZdZdd ZdZdZdd Zdd	 Z	d
S )ro   )rr   parentr   r"   Tc                 C   s6   t |}|| _|| _|j|f | _|j|f | _d S r   )rG   r   rr   r   r   r"   )r   r   rr   r   r   r   __init__"  s
    
zTokenRegistry.__init__Fc                 c   s   | j js:| j js:| j j D ]}t| j j | | jV  qnF| j jrz| j jjrz| V  | j jj	D ]}t| j j | | jV  q\n| V  d S r   )
r   r=   r|   r8   Ziterate_to_rootro   rr   r   Z_is_with_polymorphicZ_with_polymorphic_entities)r   entr   r   r   generate_for_superclasses.  s    z'TokenRegistry.generate_for_superclassesc                 C   s
   t  d S r   )NotImplementedErrorr   r   r   r   r   <  s    zTokenRegistry.__getitem__N)
ru   rw   rx   rz   r   r   r   r{   r   r   r   r   r   r   ro     s   ro   c                   @   s`   e Zd ZdZdZdd Zdd Zejdd Z	ejd	d
 Z
edd Zedd Zdd ZdS )PropRegistryFTc                 C   s
  t |d }|}|jr|jr0|j|j  }}n|jr|jr|j|jkr|d |j}|j| }|jr||j|j }d| _q|}n2|jr|jr|j|jk	r|j	|jr|j|j }|| _
|| _|j|f | _|j|f | _d|j| j
j f| _| j
j| _d| jf| _d S )NrP   Tloader)r   inspectr=   Z_use_mapper_pathr   Zwith_polymorphic_mappersZ_entity_for_mapperr8   is_unnaturalr7   propr   r"   Z_wildcard_tokenZ_wildcard_path_loader_keyZ_default_path_loader_keyZ_loader_key)r   r   r   ZinspZnatural_parentZsubclass_entityr   r   r   r   D  sH    

 
zPropRegistry.__init__c                 C   s   d dd | jD S )Nz -> c                 s   s   | ]}t |V  qd S r   r   )r4   elemr   r   r   r]     s     z'PropRegistry.__str__.<locals>.<genexpr>)joinr   r   r   r   r   __str__  s    zPropRegistry.__str__c                 C   s   | j jS r   )r   Z_links_to_entityr   r   r   r   r     s    zPropRegistry.has_entityc                 C   s   | j jS r   )r   r   r   r   r   r   r     s    zPropRegistry.entityc                 C   s   | j jS r   )r   r8   r   r   r   r   r8     s    zPropRegistry.mapperc                 C   s
   | | j  S r   )r   r   r   r   r   entity_path  s    zPropRegistry.entity_pathc                 C   s&   t |ttfr| j| S t| |S d S r   )rW   intslicer   rc   r   r   r   r   r     s    
zPropRegistry.__getitem__N)ru   rw   rx   r   r   r   r   r   Zmemoized_propertyr   r   r}   r8   r   r   r   r   r   r   r   @  s   H



r   c                   @   sH   e Zd ZdZdZdd Zedd Zedd Zd	d
 Z	e	Z
dd ZdS )AbstractEntityRegistryr   Tc                 C   s   || _ || _|j| _|| _|j|f | _|jrx| js:|jrx|j|jd jr`|j|jf | _q|j|jd jf | _n| j| _d S )NrP   )	r%   r   r=   r   r   r   r8   r7   r"   )r   r   r   r   r   r   r     s    

zAbstractEntityRegistry.__init__c                 C   s   | S r   r   r   r   r   r   r     s    z"AbstractEntityRegistry.entity_pathc                 C   s   t | jjS r   )r   r   r   r8   r   r   r   r   r8     s    zAbstractEntityRegistry.mapperc                 C   s   dS )NTr   r   r   r   r   __bool__  s    zAbstractEntityRegistry.__bool__c                 C   s@   t |ttfr| j| S |tjkr2t| tj| S t| |S d S r   )rW   r   r   r   rG   rH   ro   r   r   r   r   r   r     s
    

z"AbstractEntityRegistry.__getitem__N)ru   rw   rx   rz   r   r   r}   r   r8   r   __nonzero__r   r   r   r   r   r     s   (

r   c                   @   s   e Zd ZdZdZdS )rc   T)r%   r   r=   r   r   r"   N)ru   rw   rx   r   rz   r   r   r   r   rc     s   rc   c                   @   s    e Zd ZdZdd Zdd ZdS )ra   Tc                 C   s(   t |ttfr| j| S t| |S d S r   )rW   r   r   r   dictr   r   r   r   r   r     s    
z!CachingEntityRegistry.__getitem__c                 C   s   t | | | |< }|S r   )r   )r   r%   itemr   r   r   __missing__  s    z!CachingEntityRegistry.__missing__N)ru   rw   rx   r   r   r   r   r   r   r   ra     s   ra   ) ry   	itertoolsr   logging r   rI   r   r   r   Zsqlr	   Zsql.traversalsr
   	getLoggerru   r    r   rn   rp   r   r   rb   ZInspectionAttrr?   rG   ro   r   r   rc   r   ra   r   r   r   r   <module>   s,   
 R#fC