ML i dZddlmZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZmZmZddlmZddlmZmZdd lmZdd lmZmZdd lmZdd lmZdd lm Z ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ddl0m1Z1ddl2m3Z3m4Z4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;ddlZ>ddl?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPddlQmRZRmSZSddlTmUZUGddeZVGdde ZWGdde5ZXGdde;ZYdd&Z_d?d'Z`d@d(ZaGd)d*ZbdAd+ZcdBd,ZddCd-ZeGd.d/eKZfed0eG1ZgdDd2ZhGd3d4eLZidEd5ZjdFd6ZkdGd7ZldHd8ZmdId9Zned:ZodJd;Zpy)KaMechanisms for inferring function types based on callsites. Currently works by collecting all argument types at callsites, synthesizing a list of possible function types from that, trying them all, and picking the one with the fewest errors that we think is the "best". Can return JSON that pyannotate can use to apply the annotations to code. There are a bunch of TODOs here: * Maybe want a way to surface the choices not selected?? * We can generate an exponential number of type suggestions, and probably want a way to not always need to check them all. * Our heuristics for what types to try are primitive and not yet supported by real practice. * More! Other things: * This is super brute force. Could we integrate with the typechecker more to understand more about what is going on? * Like something with tracking constraints/unification variables? * No understanding of type variables at *all* ) annotationsN)Iterator)contextmanager)Callable NamedTuple TypedDictTypeVarcast)map_actuals_to_formals)GraphState has_any_type)InvalidSourceList SourceFinder)join_type_list)meet_type_list)PYTHON_EXTENSIONS)ARG_STAR ARG_STAR2ArgKindCallExpr Decorator ExpressionFuncDefMypyFileRefExpr ReturnStmt SymbolNode SymbolTableTypeInfoVar)Options)FunctionContext MethodContextPlugin)FineGrainedBuildManager)state)TraverserVisitor) bind_selfmake_simplified_union)AnyType CallableType FunctionLikeInstanceNoneType ProperType TupleTypeType TypeAliasType TypedDictType TypeOfAnyTypeStrVisitorTypeTranslator TypeVarTypeUninhabitedType UnionTypeget_proper_type)is_overlapping_noneremove_optional) split_targetc"eZdZUded<ded<y)PyAnnotateSignaturestr return_type list[str] arg_typesN__name__ __module__ __qualname____annotations__V/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/mypy/suggestions.pyrArAWsrLrAcJeZdZUded<ded<ded<ded<d ed <d ed <y )CallsiterBpathintlinelist[list[ArgKind]] arg_kindszlist[str | None]callee_arg_nameslist[list[str | None]] arg_nameslist[list[Type]]rENrFrKrLrMrOrO\s$ I I""&&%%rLrOc0eZdZdZddZddZd dZd dZy) SuggestionPluginz0Plugin that records all calls to a given target.cl|jdr|jddd}||_g|_y)N)z.__new__z .__init__.r)endswithrsplittarget mystery_hits)selfr`s rM__init__zSuggestionPlugin.__init__hs5 ??4 5]]3*1-F -/rLc:||jk(r |jSyNr`logrbfullnames rMget_function_hookz"SuggestionPlugin.get_function_hookq t{{ "88OrLc:||jk(r |jSyrerfrhs rMget_method_hookz SuggestionPlugin.get_method_hookwrkrLc  |jjt|jj|j j |j|j|j|j|jSre) raappendrOapirPcontextrRrTrUrWrEdefault_return_type)rbctxs rMrgzSuggestionPlugin.log}sb        $$    &&&rLN)r`rBreturnNone)rirBrtz(Callable[[FunctionContext], Type] | None)rirBrtz&Callable[[MethodContext], Type] | None)rszFunctionContext | MethodContextrtr3)rGrHrI__doc__rcrjrmrgrKrLrMrZrZes:/  'rLrZc(eZdZdZddZddZddZy) ReturnFinderz7Visitor for finding all types returned from a function.c ||_g|_yre)typemap return_types)rbrzs rMrczReturnFinder.__init__s (*rLc|jL|j|jvr3|jj|j|jyyyre)exprrzr{rorbos rMvisit_return_stmtzReturnFinder.visit_return_stmtsD 66 !&&DLL"8    $ $T\\!&&%9 :#9 rLcyrerKr~s rMvisit_func_defzReturnFinder.visit_func_defs rLN)rzdict[Expression, Type]rtru)rrrtru)rrrtru)rGrHrIrvrcrrrKrLrMrxrxsA+; rLrxcft|}|jj||jS)z9Find all the types returned by return statements in func.)rxbodyacceptr{)rzfuncfinders rMget_return_typesrs* ' "FIIV   rLc eZdZdZddZddZy) ArgUseFinderzVisitor for finding all the types of arguments that each arg is passed to. This is extremely simple minded but might be effective anyways. cp||_|jDcic]}|jgc}|_ycc}wre)rz argumentsvariablerE)rbrrzargs rMrczArgUseFinder.__init__s- TXTbTb7cS b8H7c7cs3cBtfd|jDsytjj |j }t |tsyt|j|j|j|jd}t|D]z\}}|D]p}|j|}t |ts#|jjvs<j|jj|j|r|y)Nc3rK|].}t|txr|jjv0ywre) isinstancernoderE).0erbs rM z/ArgUseFinder.visit_call_expr..s-W1:a)Faff.FFWs47c4ttjSre)r,r6 special_form)ns rMz.ArgUseFinder.visit_call_expr..sgi445rL)anyargsr<rzgetcalleerr-r rTrW enumeraterrrEro)rbrtypformal_to_actualirarg_idxrs` rMvisit_call_exprzArgUseFinder.visit_call_exprsWPQPVPVWW dll..qxx89#|, 1 KK KK MM MM 5  !!12 FGAt FffWoc7+DNN0JNN388,33CMM!4DE F FrLN)rrrzrrtru)rrrtru)rGrHrIrvrcrrKrLrMrrs dFrLrct||}|jj||jDcgc]}|j|j c}Scc}w)zFind all the types of arguments that each arg is passed to. For example, given def foo(x: int) -> None: ... def bar(x: str) -> None: ... def test(x, y): foo(x) bar(y) this will return [[int], [str]]. )rrrrrEr)rzrrrs rM get_arg_usesrsI$ (FIIV6:nn EsF  S\\ * EE Es Ac eZdZy)SuggestionFailureN)rGrHrIrKrLrMrrsrLrc<|jtjk(Sre) type_of_anyr6explicitrs rMis_explicit_anyrs ??i00 00rLcTt|}t|txr t| Sre)r<rr,rrs rMis_implicit_anyrs& # C c7 # @OC,@(@@rLct|ttfxsGt|txr5|jj xr|jj dduS)N__call__)rr9r-r/type is_protocol get_methodrs rM_arg_accepts_functionrsW 3l34 8 3! 8 HH  8 HH   +4 7rLceZdZdZdddddd d#dZd$dZd$dZed%dZed&d Z d'd Z d'd Z d(d Z d)d Z d*dZd+dZ d,dZd-dZd.dZd/dZ d0dZd1dZd2dZd3dZd4dZd5dZd6dZd7d8dZd9dZ d:dZ d;dZdd!Z!d?d"Z"y)@SuggestionEnginez8Engine for finding call sites and suggesting signatures.FN) no_errorsno_anyflex_any use_fixme max_guessesc^||_|j|_|jj|_|j|_t |jj |jj |_||_||_ ||_ |rd|_ |xsd|_ ||_ y)N?@) fgmanagermanagerplugingraphrfscacheoptionsr give_jsonrrrr)rbrjsonrrrrrs rMrczSuggestionEngine.__init__s# (( ll)) __ "4<<#7#79M9MN "  DM&,""rLcH|j|\}}}|j|5|j5|j||}dddddd|jr|j |||S|j S#1swYBxYw#1swYFxYw)z&Suggest an inferred type for function.N) find_node restore_afterwith_export_typesget_suggestionrjson_suggestionformat_signature)rbfunctionmod func_namer suggestions rMsuggestzSuggestionEngine.suggests#~~h7Y    $ <'') <!00d;  < < >>''YjI I((4 4  < < < > JaWY00 1 J NN NN I// 0 OO/ 0   Js A9ct|jtrt|jS|j |Sre)rrr-make_suggestion_anysr)rbrs rMget_starting_typez"SuggestionEngine.get_starting_typeSs0 dii .' 2 2((. .rLc jg}tt|jD]}|dk(r,|r*|jt t j g5g}|D]6} | j||z D]} t| r|j| !8g} ||D]} t| r| j| !||} | r$|j| | r| j| g} |rStd|DrA| jtj|dt t jgnE|r| jt|n(| jt t j| r| jt| |j| |S)z:Produce a list of type suggestions for each argument type.rc3NK|]}tt|tywre)rr<r0)rtps rMrz,SuggestionEngine.get_args..}s!%>@ ?2.9%#%)rangelenrTror,r6rrErallr; make_unionrextendgenerate_type_combinationsr)rb is_methodbasedefaultsrusestypesr all_arg_typescallr all_use_typesdefaultrEs rMget_argszSuggestionEngine.get_argsYs#%s4>>*+) $AAv) gi&A&ABCDM! 2>>!i-82C*3/%,,S12 2 MAw .&s+!((- . qkG$$W- !((1I%DQ%"  ((-*:GIDVDV? LL #S) $T rLc|jDcgc]3}|jr#|jj|jnd5c}Scc}wre)r initializerr all_types)rbrrs rMget_default_arg_typesz&SuggestionEngine.get_default_arg_typessF~~ 8;DLL " "3?? 3D P   s8A c |j|||||}tjtj|d|j}|Dcgc]'}t ||j t|)c}Scc}w)zCompute a list of guesses for a function's type. This focuses just on the argument types, and doesn't change the provided return type. r)rE)r itertoolsisliceproductrrefine_callable copy_modifiedlist) rbrrrrrrrxs rM get_guesseszSuggestionEngine.get_guessesso-- 49dK""9#4#4g#>4CSCSTV]^QRd&8&847&8&KL^^^s ,A:cz|j|}t|j}|jjj d| |j ||}|jjjd|j|fS#|jjjdwxYw)z"Find all call sites of a function.r) rrZrir_pluginsinserttry_typepopra)rbrnew_typecollector_pluginerrorss rMrzSuggestionEngine.get_callsitess))$/+DMM: ##A'78 (]]42F KK $ $Q ',,f44 KK $ $Q 's B'B:cx|Dcgc]*}|jt||||jk\r|,c}Scc}w)z~Apply any configured filters to the possible guesses. Currently the only option is filtering based on Any prevalance.)rany_score_callable)rbguessesr ignore_returnts rMfilter_optionszSuggestionEngine.filter_optionssC }}$!!Y >$--O    s/7c|s td|Dcic]}|j||c}t|fd}|t|fScc}w)zFrom a list of possible function types, find the best one. For best, we want the fewest errors, then the best "score" from score_callable. zNo guesses that match criteria!cBt|j|fSre) count_errorsscore_callable)srrbs rMrz,SuggestionEngine.find_best..s!<q +BDDWDWXYDZ*[rL)key)rrminr)rbrrguessbestrs` @rM find_bestzSuggestionEngine.find_bests[ #$EF FAHI%tU33I7 [\\&,///JsAc|jsgS|jjddD]}|jj|j}|s+t |j ttfsLt|j j}t |ts|t|jt|jk(s|gcSgS)z8Try to get a guess of a method type from a parent class.r]N)infomronamesrnamerrrrr<rr-rrEr)rbrparentpnoders rMget_guesses_from_parentz(SuggestionEngine.get_guesses_from_parentsyyIiimmAB' !FLL$$TYY/EEJJ)0DE%ejjoo6c<0S5G3t~~K^5^ 5L ! rLc |j}|j|\}}t|jj|}|j r |r t dt|jxr |j}tj||jj5|j||j||j!|||}ddd|j#|z }|j%||d}|j'||\} } |j)|| t+|jj|} tj||jj5| r t-| } n t/g} ddd D cgc](} | j1t3| j4| *}} |j%||d}|j'||\} }|j r |r t d|j7||| S#1swYOxYw#1swYxYwcc} w)zxCompute a suggestion for a function. Return the type and whether the first argument should be ignored. zFunction does not typecheck.NT)rret_typeFzNo annotation without errors)rrrrrrrboolr&has_self_or_cls_argumentr(strict_optional_setrstrict_optionalr rrr,rr$rrrr0r  refine_typer/pyannotate_signature)rbrrrr orig_errorsrrrr#rreturns ret_typesrrs rMrzSuggestionEngine.get_suggestions   !%!3!3D!9 ;DLL22D9 >>k#$BC COE(E(E  & &uSz'9'9'I'I J &&&&t,**40 G  4//55%%gy%M..w/a dD!"4<<#9#94@  & &uSz'9'9'I'I J )6w? %ZL  ) XaaRS4%%{4==!/L%Maa%%gy%N~~dG4 f >>f#$BC C((i>>9   ) ) bs)4H*H7&-I*H47IcXg}tt|D]}}t||||||D]Q\}}}|jd|} |tk(rd| z} (|t k(rd| z} 7|j sH|sK|d| } S|j ddj|dS)N*z**=(, )) rrzip format_typerris_namedror) rbrTrWrErrkindr)rrs rMrzSuggestionEngine.format_args s s9~& A#&y|Yq\9Q<#P .dC&&tS18#)CY&*C]]_!%auo . KK  499T?#1%%rLcd}d|vrtjdk(rdnd}|jd|kDrtdj ||j dd\}}|j std|t|}|j||\}}|jt|dzd}nGt|jj|} | std|| \}}|j||}t|t r"|j#|}|std |d t|t$std |d |||fS) a4From a target name, return module/target names and the func def. The 'key' argument can be in one of two formats: * As the function full name, e.g., package.module.Cls.method * As the function location as file and line separated by column, e.g., path/to/file.py:42 Nrwin32r]zgMalformed location for function: {}. Must be either package.module.Class.method or path/to/file.py:linez"Line number must be a number. Got zCannot find module for zObject z is a decorator we can't handlez is not a function)sysplatformcountrformatr_isdigitrQfind_node_by_file_and_linerirr?rrfind_node_by_module_and_namerrextract_from_decoratorr) rbr rplatform_key_countfilerR line_numbermodnametailr`s rMrzSuggestionEngine.find_nodesc#' #: '*llg&=1 yy~ 22'KKQ6RU;C+JD$<<>'*LTF(STTd)K ;;D+NMGT==W!1!34D!$.."6"6 5 C-$&C#&&3z?Q3FxX[\ LVX[\ X###rLctfdtDs td |jj t j j\}}||jvrtd|z|j|jj|d}d}d}|jD]Z\}} }t| jtt fr| jj"} n?| |ksE|| |kDsM| }| j}\|std|||fS#t$r}tdz|d}~wwxYw) zFind symbol node by path to file and line number. Find the first function declared *before or on* the line number. Return module id and the node found. Raise SuggestionFailure if can't find one. c3@K|]}j|ywre)r^)rextrOs rMrz>SuggestionEngine.find_node_by_file_and_line..tsC#4==%Csz Source file is not a Python filezInvalid source file name: NzUnknown module: T)forcezCannot find a function at line )rrrrcrawl_uposrPnormpathrrrVrlocal_definitionsrrrrrR) rbrOrRrQrrrXr closest_linesymsym_lines ` rMrKz+SuggestionEngine.find_node_by_file_and_linemsJC1BCC#$FG G P--bgg.>.>t.DEJGQ $** $#$6$@A A!!$.."6"6w"?t!L"&#' //1 IAsA#((Wi$8988==4\%9X =T' xx #&EdV$LM M}-! P#$@4$GHa O Ps;D,, E 5EE c|jD]}d}t|tr@t|jtt fr t |jj}nt|trt|jtr}t|jjtt tfrNtt |jjjx}trt |j}t|tr[|jjd}t|t r0t|jtrt!|jd}t|tsy|j"D]Z}t%|j&dk(r>t)t |j&dr|j&d|jk(rYy|j*S)Nrr]r) decoratorsrrrr"rr<rrrrr-r/r/rr.r*itemsrrErr)rbrdecrcall_tp call_methodcts rMrMz'SuggestionEngine.extract_from_decorators^?? CC#w'Jsxx#w,P%chhmm43)szz73szzGS0IJ?3::??;O;O+P PS_`%g&6&67#x(!hh11*= k73 ;CSCSUa8b#K$4$4d;Cc<0ii  %*-obll1o.NO Q2;;6  ' 6yyrLc|j}d|_||_ |jj|j}|||_S#||_wxYw)z_Recheck a function while assuming it has type typ. Return all error messages. N)unanalyzed_typerrtriggerri)rbrrrress rMrzSuggestionEngine.try_typesS "" " '..((7C#&D 3D s &A Ac|jJ|jj|jj|j|jfggS)z"Recheck the module given by state.)rPr flush_cacheupdateid)rbr(s rMrzSuggestionEngine.reloadsIzz%%% ""$~~$$uxx&<%=rBBrLc|jr|jjs|r|j||jJ|jS)z?Make sure that the module represented by state is fully loaded.)rXis_cache_skeletonr)rbr(r_s rMrVzSuggestionEngine.ensure_loadeds=zzUZZ99U KK zz%%%zzrLcL|jjj|Sre)rsemantic_analyzerr)rbrs rMrzSuggestionEngine.named_types||--88;;rLc|js |jr|jddd}tjj |j |j}||j||dd}tj|gdS)zLProduce a json blob for a suggestion suitable for application by pyannotate.r\r]rTr) signaturerRrPrsamplesT) sort_keys) is_class is_staticrWrarPabspathrxpathrRrdumps)rbrrrrrPobjs rMrz SuggestionEngine.json_suggestionsy ==DNN!Q/3I wwtzz#445$II"  zz3%400rLct|}|j|dDcgc]}|j||c}|j||jdScc}w)z+Format a callable type as a pyannotate dictN)rErC)rQrEr@r/)rb cur_modulerrstartrs rMr5z%SuggestionEngine.pyannotate_signaturesVICF==QVQWCXYa$**:q9Y++J E  YsAc<ddj|dd|dS)zDFormat a callable type in a way suitable as an annotation... kind ofr<r=rEz) -> rC)r)rbsigs rMrz!SuggestionEngine.format_signatures*499S-./uS5G4HIIrLc|jr%tt|tr |jS|j t ||j |jjSre) rrr<r,r TypeFormatterrrr)rbrrs rMr@zSuggestionEngine.format_typesG >>j)=wG>> !zz- DJJ @T@TUVVrLc\t|}t|try|rt|tryt|trFt d|j Dryt d|j Dryt|syt|trt|s t|ryy)zGenerate a score for a type that we use to pick which type to use. Lower is better, prefer non-union/non-any types. Don't penalize optionals. c3NK|]}tt|tywrerr<r,rr s rMrz.SuggestionEngine.score_type..sLq:oa0':Lrc32K|]}t|ywrerrs rMrz.SuggestionEngine.score_type..s4q<?4 r) r<rr,r0r;rrir=r-ris_tricky_callable)rbrarg_poss rM score_typezSuggestionEngine.score_types A  a ! z!X. a #LAGGLL4AGG44&q) a &LO?QRS?TrLc|tfd|jDj|jdzS)Nc3DK|]}j|dyw)TrN)r)rr rbs rMrz2SuggestionEngine.score_callable..sI4??1d?3Is Fr)sumrErr/rbrs` rMrzSuggestionEngine.score_callables;IQ[[IIDOO JJM\M   rL)rr'rr0rr0rr0rz float | Noner str | Nonerz int | Nonertru)rrBrtrB)rrBrtIterator[None])rtr)rrrtr-) rr0rr-rlist[Type | None]rlist[Callsite]rrXrtrX)rrrtr) rr0rr-rrrrrrXrtlist[CallableType])rrrtz tuple[list[Callsite], list[str]])rrrr0rr0rtr)rrrrrtztuple[CallableType, int])rrrtr)rrBrrrtrA)rTrSrWrVrErXrtrB)r rBrtztuple[str, str, FuncDef])rQrBrRrBrtzSymbolNode | None)rOrBrRrQrtztuple[str, SymbolNode])rrrtzFuncDef | None)rrrr1rtrD)r(r rtrD)F)r(r r_r0rtr)rrBrtr/) rrBrrBrrrrArtrB)rrrr0rr-rtrA)rrArtrB)rrrr3rtrB)rr3rr0rtrQ)rr-rtrQ)#rGrHrIrvrcrrrrrrrrrr rrr$r,rrrrLrKrMrrrVrrr5rr@rrrKrLrMrrs)B !% $"&#*# #  #  ### # #4 5  ,, 4 4  / 444$ 4 " 4  4 4l ___$ _ " _  _ _$ 5  )  6:  KO     0"*?X&&&*&$ & &(*#X!$F!F<'(C <11#&1.51CV1 1, $ 15 .!sH1z/!,g6Hrc32K|]}t|ywrerrs rMrz!any_score_type..#s01|A0rg?r) r<rr,rr6rr0r;rrir-rr)utrrs rMany_score_typers A!W!--93N3N"N!X7!Y HH H 00 0!\"'9!'<A rLc(|jt|dDcgc]}t|d}}tt |j t r|s"|rdnt|j d}|||gz }t|t|z Scc}w)NTrrF) rErQrrr<r/r0rr)rrrr scoresrets rMrr-s~78{{3y>CS7T U!nQ- UF U oajj18 .<s$$VQQYY[%@AJJL%@$Vs,.)is_ellipsis_argsrrTrs rMrr:s"   V$V!++$V!VVrLc`eZdZdZd fd Zd dZd dZd dZddZddZ dfd Z dd Z xZ S)rzVisitor used to format typescBt||||_||_y)N)r)superrcrr)rbrrr __class__s rMrczTypeFormatter.__init__Cs! )  rLc4|jr |jSyNAny)missing_import_namers rM visit_anyzTypeFormatter.visit_anyHs (( (rLcv|jjxs|jjxsd}|yt|j|}|sJ|\}}|j ra|j d}|j|j j}|r+|d|jvr||jvr |j }||fdk(r'dd|jdj|zdz}}n.|jr"|d|j|jd z }|d k(ry |d k(r|Sd|vrdnd }||z|zS)Nzr\r)builtinstupletypingTuple[z, ...][])runicodeTextrr) rrir)r?rrrWrXr(rrlist_str) rbrrmod_objrrpartsrXdelims rMvisit_instancezTypeFormatter.visit_instanceNs- FFOO 2qvv{{ 2d 9tzz1-wS ;;IIcNE::dkk*//DaDJJ.3djj3Hkk :. .AFF1I,<,CsE;$ $rLc|jrV|jjr@|jjj}|dk7r|jj|S|j |j }d|dS)Nzbuiltins.tuplerr)partial_fallbackrrirrri)rbr fallback_namers rMvisit_tuple_typezTypeFormatter.visit_tuple_typemsp  !"4"4"9"9..33<rrvisit_union_type)rbrrs rMrzTypeFormatter.visit_union_type{sK qww<1 !4Q!7q188>?qA A7+A. .rLct|rd}n=|jDcgc]}|j|}}ddj|d}d|d|jj|dScc}w)Nz...rr=rz Callable[)rrErrr/)rbrarg_strrrs rMvisit_callable_typez!TypeFormatter.visit_callable_typesr a G 12 <CJJt$a@@=sA.)rrrr rr#rtru)rr,rtrB)rr/rtrB)rr2rtrB)rr:rtrB)rr5rtrB)rr;rtrB)rr-rtrB) rGrHrIrvrcrrrrrrr __classcell__)rs@rMrr?s/&  %>'/ ArLrTType)boundcPtt|jtS)zMake all anys in the type as coming from the suggestion engine. This keeps those Anys from influencing constraint generation, which allows us to do better when refining types. )r rrMakeSuggestionAnyrs rMrrs qxx 1 34 55rLceZdZddZddZy)rc^|js |jtjS|S)N)r)rr r6rrs rMrzMakeSuggestionAny.visit_anys'$$??y/J/J?K KHrLc~|j|jDcgc]}|j|c}Scc}w)Nr)r rr)rbras rMvisit_type_alias_typez'MakeSuggestionAny.visit_type_alias_types-QVV$DQXXd^$DEE$Ds:N)rr,rtr3)rr4rtr3)rGrHrIrrrKrLrMrrs  FrLrcFt|}t|}||k(r|gS||gS)zGenerate possible combinations of a list of types. mypy essentially supports two different ways to do this: joining the types and unioning the types. We try both. )rr+)r joined_type union_types rMrrs3 !'K&u-Jj }Z((rLcHt|Dcgc] }d|vs| c}Scc}w)Nz error: )r)msgsr s rMrrs! 43a:?3 443s c t|}t|}t|tr t|tr|jr|S|St|trvt|trf|j |j k(rM|j t|j|jDcgc]\}}t||c}}St|trt|tr|j|jk(rxt|jt|jk(rM|j t|j|jDcgc]\}}t||c}}St|trt|tr t||St|t r t#||S|Scc}}wcc}}w)aRefine `ti` by replacing Anys in it with information taken from `si` This basically works by, when the types have the same structure, traversing both of them in parallel and replacing Any on the left with whatever the type on the right is. If the types don't have the same structure (or aren't supported), the left type is chosen. For example: refine(Any, T) = T, for all T refine(float, int) = float refine(List[Any], List[int]) = List[int] refine(Dict[int, Any], Dict[Any, int]) = Dict[int, int] refine(Tuple[int, Any], Tuple[Any, int]) = Tuple[int, int] refine(Callable[[Any], Any], Callable[[int], int]) = Callable[[int], int] refine(Callable[..., int], Callable[[int, float], Any]) = Callable[[int, float], int] refine(Optional[Any], int) = Optional[int] refine(Optional[Any], Optional[int]) = Optional[int] refine(Optional[Any], Union[int, str]) = Optional[Union[int, str]] refine(Optional[List[Any]], List[int]) = List[int] r)ri)r<rr,rr/rr r?rr4r2rrrir-rr; refine_union)tisirrtasas rMr4r4s^0 AA!Wq'*q/D/DqK!K!X:a#:qvv?Os166STSYSYGZ$[VR[R%8$[\\ 1i q) $  !"4"4 4 LCL (AGGUVU\U\H]%^fb"k"b&9%^__!\"z!\'Bq!$$!YAq!! H%%\&_s .G G cd||k(r|St|tr |jn|g}g}|jD]D}d}|D]'}t||}||k7s|j |d})|r4|j |Ft j d5t|cdddS#1swYyxYw)a7Refine a union type based on another type. This is done by refining every component of the union against the right hand side type (or every component of its union if it is one). If an element of the union is successfully refined, we drop it from the union in favor of the refined versions. FTN)rr;rir4ror(r2r+)rr rhs_items new_itemslhsrefinedrhsnews rMrrs Av%a3!IIww" Cc3'Ccz  %      S !"  " "4 (0$Y/000s  B&&B/c |j|jk7r|S|jr;t|s0|jt |j |j St|s|j |j k7r|S|jt|j|jDcgc]\}}t ||c}}t |j |j Scc}}w)zKRefine a callable based on another. See comments for refine_type. r.)rEr/) rrrr r4r/rTr?rE)rrrrs rMrrs  zzQZZ"4Q"7 AJJ (KLL! q{{ : ??58akk5RS62r;r2&SQZZ4  Ss7C5 TcDg}|D]}||vs|j||Sre)ro)rrr s rMrr&s/C  C< JJqM JrL)rzrrrrt list[Type])rzrrrrtrX)rr,rtr0)rr3rtr0)rr1rtr0)rr3rr0rtfloat)rr-rr0rr0rtr)rr-rtr0)rrrtr)rrrtr)rrDrtrQ)rr3rr3rtr3)rr;rr1rtr3)rr-rr-rtr-)rlist[T]rtr)qrv __future__rrrrarFcollections.abcr contextlibrrrrrr r mypy.argmapr mypy.buildr r mypy.checkexprrmypy.find_sourcesrr mypy.joinr mypy.meetrmypy.modulefinderr mypy.nodesrrrrrrrrrrrr r!r" mypy.optionsr# mypy.pluginr$r%r&mypy.server.updater' mypy.stater(mypy.traverserr) mypy.typeopsr*r+ mypy.typesr,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<mypy.types_utilsr=r> mypy.utilr?rArOrZrxrrr Exceptionrrrrrrrrrrrrrrr4rrrrrKrLrMr sl0# $%AA.#'=$$/ !>>6+9&B")  z #'v#'P  #  F#FBF"  1A ^ ^ B. %W NANNAb t$6FF )52 j0B( CLrL