Esempio n. 1
0
 def _function_to_return_types(self, node, fvar):
     """Convert a function variable to a list of PyTD return types."""
     options = fvar.FilteredData(self.vm.exitpoint, strict=False)
     if not all(isinstance(o, abstract.Function) for o in options):
         return [pytd.AnythingType()]
     types = []
     for val in options:
         if isinstance(val, abstract.InterpreterFunction):
             combinations = val.get_call_combinations(node)
             for node_after, _, return_value in combinations:
                 types.append(
                     self._function_call_to_return_type(
                         node_after, val, return_value, len(combinations)))
         elif isinstance(val, abstract.PyTDFunction):
             types.extend(sig.pytd_sig.return_type
                          for sig in val.signatures)
         else:
             types.append(pytd.AnythingType())
     safe_types = []  # types without type parameters
     for t in types:
         collector = visitors.CollectTypeParameters()
         t.Visit(collector)
         t = t.Visit(
             visitors.ReplaceTypeParameters(
                 {p: p.upper_value
                  for p in collector.params}))
         safe_types.append(t)
     return safe_types
Esempio n. 2
0
  def _combine_multiple_returns(self, signatures):
    """Combines multiple return types.

    Args:
      signatures: The candidate signatures.

    Returns:
      The combined return type.
    """
    options = []
    for sig, _, _ in signatures:
      t = sig.pytd_sig.return_type
      params = pytd_utils.GetTypeParameters(t)
      if params:
        replacement = {}
        for param_type in params:
          replacement[param_type] = pytd.AnythingType()
        replace_visitor = visitors.ReplaceTypeParameters(replacement)
        t = t.Visit(replace_visitor)
      options.append(t)
    if len(set(options)) == 1:
      return options[0]
    # Optimizing and then removing unions allows us to preserve as much
    # precision as possible while avoiding false positives.
    ret_type = optimize.Optimize(pytd_utils.JoinTypes(options))
    return ret_type.Visit(visitors.ReplaceUnionsWithAny())
Esempio n. 3
0
 def VisitSignature(self, sig):
   new_template = []
   substitutions = {k: k for k in self.type_params_stack[-1].keys()}
   for item in sig.template:
     new_template += self._ReplaceByOuterIfNecessary(item, substitutions)
   if sig.template == new_template:
     return sig  # Nothing changed.
   else:
     return sig.Replace(template=tuple(new_template)).Visit(
         visitors.ReplaceTypeParameters(substitutions)).Visit(SimplifyUnions())