def compute_subst(self, node, formal_args, arg_dict, view): """Compute information about type parameters using one-way unification. Given the arguments of a function call, try to find a substitution that matches them against the specified formal parameters. Args: node: The current CFG node. formal_args: An iterable of (name, value) pairs of formal arguments. arg_dict: A map of strings to pytd.Bindings instances. view: A mapping of Variable to Value. Returns: A tuple (subst, name), with "subst" the datatypes.HashableDict if we found a working substition, None otherwise, and "name" the bad parameter in case subst=None. """ if not arg_dict: # A call with no arguments always succeeds. assert not formal_args return datatypes.HashableDict(), None subst = {} self._set_error_subst(None) for name, formal in formal_args: actual = arg_dict[name] subst = self._match_value_against_type(actual, formal, subst, node, view) if subst is None: formal = self.vm.annotations_util.sub_one_annotation( node, formal, [self._error_subst or {}]) return None, abstract.BadParam(name=name, expected=formal) return datatypes.HashableDict(subst), None
def compute_subst(self, node, formal_args, arg_dict, view, alias_map=None): """Compute information about type parameters using one-way unification. Given the arguments of a function call, try to find a substitution that matches them against the specified formal parameters. Args: node: The current CFG node. formal_args: An iterable of (name, value) pairs of formal arguments. arg_dict: A map of strings to pytd.Bindings instances. view: A mapping of Variable to Value. alias_map: Optionally, a datatypes.UnionFind, which stores all the type renaming information, mapping of type parameter name to its representative. Returns: A tuple (subst, name), with "subst" the datatypes.HashableDict if we found a working substition, None otherwise, and "name" the bad parameter in case subst=None. """ if not arg_dict: # A call with no arguments always succeeds. assert not formal_args return datatypes.AliasingDict(), None subst = datatypes.AliasingDict() if alias_map: subst.uf = alias_map self._set_error_subst(None) self_subst = None for name, formal in formal_args: actual = arg_dict[name] subst = self._match_value_against_type(actual, formal, subst, node, view) if subst is None: formal = self.vm.annotations_util.sub_one_annotation( node, formal, [self._error_subst or {}]) return None, function.BadParam(name=name, expected=formal) if name == "self": self_subst = subst if self_subst: # Type parameters matched from a 'self' arg are class parameters whose # values have been declared by the user, e.g.: # x = Container[int](__any_object__) # We should keep the 'int' value rather than using Union[int, Unknown]. for name, value in self_subst.items(): if any(not isinstance(v, abstract.Empty) for v in value.data): subst[name] = value return datatypes.HashableDict(subst), None