U kfK @s.ddlmZddlmZddlmZddlmZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z dd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddl m!Z!ddl m"Z"dddd d!d d"d#d$Z#dddd d d%d&d'Z$dddd d d%d(d)Z%dddd d!d d"d*d+Z&dddd d d%d,d-Z'dCdddd d/d d0d1d2Z(dDddd3d3d d d d4d5d6Z)ddd7d7d d8d9d:Z*ddd d d;dd?d3d@dAdBZ,d.S)E) annotations)Optional)Sequence)map_instance_to_supertype)AssignmentStmt)CallExpr) Expression)FuncDef) LambdaExpr) MemberExpr)NameExpr)RefExpr)StrExpr)TypeInfo)Var)SemanticAnalyzerPluginInterface) is_subtype)AnyType) CallableType)get_proper_type)Instance)NoneType) ProperType) TypeOfAny) UnionType)names)utilrrrzOptional[ProperType]r )apistmtnodeleft_hand_explicit_typeinfer_from_right_sidereturncCst|}|dkrdS|tjkr2t|||||}n|tjkrLt||||}nj|tjkrft||||}nP|tjkrt ||||}n6|tj krt |||}n|tj krt ||||}ndS|S)N)rtype_id_for_calleeZMAPPED_infer_type_from_mappedCOLUMN_infer_type_from_decl_columnZ RELATIONSHIP_infer_type_from_relationshipZCOLUMN_PROPERTY%_infer_type_from_decl_column_propertyZSYNONYM_PROPERTY#infer_type_from_left_hand_type_onlyZCOMPOSITE_PROPERTY(_infer_type_from_decl_composite_property)rrr r!r"type_idpython_type_for_typer.I/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/ext/mypy/infer.py#infer_type_from_right_hand_nameexpr(s^       r0)rrr r!r#c Cst|jtst|jjd}d}t|trFt|jtrF|j}t|g}t |jd}t |jd}d} |dk r| |dkr|dkrd} |dk r| t j|g}nt|dks| |dkr|dk rd} t|tr|j}t|trt|jtr|dk rt|j|g}nt|trt|jtr|jjdk r|dk rt|jjtrt|jjj} t| trt| j} t| trt| j|g}nt |d|jd}nr|dk r| |dkr|dk rt |d|j|dk rt|tg}n$|dkrd } t || |j||dkr.t|||S|dk r|| rlt|tsNtt|ts^tt||||St||||Sn|SdS) aInfer the type of mapping from a relationship. E.g.:: @reg.mapped class MyClass: # ... addresses = relationship(Address, uselist=True) order: Mapped["Order"] = relationship("Order") Will resolve in mypy as:: @reg.mapped class MyClass: # ... addresses: Mapped[List[Address]] order: Mapped["Order"] rNZuselistZcollection_classFTz>Expected Python collection type for collection_class parameterzOSending uselist=False and collection_class at the same time does not make sensezCan't infer scalar or collection for ORM mapped expression assigned to attribute '{}' if both 'uselist' and 'collection_class' arguments are absent from the relationship(); please specify a type annotation on the left hand side.) isinstancervaluerAssertionErrorargsr r rrrZget_callexpr_kwargZ parse_bool named_typerZNAMED_TYPE_BUILTINS_LISTcalleer typerrZret_typefailrrformatnamer*3_infer_collection_type_from_left_and_inferred_right(_infer_type_from_left_and_inferred_right) rrr r!target_cls_argr-related_object_typeZ uselist_argZcollection_cls_argZtype_is_a_collectionrtZcallable_ret_typemsgr.r.r/r(Ps                  r(cCs~t|jtst|jjd}d}t|trHt|jtrH|j}t|g}nd}|dkr`t |||S|dk rvt ||||S|SdS)z+Infer the type of mapping from a Composite.rN) r1r2rr3r4r r rrr*r<)rrr r!r=r-r>r.r.r/r+s0   r+cCs&t|jtstt|}t|||S)zVInfer the type of mapping from a right side expression that returns Mapped. )r1r2rr3rZtype_for_calleer*)rrr r!r"Zthe_mapped_typer.r.r/r%s  r%cCst|jtst|jjrV|jjd}t|trVt|j}|tjkrVt |||||dSt|jtrt|jj}|tj krt ||||St |||S)zInfer the type of mapping from a ColumnProperty. This includes mappings against ``column_property()`` as well as the ``deferred()`` function. r)right_hand_expression) r1r2rr3r4rr$r6r&r'ZQUERY_EXPRESSIONr*)rrr r!Zfirst_prop_argr,r.r.r/r)6s6       r)NzOptional[CallExpr])rrr r!rAr#c Cs4t|tstd}|dkr0t|jts*dS|j}|jddD]}t|trjt|jtr|j}|j}qq>t|tt frt|j t r>|}d}qqq>q>t|t frq>q>t|t frq>q>ds>tq>|dkrdSt|j t r$t|j jtjr$t||j |}|dk rt||||St|tgSn t|||SdS)aInfer the type of mapping from a Column. E.g.:: @reg.mapped class MyClass: # ... a = Column(Integer) b = Column("b", String) c: Mapped[int] = Column(Integer) d: bool = Column(Boolean) Will resolve in MyPy as:: @reg.mapped class MyClass: # ... a : Mapped[int] b : Mapped[str] c: Mapped[int] d: Mapped[bool] Nrr.F)r1rr3r2rr4r6r r r r rrr rZ mro_has_idmroZ TYPEENGINE#extract_python_type_from_typeenginer<rrr*) rrr r!rAr6Z column_arg type_argsr-r.r.r/r'gs^&        r'r)rr r!r-orig_left_hand_typeorig_python_type_for_typer#c Csh|dkr |}|dkr|}t||sd|tj|g}d}t|||jt||j t||j ||S)zValidate type when a left hand annotation is present and we also could infer the right hand side:: attrname: SomeType = Column(SomeDBType) NzRLeft hand assignment '{}: {}' not compatible with ORM mapped expression of type {}) rr5rNAMED_TYPE_SQLA_MAPPEDrr8r9r:Z format_typeoptions)rr r!r-rFrGZeffective_typer@r.r.r/r<s*    r<r)rr r!r-r#cCsl|}|}|jr,t|jd}t|jd}n|}|}t|ttfsFtt|ttfsXtt||||||dS)Nr)rFrG)r4rr1rrr3r<)rr r!r-rFrGZ left_hand_argZpython_type_argr.r.r/r;s"r;)rr r!r#cCs@|dkr8d}t|||j||tjttj gS|SdS)zDetermine the type based on explicit annotation only. if no annotation were present, note that we need one there to know the type. NzCan't infer type from ORM mapped expression assigned to attribute '{}'; please specify a Python type or Mapped[] on the left hand side.) rr8r9r:r5rrHrrZ special_form)rr r!r@r.r.r/r*s  r*rzSequence[Expression])rr rEr#cCs|jdkrd|rd|d}t|trVt|jtrV|jjD]}|jdkr4t|jgSq4n|tj gS| dszt d|| d}|dk rt|jtst t t|g|j}t|jdS)Nzsqlalchemy.sql.sqltypes.Enumrz enum.Enumz"sqlalchemy.sql.type_api.TypeEnginez+could not extract Python type from node: %s)fullnamer1r r rrCrr5rZNAMED_TYPE_BUILTINS_STRZhas_baser3Zlookup_fully_qualified_or_nonerrr4)rr rEZ first_argZbase_Ztype_engine_symZ type_enginer.r.r/rD.s2     rD)N)NN)- __future__rtypingrrZ mypy.maptyperZ mypy.nodesrrrr r r r r rrrZ mypy.pluginrZ mypy.subtypesrZ mypy.typesrrrrrrrrrrr0r(r+r%r)r'r<r;r*rDr.r.r.r/sP                           ('  6h*