B
    \++                 @   s  d 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
 dd
l	mZ ddl	mZ ddlmZ e Z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eedd  G dd deZdd ZG dd deZdd  Zd!d" ZdS )#zRoutines to handle the string class registry used by declarative.

This system allows specification of classes and expressions used in
:func:`.relationship` using strings.

    N   )exc)
inspection)util)class_mapper)
interfaces)ColumnProperty)RelationshipProperty)SynonymProperty)_get_table_keyc             C   s   | |j kr6|j |  }t|ts@t||g }|j | < n
||j | < y|j d }W n( tk
rv   tdd |j d< }Y nX |jd}x@|r|d}||}x|D ]}||}qW |	| | qW dS )z^Add a class to the _decl_class_registry associated with the
    given declarative class.

    _sa_module_registryN.r   )
_decl_class_registry
isinstance_MultipleClassMarkerKeyError_ModuleMarker
__module__splitpop
get_module	add_class)Z	classnameclsexistingZroot_moduletokenstokenmodule r   Elib/python3.7/site-packages/sqlalchemy/ext/declarative/clsregistry.pyr   !   s     







r   c               @   s>   e Zd ZdZdZdddZdd Zdd	 Zd
d Zdd Z	dS )r   zRrefers to multiple classes of the same name
    within _decl_class_registry.

    )	on_removecontents__weakref__Nc                s,   | _ t fdd|D  _t  d S )Nc                s   g | ]}t | jqS r   )weakrefref_remove_item).0item)selfr   r   
<listcomp>T   s    z1_MultipleClassMarker.__init__.<locals>.<listcomp>)r   setr    _registriesadd)r'   classesr   r   )r'   r   __init__Q   s    z_MultipleClassMarker.__init__c             C   s   dd | j D S )Nc             s   s   | ]}| V  qd S )Nr   )r%   r#   r   r   r   	<genexpr>Y   s    z0_MultipleClassMarker.__iter__.<locals>.<genexpr>)r    )r'   r   r   r   __iter__X   s    z_MultipleClassMarker.__iter__c             C   sV   t | jdkr*tdd||g  n(t| jd }| }|d krNt||S d S )N   zxMultiple classes found for path "%s" in the registry of this declarative base. Please use a fully module-qualified path.r   r   )lenr    r   InvalidRequestErrorjoinlist	NameError)r'   pathkeyr#   r   r   r   r   attempt_get[   s    z _MultipleClassMarker.attempt_getc             C   s.   | j | | j s*t|  | jr*|   d S )N)r    remover*   discardr   )r'   r#   r   r   r   r$   j   s
    
z!_MultipleClassMarker._remove_itemc             C   sX   t dd dd | jD D }|j|kr>td|j|jf  | jt|| j	 d S )Nc             S   s   g | ]}|d k	r|j qS )N)r   )r%   r   r   r   r   r(   w   s   z1_MultipleClassMarker.add_item.<locals>.<listcomp>c             S   s   g | ]
}| qS r   r   )r%   r#   r   r   r   r(   x   s    zThis declarative base already contains a class with the same class name and module name as %s.%s, and will be replaced in the string-lookup table.)
r)   r    r   r   warn__name__r+   r"   r#   r$   )r'   r&   modulesr   r   r   add_itemq   s    
z_MultipleClassMarker.add_item)N)
r<   r   __qualname____doc__	__slots__r-   r/   r8   r$   r>   r   r   r   r   r   I   s   
r   c               @   sL   e Zd 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 )r   z?"refers to a module name within
    _decl_class_registry.

    )parentnamer    mod_nsr6   r!   c             C   sJ   || _ || _i | _t| | _| j r6| j j| jg | _ng | _t|  d S )N)rB   rC   r    _ModNSrD   r6   r*   r+   )r'   rC   rB   r   r   r   r-      s    
z_ModuleMarker.__init__c             C   s
   || j kS )N)r    )r'   rC   r   r   r   __contains__   s    z_ModuleMarker.__contains__c             C   s
   | j | S )N)r    )r'   rC   r   r   r   __getitem__   s    z_ModuleMarker.__getitem__c             C   s:   | j |d  | j s6| jd k	r6| j| j t|  d S )N)r    r   rB   r$   rC   r*   r:   )r'   rC   r   r   r   r$      s    z_ModuleMarker._remove_itemc             C   s   t | j|S )N)getattrrD   )r'   r7   r   r   r   resolve_attr   s    z_ModuleMarker.resolve_attrc             C   s.   || j kr t|| }|| j |< n
| j | }|S )N)r    r   )r'   rC   Zmarkerr   r   r   r      s
    


z_ModuleMarker.get_modulec                sF    j kr j   }|| n"t|g fddd }j  < d S )Nc                  s
     S )N)r$   r   )rC   r'   r   r   <lambda>   s    z)_ModuleMarker.add_class.<locals>.<lambda>)r   )r    r>   r   )r'   rC   r   r   r   )rC   r'   r   r      s
    

z_ModuleMarker.add_classN)r<   r   r?   r@   rA   r-   rF   rG   r$   rI   r   r   r   r   r   r   r      s   r   c               @   s    e Zd ZdZdd Zdd ZdS )rE   )Z__parentc             C   s
   || _ d S )N)_ModNS__parent)r'   rB   r   r   r   r-      s    z_ModNS.__init__c             C   st   y| j j| }W n tk
r$   Y n8X |d k	r\t|tr>|jS t|tsLt|| j j	|S t
d| j j|f d S )Nz<Module %r has no mapped classes registered under the name %r)rK   r    r   r   r   rD   r   AssertionErrorr8   r6   AttributeErrorrC   )r'   r7   valuer   r   r   __getattr__   s    
z_ModNS.__getattr__N)r<   r   r?   rA   r-   rO   r   r   r   r   rE      s   rE   c               @   s    e Zd ZdZdd Zdd ZdS )_GetColumns)r   c             C   s
   || _ d S )N)r   )r'   r   r   r   r   r-      s    z_GetColumns.__init__c             C   s   t | jdd}|rv||jkr0td| j|f |j| }|jtjkrv|j}t	|t
r^|j}nt	|tsvtd| t| j|S )NF)Z	configurez/Class %r does not have a mapped column named %rzaProperty %r is not an instance of ColumnProperty (i.e. does not correspond directly to a Column).)r   r   Zall_orm_descriptorsr   r2   Zextension_typer   ZNOT_EXTENSIONpropertyr   r
   rC   r   rH   )r'   r7   ZmpZdescpropr   r   r   rO      s     



z_GetColumns.__getattr__N)r<   r   r?   rA   r-   rO   r   r   r   r   rP      s   rP   c             C   s   t | jS )N)r   inspectr   )targetr   r   r   rJ      s    rJ   c               @   s    e Zd ZdZdd Zdd ZdS )	_GetTable)r7   metadatac             C   s   || _ || _d S )N)r7   rV   )r'   r7   rV   r   r   r   r-      s    z_GetTable.__init__c             C   s   | j jt|| j S )N)rV   tablesr   r7   )r'   r7   r   r   r   rO      s    z_GetTable.__getattr__N)r<   r   r?   rA   r-   rO   r   r   r   r   rU      s   rU   c             C   s   t |tr|g | }t|S )N)r   r   r8   rP   )r7   rN   r   r   r   _determine_container   s    
rX   c               @   s$   e Zd Zdd Zdd Zdd ZdS )_class_resolverc             C   s6   || _ || _| | _| _|| _t| j| _d| _	d S )Nr   )
r   rR   argZ_declarative_argfallbackr   ZPopulateDict_access_cls_dict
_resolvers)r'   r   rR   r[   rZ   r   r   r   r-     s    z_class_resolver.__init__c             C   s   | j }||jkr t||j| S ||jjkr8|jj| S ||jjkrPt||jS d|jkr|||jd kr||jd }||S | jrx"| jD ]}||}|d k	r|S qW | j	| S )Nr   )
r   r   rX   rV   rW   Z_schemasrU   rI   r^   r[   )r'   r7   r   registryZresolvrN   r   r   r   r\     s"    



z_class_resolver._access_clsc          
   C   sv   y*t | jt | j}t|tr$|jS |S W nF tk
rp } z(t	d| j
j| j|jd | jf W d d }~X Y nX d S )NzWhen initializing mapper %s, expression %r failed to locate a name (%r). If this is a class name, consider adding this relationship() to the %r class after both dependent classes have been defined.r   )evalrZ   globalsr]   r   rP   r   r5   r   r2   rR   rB   args)r'   xnr   r   r   __call__$  s    
z_class_resolver.__call__N)r<   r   r?   r-   r\   re   r   r   r   r   rY     s   rY   c                sF   dd l }ddlm}m} |j ||d  fdd}|S )Nr   )foreignremotec                s   t  | S )N)rY   )rZ   )r   r[   rR   r   r   resolve_arg=  s    z_resolver.<locals>.resolve_arg)
sqlalchemyZsqlalchemy.ormrf   rg   __dict__copyupdate)r   rR   ri   rf   rg   rh   r   )r   r[   rR   r   	_resolver6  s    
rm   c             C   s   t |trt| |}x2dD ]*}t||}t |tjrt|||| qW |jrt |jtr|j\}}x4dD ],}||krjt || tjrj||| ||< qjW |S )N)Zargumentorder_byprimaryjoinsecondaryjoin	secondaryZ_user_defined_foreign_keysremote_side)ro   rp   rq   Zforeign_keysrr   rn   )	r   r	   rm   rH   r   Zstring_typessetattrZbackreftuple)r   rR   rh   attrvr7   kwargsr   r   r   _deferred_relationshipC  s    




rx   )r@   r"    r   r   r   Zormr   r   Zorm.propertiesr   r	   r
   Zschemar   r)   r*   r   objectr   r   rE   rP   Z	_inspectsrU   rX   rY   rm   rx   r   r   r   r   <module>   s.   (=4
1