U
    cc$                     @   s&  d 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 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 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" ddl m#Z# G dd deZ$e%ee$ d d!d"Z&ed#d$d%d&Z'ed#d$d'd(Z(ed#d$d)d*Z)ed#d$d+d,Z*ed#d$d-d.Z+ed#d$d/d0Z,ed#d$d1d2Z-eed$d3d4Z.eeef d#d$d5d6Z/eed#d7d8d9Z0d#S ):z"
Mypy plugin for SQLAlchemy ORM.

    )Callable)List)Optional)Tuple)Type)Union)nodes)calculate_mro)MroError)Block)ClassDef)GDEF)MypyFile)NameExpr)SymbolTable)SymbolTableNode)TypeInfo)AttributeContext)ClassDefContext)DynamicClassDefContext)Plugin)SemanticAnalyzerPluginInterface)get_proper_type)Instance   )
decl_class)names)utilc                   @   s   e Zd Zeeeegdf  dddZeeeegdf  dddZ	eeeegdf  dddZ
eeeegdf  dd	d
Zeeeegdf  dddZeeeegef  dddZeeeeeef  dddZdS )SQLAlchemyPluginN)fullnamereturnc                 C   s   t |t jkrtS d S N)r   type_id_for_fullnameZDECLARATIVE_BASE_dynamic_class_hookselfr    r&   >/tmp/pip-unpacked-wheel-8u86ls_i/sqlalchemy/ext/mypy/plugin.pyget_dynamic_class_hook-   s    z'SQLAlchemyPlugin.get_dynamic_class_hookc                 C   s   t S r!   )_fill_in_decoratorsr$   r&   r&   r'   get_customize_class_mro_hook4   s    z-SQLAlchemyPlugin.get_customize_class_mro_hookc                 C   s\   |  |}|d k	rX|jd k	rXt|j}|tjkr6tS |tjtjfkrJtS |tj	krXt
S d S r!   )lookup_fully_qualifiednoder   type_id_for_named_nodeZMAPPED_DECORATOR_cls_decorator_hookZAS_DECLARATIVEZAS_DECLARATIVE_BASE_base_cls_decorator_hookZDECLARATIVE_MIXIN_declarative_mixin_hook)r%   r   symZtype_idr&   r&   r'   get_class_decorator_hook9   s    


z)SQLAlchemyPlugin.get_class_decorator_hookc                 C   s   t |t jkrtS d S r!   )r   r"   ZDECLARATIVE_META_metaclass_cls_hookr$   r&   r&   r'   get_metaclass_hookM   s    z#SQLAlchemyPlugin.get_metaclass_hookc                 C   s.   |  |}|r*t|jtr*t|jr*tS d S r!   )r+   
isinstancer,   r   r   Zhas_declarative_base_base_cls_hook)r%   r   r1   r&   r&   r'   get_base_class_hookW   s    


z$SQLAlchemyPlugin.get_base_class_hookc                 C   s   | drtS d S )Nz-sqlalchemy.orm.attributes.QueryableAttribute.)
startswith_queryable_getattr_hookr$   r&   r&   r'   get_attribute_hooke   s
    z#SQLAlchemyPlugin.get_attribute_hook)filer    c                 C   s   ddgS )N)
   sqlalchemy.orm.attributes)r<   zsqlalchemy.orm.decl_apir>   r&   )r%   r;   r&   r&   r'   get_additional_depso   s    z$SQLAlchemyPlugin.get_additional_deps)__name__
__module____qualname__strr   r   r   r(   r   r*   r2   r4   r7   r   r   r:   r   r   r   intr?   r&   r&   r&   r'   r   ,   s*   r   )versionr    c                 C   s   t S r!   )r   )rE   r&   r&   r'   pluginx   s    rF   N)ctxr    c                 C   s4  t |  t| jtg }| j| j|_tt || jj	}||_
t| j| tj| jdtfd}|dk	rt|jtrt|j tj|jj| jdd t|jg g|_n| jtj}|g|_zt| W nD tk
r   t| jd| j | jtj}|g|_d|_Y nX | j| jt t!| t| dS )zZGenerate a declarative Base class when the declarative_base() function
    is encountered.cls)Z
expr_typesNTZis_mixin_scanz.Not able to calculate MRO for declarative base)"_add_globalsr   namer   apiZqualified_namer   r   r   Z
cur_mod_idinfo_set_declarative_metaclassr   Zget_callexpr_kwargcallr   r5   r,   set_is_baser   ,scan_declarative_assignments_and_apply_typesZdefnr   basesZ
named_typer   ZNAMED_TYPE_BUILTINS_OBJECTr	   r
   failZfallback_to_anyZadd_symbol_table_noder   r   )rG   rH   rM   Zcls_argobjr&   r&   r'   r#   |   s<        r#   c                 C   s   | j jD ]}t|tjr:t|jtjr:|jjdkr:|j}nt|tjr|jdkr|}nqt|jt	sht
| jj|jj|dd}|r|jrt|j}t|tr|jj d|j |_qt| jd|j |j qd S )NZas_declarative_baseZmappedT)Zsuppress_errors.zClass decorator called %s(), but we can't tell if it's from an ORM registry.  Please annotate the registry assignment, e.g. my_registry: registry = registry())rH   Z
decoratorsr5   r   ZCallExprZcallee
MemberExprrK   exprr   AssertionErrorrL   Zlookup_qualifiedr,   r   typer   r   r   rS   )rG   	decoratortargetr1   Zsym_typer&   r&   r'   r)      s>    



  



r)   c                 C   s   t |  t| jtjst| jj}t|tjr<t|jtj	s@tt
|jj}t|trht|jtjksltt| j| j d S r!   )rJ   r5   reasonr   rV   rX   rW   ZRefExprr,   ZVarr   rY   r   r   r-   ZREGISTRYr   rQ   rH   rL   )rG   rW   Z	node_typer&   r&   r'   r.      s    r.   c                 C   s>   t |  | j}t| j| t| jj tj|| jdd d S NTrI   )	rJ   rH   rN   rL   r   rP   rM   r   rQ   )rG   rH   r&   r&   r'   r/      s      r/   c                 C   s.   t |  t| jj tj| j| jdd d S r]   )rJ   r   rP   rH   rM   r   rQ   rL   rG   r&   r&   r'   r0      s      r0   c                 C   s   t | jj d S r!   )r   rP   rH   rM   r^   r&   r&   r'   r3      s    r3   c                 C   s   t |  t| j| j d S r!   )rJ   r   rQ   rH   rL   r^   r&   r&   r'   r6      s    r6   c                 C   s   | j S r!   )Zdefault_attr_typer^   r&   r&   r'   r9     s    r9   c                 C   s   t | ddd dS )z`Add __sa_DeclarativeMeta and __sa_Mapped symbol to the global space
    for all class defs

    r=   ZMappedZ__sa_MappedN)r   Z
add_globalr^   r&   r&   r'   rJ     s    rJ   )rL   
target_clsr    c                 C   s@   |j }| d}|d k	r$t|jts(tt|jg  |_|_d S )Nz'sqlalchemy.orm.decl_api.DeclarativeMeta)	rM   Zlookup_fully_qualified_or_noner5   r,   r   rX   r   Zdeclared_metaclassZmetaclass_type)rL   r_   rM   r1   r&   r&   r'   rN     s    rN   )1__doc__typingr   r   r   r   r   Z
TypingTyper   Zmypyr   Zmypy.mror	   r
   Z
mypy.nodesr   r   r   r   r   r   r   r   Zmypy.pluginr   r   r   r   r   Z
mypy.typesr   r    r   r   r   r   rC   rF   r#   r)   r.   r/   r0   r3   r6   r9   rJ   rN   r&   r&   r&   r'   <module>   sV   L'3
 