B
    fv*                 @  s  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! ddl"m#Z# ddl"m$Z$ dd l%m&Z& dd!l%m'Z' d"d#d$d%d&d'd(d)Z(d"d#d%d&d*d+d,Z)d#d-d.d/d/d&d0d1d2Z*d"d#d%d&d*d3d4Z+d#d"d5d5d&d6d7d8Z,d9S ):    )annotations)List)Optional)Union)ARG_NAMED_OPT)Argument)AssignmentStmt)CallExpr)ClassDef)MDEF)
MemberExpr)NameExpr)RefExpr)StrExpr)SymbolTableNode)TempNode)TypeInfo)Var)SemanticAnalyzerPluginInterface)add_method_to_class)AnyType)get_proper_type)Instance)NoneTyp)
ProperType)	TypeOfAny)UnboundType)	UnionType   )infer)util)expr_to_mapped_constructor)NAMED_TYPE_SQLA_MAPPEDr
   r   zUnion[NameExpr, StrExpr]zList[util.SQLAlchemyAttribute]None)clsapiitem
attributesreturnc          	   C  s   t |tr|j}nt |tr$|j}nd S xT| jjD ]0}t |tr2t |jd tr2|jd j|kr2P q2W t	
|d| |  d S |jd krt	
|d| d S t|j}t |tttfst|t	j||j|j|| jd t|||jd |d  d S )Nr   zCan't find mapped attribute zBStatement linked from _mypy_mapped_attrs has no typing information)namelinecolumntypinfo)
isinstancer   r)   r   valuedefsbodyr   lvaluesr    Zfailtyper   r   r   r   AssertionErrorappendZSQLAlchemyAttributer*   r+   r-   apply_type_to_mapped_statement)r$   r%   r&   r'   r)   stmtleft_hand_explicit_type r9   [C:\Users\Lenovo\AppData\Local\Temp\pip-unpacked-wheel-4nia5yor\sqlalchemy\ext\mypy\apply.pyapply_mypy_mapped_attr-   s<    




r;   )r$   r%   r'   r(   c       
   	   C  s  dd |D }d}x| j jD ]}t|trt|jd tr|jd j|krt|jd jtr|jd j}||jd j j	}t
|j	}t|tr|t|ts|t|jtr|t|jjtr|t|jjjtr||jjjjdk	r||jjjjjtkr||jjjdkr|t|jjd tr|t|jjd jtr|t|||||jjd j}	|	dk	r|t|	ts||	}|||jd j _	d}t|j	tr|j	j	jtkr|dk	st|t|g|_	qW |rt| j| dS )zlFor multiple class passes, re-apply our left-hand side types as mypy
    seems to reset them in place.

    c             S  s   i | ]}||j qS r9   )r)   ).0attrr9   r9   r:   
<dictcomp>k   s    z4re_apply_declarative_assignments.<locals>.<dictcomp>Fr   NZ_empty_constructorT)r0   r1   r.   r   r2   r   r)   noder   r3   r   r   rvaluer	   Zcalleer   exprfullnamer"   argsr   r   Z#infer_type_from_right_hand_nameexprr   r4   
named_typer    Zset_mapped_attributesr-   )
r$   r%   r'   Zmapped_attr_lookupZupdate_cls_metadatar7   	left_nodepython_type_for_typeZleft_node_proper_typeZnew_python_type_for_typer9   r9   r:    re_apply_declarative_assignmentsb   sP    	


rG   r   r   zOptional[ProperType])r%   r7   lvaluer8   rF   r(   c             C  s   |j }t|tst|dk	r4d|_| t|g|_n*d|_| t|dkrTtt	j
gn|g|_t|j|_|jdk	r|dk	r||_dS )a  Apply the Mapped[<type>] annotation and right hand object to a
    declarative assignment statement.

    This converts a Python declarative class statement such as::

        class User(Base):
            # ...

            attrname = Column(Integer)

    To one that describes the final Python behavior to Mypy::

        class User(Base):
            # ...

            attrname : Mapped[Optional[int]] = <meaningless temp node>

    NF)r?   r.   r   r4   Zis_inferred_defrD   r"   r3   r   r   special_formr!   r@   )r%   r7   rH   r8   rF   rE   r9   r9   r:   r6      s    
r6   c          	   C  s2  t | |}|dkrdS t |}d|jkr|sdd |D }xV|jdd D ]D}d|jkr^qNt ||}|dkrtqNx|D ]}||j|j	 qzW qNW g }	xF|
 D ]:\}
}|dkrttj}|	tt|
||t|td qW t|| d|	t  d	|jkrt |rt|| d
d	 |s.t|| dd dS )zCApply __init__, __table__ and other attributes to the mapped class.N__init__c             S  s   i | ]}|j |jqS r9   )r3   r)   )r<   r=   r9   r9   r:   r>   
  s    z1add_additional_orm_attributes.<locals>.<dictcomp>r   Z
sqlalchemy)variableZtype_annotationZinitializerkindZ	__table__zsqlalchemy.sql.schema.Tablezsqlalchemy.orm.mapper.MapperZ
__mapper__)r    Zinfo_for_clsZget_is_basenamesmrometadataZget_mapped_attributes
setdefaultr)   r3   itemsr   r   rI   r5   r   r   r   r   r   r   Zget_has_table _apply_placeholder_attr_to_class)r$   r%   r'   r-   is_baseZmapped_attr_namesbaseZbase_cls_attributesr=   	argumentsr)   r,   r9   r9   r:   add_additional_orm_attributes   s>    



rW   str)r%   r$   qualified_nameattrnamer(   c             C  sr   |  |}|r,t|jtstt|jg }n
ttj}t	|}|j
d | |_|j|_||_tt||jj|< d S )N.)Zlookup_fully_qualified_or_noner.   r?   r   r4   r   r   r   rI   r   rB   Z	_fullnamer-   r3   r   r   rN   )r%   r$   rY   rZ   symtype_varr9   r9   r:   rS   0  s    

rS   N)-
__future__r   typingr   r   r   Z
mypy.nodesr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   Zmypy.pluginr   Zmypy.plugins.commonr   Z
mypy.typesr   r   r   r   r   r   r   r    r   r    rN   r!   r"   r;   rG   r6   rW   rS   r9   r9   r9   r:   <module>   sH   5UD5