def get_formal_type_parameters(self): return { abstract_utils.full_type_name(self, abstract_utils.ARGS): (self.formal_type_parameters[abstract_utils.ARGS]), abstract_utils.full_type_name(self, abstract_utils.RET): (self.formal_type_parameters[abstract_utils.RET]) }
def test_callable_with_args(self): ast = self._load_ast("a", """ from typing import Callable x = ... # type: Callable[[int, bool], str] """) x = ast.Lookup("a.x").type cls = self._ctx.convert.constant_to_value(x, {}, self._ctx.root_node) instance = self._ctx.convert.constant_to_value( abstract_utils.AsInstance(x), {}, self._ctx.root_node) self.assertIsInstance(cls, abstract.CallableClass) self.assertCountEqual( cls.formal_type_parameters.items(), [(0, self._ctx.convert.int_type), (1, self._ctx.convert.primitive_classes[bool]), (abstract_utils.ARGS, abstract.Union( [cls.formal_type_parameters[0], cls.formal_type_parameters[1]], self._ctx)), (abstract_utils.RET, self._ctx.convert.str_type)]) self.assertIsInstance(instance, abstract.Instance) self.assertEqual(instance.cls, cls) self.assertCountEqual( [(name, set(var.data)) for name, var in instance.instance_type_parameters.items()], [(abstract_utils.full_type_name(instance, abstract_utils.ARGS), { self._ctx.convert.primitive_class_instances[int], self._ctx.convert.primitive_class_instances[bool] }), (abstract_utils.full_type_name(instance, abstract_utils.RET), {self._ctx.convert.primitive_class_instances[str]})])
def get_instance_type_parameter(self, name, node=None): name = abstract_utils.full_type_name(self, name) param = self.instance_type_parameters.get(name) if not param: log.info("Creating new empty type param %s", name) if node is None: node = self.ctx.root_node param = self.ctx.program.NewVariable([], [], node) self.instance_type_parameters[name] = param return param
def test_plain_callable(self): ast = self._load_ast("a", """ from typing import Callable x = ... # type: Callable[..., int] """) x = ast.Lookup("a.x").type cls = self._ctx.convert.constant_to_value(x, {}, self._ctx.root_node) instance = self._ctx.convert.constant_to_value( abstract_utils.AsInstance(x), {}, self._ctx.root_node) self.assertIsInstance(cls, abstract.ParameterizedClass) self.assertCountEqual(cls.formal_type_parameters.items(), [(abstract_utils.ARGS, self._ctx.convert.unsolvable), (abstract_utils.RET, self._ctx.convert.int_type)]) self.assertIsInstance(instance, abstract.Instance) self.assertEqual(instance.cls, cls.base_cls) self.assertCountEqual( [(name, var.data) for name, var in instance.instance_type_parameters.items()], [(abstract_utils.full_type_name( instance, abstract_utils.ARGS), [self._ctx.convert.unsolvable]), (abstract_utils.full_type_name(instance, abstract_utils.RET), [self._ctx.convert.primitive_class_instances[int]])])
def merge_instance_type_parameter(self, node, name, value): """Set the value of a type parameter. This will always add to the type parameter unlike set_attribute which will replace value from the same basic block. This is because type parameters may be affected by a side effect so we need to collect all the information regardless of multiple assignments in one basic block. Args: node: Optionally, the current CFG node. name: The name of the type parameter. value: The value that is being used for this type parameter as a Variable. """ name = abstract_utils.full_type_name(self, name) log.info("Modifying type param %s", name) if name in self.instance_type_parameters: self.instance_type_parameters[name].PasteVariable(value, node) else: self.instance_type_parameters[name] = value
def get_formal_type_parameters(self): return { abstract_utils.full_type_name(self, abstract_utils.T): self.formal_type_parameters[abstract_utils.T] }
def get_formal_type_parameters(self): return { abstract_utils.full_type_name(self, k): v for k, v in self.formal_type_parameters.items() }
def has_instance_type_parameter(self, name): """Check if the key is in `instance_type_parameters`.""" name = abstract_utils.full_type_name(self, name) return name in self.instance_type_parameters