module documentation
(source)

Mechanisms 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
Class ​Arg​Use​Finder Visitor for finding all the types of arguments that each arg is passed to.
Class ​Make​Suggestion​Any Undocumented
Class ​Return​Finder Visitor for finding all types returned from a function.
Class ​Str​To​Text Undocumented
Class ​Suggestion​Engine Engine for finding call sites and suggesting signatures.
Class ​Suggestion​Failure Undocumented
Class ​Suggestion​Plugin Plugin that records all calls to a given target.
Class ​Type​Formatter Visitor used to format types
Function any​_score​_callable Undocumented
Function any​_score​_type Generate a very made up number representing the Anyness of a type.
Function count​_errors Undocumented
Function dedup Undocumented
Function generate​_type​_combinations Generate possible combinations of a list of types.
Function get​_arg​_uses Find all the types of arguments that each arg is passed to.
Function get​_return​_types Find all the types returned by return statements in func.
Function is​_explicit​_any Undocumented
Function is​_implicit​_any Undocumented
Function is​_tricky​_callable Is t a callable that we need to put a ... in for syntax reasons?
Function make​_suggestion​_anys Make all anys in the type as coming from the suggestion engine.
Function refine​_callable Refine a callable based on another.
Function refine​_type Refine ti by replacing Anys in it with information taken from si
Function refine​_union Refine a union type based on another type.
Constant T Undocumented
Variable ​Callsite Undocumented
Variable ​Py​Annotate​Signature Undocumented
Variable ​TType Undocumented
def any_score_callable(t, is_method, ignore_return): (source)

Undocumented

Parameters
t:CallableTypeUndocumented
is​_method:boolUndocumented
ignore​_return:boolUndocumented
Returns
floatUndocumented
def any_score_type(ut, arg_pos): (source)

Generate a very made up number representing the Anyness of a type.

Higher is better, 1.0 is max

Parameters
ut:TypeUndocumented
arg​_pos:boolUndocumented
Returns
floatUndocumented
def count_errors(msgs): (source)

Undocumented

Parameters
msgs:List[str]Undocumented
Returns
intUndocumented
def dedup(old): (source)

Undocumented

Parameters
old:List[T]Undocumented
Returns
List[T]Undocumented
def generate_type_combinations(types): (source)

Generate 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.

Parameters
types:List[Type]Undocumented
Returns
List[Type]Undocumented
def get_arg_uses(typemap, func): (source)

Find 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]].

Parameters
typemap:Dict[Expression, Type]Undocumented
func:FuncDefUndocumented
Returns
List[List[Type]]Undocumented
def get_return_types(typemap, func): (source)
Find all the types returned by return statements in func.
Parameters
typemap:Dict[Expression, Type]Undocumented
func:FuncDefUndocumented
Returns
List[Type]Undocumented
def is_explicit_any(typ): (source)

Undocumented

Parameters
typ:AnyTypeUndocumented
Returns
boolUndocumented
def is_implicit_any(typ): (source)

Undocumented

Parameters
typ:TypeUndocumented
Returns
boolUndocumented
def is_tricky_callable(t): (source)
Is t a callable that we need to put a ... in for syntax reasons?
Parameters
t:CallableTypeUndocumented
Returns
boolUndocumented
def make_suggestion_anys(t): (source)

Make 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.

Parameters
t:TTypeUndocumented
Returns
TTypeUndocumented
def refine_callable(t, s): (source)

Refine a callable based on another.

See comments for refine_type.

Parameters
t:CallableTypeUndocumented
s:CallableTypeUndocumented
Returns
CallableTypeUndocumented
def refine_type(ti, si): (source)

Refine 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]

Parameters
ti:TypeUndocumented
si:TypeUndocumented
Returns
TypeUndocumented
def refine_union(t, s): (source)

Refine 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.

Parameters
t:UnionTypeUndocumented
s:ProperTypeUndocumented
Returns
TypeUndocumented

Undocumented

Value
TypeVar('T')
Callsite = (source)

Undocumented

PyAnnotateSignature = (source)

Undocumented

TType = (source)

Undocumented