1"""Tests for abstract.py."""
2
3from pytype import abstract
4from pytype import abstract_utils
5from pytype import config
6from pytype import errors
7from pytype import function
8from pytype import load_pytd
9from pytype import special_builtins
10from pytype import state as frame_state
11from pytype import vm
12from pytype.pytd import pytd
13from pytype.pytd import pytd_utils
14from pytype.tests import test_base
15from pytype.typegraph import cfg
16
17import unittest
18
19
20class AbstractTestBase(test_base.UnitTest):
21
22  def setUp(self):
23    super().setUp()
24    options = config.Options.create(python_version=self.python_version)
25    self._vm = vm.VirtualMachine(
26        errors.ErrorLog(), options, load_pytd.Loader(None, self.python_version))
27    self._program = self._vm.program
28    self._node = self._vm.root_node.ConnectNew("test_node")
29
30  def new_var(self, *values):
31    """Create a Variable bound to the given values."""
32    var = self._program.NewVariable()
33    for value in values:
34      var.AddBinding(value, source_set=(), where=self._node)
35    return var
36
37  def new_dict(self, **kwargs):
38    """Create a Dict from keywords mapping names to Variable objects."""
39    d = abstract.Dict(self._vm)
40    for name, var in kwargs.items():
41      d.set_str_item(self._node, name, var)
42    return d
43
44
45class IsInstanceTest(AbstractTestBase):
46
47  def setUp(self):
48    super().setUp()
49    self._is_instance = special_builtins.IsInstance.make(self._vm)
50    # Easier access to some primitive instances.
51    self._bool = self._vm.convert.primitive_class_instances[bool]
52    self._int = self._vm.convert.primitive_class_instances[int]
53    self._str = self._vm.convert.primitive_class_instances[str]
54    # Values that represent primitive classes.
55    self._obj_class = self._vm.convert.primitive_classes[object]
56    self._int_class = self._vm.convert.primitive_classes[int]
57    self._str_class = self._vm.convert.primitive_classes[str]
58
59  def assert_call(self, expected, left, right):
60    """Check that call() returned the desired results.
61
62    Args:
63      expected: A dict from values to source sets, where a source set is
64          represented by the sorted binding names separated by spaces, for
65          example "left:0 right:1" would indicate binding #0 of variable
66          "left" and binding #1 of variable "right".
67      left: A Variable to use as the first arg to call().
68      right: A Variable to use as the second arg to call().
69    """
70    name_map = {left: "left", right: "right"}
71    node, result = self._is_instance.call(
72        self._node, None, function.Args(
73            (left, right), self.new_dict(), None, None))
74    self.assertIn(node, self._node.outgoing)
75    result_map = {}
76    # Turning source sets into canonical string representations of the binding
77    # names makes it much easier to debug failures.
78    for b in result.bindings:
79      terms = set()
80      for o in b.origins:
81        self.assertEqual(node, o.where)
82        for sources in o.source_sets:
83          terms.add(" ".join(sorted(
84              "%s:%d" % (name_map[b.variable], b.variable.bindings.index(b))
85              for b in sources)))
86      result_map[b.data] = terms
87    self.assertEqual(expected, result_map)
88
89  def test_call_single_bindings(self):
90    right = self.new_var(self._str_class)
91    left = self.new_var(self._str)
92    self.assert_call(
93        {self._vm.convert.true: {"left:0 right:0"}},
94        left, right)
95    left = self.new_var(self._int)
96    self.assert_call(
97        {self._vm.convert.false: {"left:0 right:0"}},
98        left, right)
99    left = self.new_var(abstract.Unknown(self._vm))
100    self.assert_call(
101        {self._bool: {"left:0 right:0"}},
102        left, right)
103
104  def test_call_multiple_bindings(self):
105    left = self.new_var(self._int, self._str)
106    right = self.new_var(self._int_class, self._str_class)
107    self.assert_call(
108        {
109            self._vm.convert.true: {"left:0 right:0", "left:1 right:1"},
110            self._vm.convert.false: {"left:0 right:1", "left:1 right:0"},
111        }, left, right)
112
113  def test_call_wrong_argcount(self):
114    self._vm.push_frame(frame_state.SimpleFrame())
115    node, result = self._is_instance.call(
116        self._node, None, function.Args((), self.new_dict(), None, None))
117    self.assertEqual(self._node, node)
118    self.assertIsInstance(abstract_utils.get_atomic_value(result),
119                          abstract.Unsolvable)
120    self.assertRegex(str(self._vm.errorlog), "missing-parameter")
121
122  def test_call_wrong_keywords(self):
123    self._vm.push_frame(frame_state.SimpleFrame())
124    x = self.new_var(abstract.Unknown(self._vm))
125    node, result = self._is_instance.call(
126        self._node, None, function.Args(
127            (x, x), self.new_dict(foo=x), None, None))
128    self.assertEqual(self._node, node)
129    self.assertIsInstance(abstract_utils.get_atomic_value(result),
130                          abstract.Unsolvable)
131    self.assertRegex(str(self._vm.errorlog),
132                     r"foo.*isinstance.*\[wrong-keyword-args\]")
133
134  def test_is_instance(self):
135    def check(expected, left, right):
136      self.assertEqual(expected, self._is_instance._is_instance(left, right))
137
138    # Unknown and Unsolvable are ambiguous.
139    check(None, abstract.Unknown(self._vm), self._obj_class)
140    check(None, abstract.Unsolvable(self._vm), self._obj_class)
141
142    # If the object's class has multiple bindings, result is ambiguous.
143    obj = abstract.SimpleValue("foo", self._vm)
144    check(None, obj, self._obj_class)
145    obj.set_class(self._node, self.new_var(
146        self._str_class, self._int_class))
147    check(None, obj, self._str_class)
148
149    # If the class_spec is not a class, result is ambiguous.
150    check(None, self._str, self._str)
151
152    # Result is True/False depending on if the class is in the object's mro.
153    check(True, self._str, self._obj_class)
154    check(True, self._str, self._str_class)
155    check(False, self._str, self._int_class)
156
157  def test_flatten(self):
158    def maybe_var(v):
159      return v if isinstance(v, cfg.Variable) else self.new_var(v)
160
161    def new_tuple(*args):
162      pyval = tuple(maybe_var(a) for a in args)
163      return self._vm.convert.tuple_to_value(pyval)
164
165    def check(expected_ambiguous, expected_classes, value):
166      classes = []
167      ambiguous = abstract_utils._flatten(value, classes)
168      self.assertEqual(expected_ambiguous, ambiguous)
169      self.assertEqual(expected_classes, classes)
170
171    unknown = abstract.Unknown(self._vm)
172
173    # Simple values.
174    check(False, [self._str_class], self._str_class)
175    check(True, [], self._str)
176    check(True, [], unknown)
177
178    # (str, int)
179    check(False, [self._str_class, self._int_class],
180          new_tuple(self._str_class, self._int_class))
181    # (str, ?, int)
182    check(True, [self._str_class, self._int_class],
183          new_tuple(self._str_class, unknown, self._int_class))
184    # (str, (int, object))
185    check(False, [self._str_class, self._int_class, self._obj_class],
186          new_tuple(
187              self._str_class,
188              new_tuple(self._int_class, self._obj_class)))
189    # (str, (?, object))
190    check(True, [self._str_class, self._obj_class],
191          new_tuple(
192              self._str_class,
193              new_tuple(unknown, self._obj_class)))
194    # A variable with multiple bindings is ambiguous.
195    # (str, int | object)
196    check(True, [self._str_class],
197          new_tuple(self._str_class,
198                    self.new_var(self._int_class, self._obj_class)))
199
200
201class PyTDTest(AbstractTestBase):
202  """Tests for abstract -> pytd type conversions."""
203
204  def test_metaclass(self):
205    cls = abstract.InterpreterClass("X", [], {}, None, self._vm)
206    meta = abstract.InterpreterClass("M", [], {}, None, self._vm)
207    meta.official_name = "M"
208    cls.cls = meta
209    pytd_cls = cls.to_pytd_def(self._vm.root_node, "X")
210    self.assertEqual(pytd_cls.metaclass, pytd.NamedType("M"))
211
212  def test_inherited_metaclass(self):
213    parent = abstract.InterpreterClass("X", [], {}, None, self._vm)
214    parent.official_name = "X"
215    meta = abstract.InterpreterClass("M", [], {}, None, self._vm)
216    meta.official_name = "M"
217    parent.cls = meta
218    child = abstract.InterpreterClass("Y",
219                                      [parent.to_variable(self._vm.root_node)],
220                                      {}, None, self._vm)
221    self.assertIs(child.cls, parent.cls)
222    pytd_cls = child.to_pytd_def(self._vm.root_node, "Y")
223    self.assertIs(pytd_cls.metaclass, None)
224
225  def test_metaclass_union(self):
226    cls = abstract.InterpreterClass("X", [], {}, None, self._vm)
227    meta1 = abstract.InterpreterClass("M1", [], {}, None, self._vm)
228    meta2 = abstract.InterpreterClass("M2", [], {}, None, self._vm)
229    meta1.official_name = "M1"
230    meta2.official_name = "M2"
231    cls.cls = abstract.Union([meta1, meta2], self._vm)
232    pytd_cls = cls.to_pytd_def(self._vm.root_node, "X")
233    self.assertEqual(pytd_cls.metaclass, pytd.UnionType(
234        (pytd.NamedType("M1"), pytd.NamedType("M2"))))
235
236  def test_to_type_with_view1(self):
237    # to_type(<instance of List[int or unsolvable]>, view={T: int})
238    instance = abstract.List([], self._vm)
239    instance.merge_instance_type_parameter(
240        self._vm.root_node, abstract_utils.T,
241        self._vm.program.NewVariable([self._vm.convert.unsolvable], [],
242                                     self._vm.root_node))
243    param_binding = instance.get_instance_type_parameter(
244        abstract_utils.T).AddBinding(
245            self._vm.convert.primitive_class_instances[int], [],
246            self._vm.root_node)
247    view = {
248        instance.get_instance_type_parameter(abstract_utils.T): param_binding}
249    pytd_type = instance.to_type(self._vm.root_node, seen=None, view=view)
250    self.assertEqual("builtins.list", pytd_type.name)
251    self.assertSetEqual({"builtins.int"},
252                        {t.name for t in pytd_type.parameters})
253
254  def test_to_type_with_view2(self):
255    # to_type(<tuple (int or str,)>, view={0: str})
256    param1 = self._vm.convert.primitive_class_instances[int]
257    param2 = self._vm.convert.primitive_class_instances[str]
258    param_var = param1.to_variable(self._vm.root_node)
259    str_binding = param_var.AddBinding(param2, [], self._vm.root_node)
260    instance = abstract.Tuple((param_var,), self._vm)
261    view = {param_var: str_binding}
262    pytd_type = instance.to_type(self._vm.root_node, seen=None, view=view)
263    self.assertEqual(pytd_type.parameters[0],
264                     pytd.NamedType("builtins.str"))
265
266  def test_to_type_with_view_and_empty_param(self):
267    instance = abstract.List([], self._vm)
268    pytd_type = instance.to_type(self._vm.root_node, seen=None, view={})
269    self.assertEqual("builtins.list", pytd_type.name)
270    self.assertSequenceEqual((pytd.NothingType(),), pytd_type.parameters)
271
272  def test_typing_container(self):
273    cls = self._vm.convert.list_type
274    container = abstract.AnnotationContainer("List", self._vm, cls)
275    expected = pytd.GenericType(pytd.NamedType("builtins.list"),
276                                (pytd.AnythingType(),))
277    actual = container.get_instance_type(self._vm.root_node)
278    self.assertEqual(expected, actual)
279
280
281# TODO(rechen): Test InterpreterFunction.
282class FunctionTest(AbstractTestBase):
283
284  def _make_pytd_function(self, params, name="f"):
285    pytd_params = []
286    for i, p in enumerate(params):
287      p_type = pytd.ClassType(p.name)
288      p_type.cls = p
289      pytd_params.append(
290          pytd.Parameter(function.argname(i), p_type, False, False, None))
291    pytd_sig = pytd.Signature(
292        tuple(pytd_params), None, None, pytd.AnythingType(), (), ())
293    sig = function.PyTDSignature(name, pytd_sig, self._vm)
294    return abstract.PyTDFunction(
295        name, (sig,), pytd.MethodTypes.METHOD, self._vm)
296
297  def _call_pytd_function(self, f, args):
298    b = f.to_binding(self._vm.root_node)
299    return f.call(self._vm.root_node, b, function.Args(posargs=args))
300
301  def test_call_with_empty_arg(self):
302    self.assertRaises(AssertionError, self._call_pytd_function,
303                      self._make_pytd_function(params=()),
304                      (self._vm.program.NewVariable(),))
305
306  def test_call_with_bad_arg(self):
307    f = self._make_pytd_function(
308        (self._vm.lookup_builtin("builtins.str"),))
309    arg = self._vm.convert.primitive_class_instances[int].to_variable(
310        self._vm.root_node)
311    self.assertRaises(
312        function.WrongArgTypes, self._call_pytd_function, f, (arg,))
313
314  def test_simple_call(self):
315    f = self._make_pytd_function(
316        (self._vm.lookup_builtin("builtins.str"),))
317    arg = self._vm.convert.primitive_class_instances[str].to_variable(
318        self._vm.root_node)
319    node, ret = self._call_pytd_function(f, (arg,))
320    self.assertIs(node, self._vm.root_node)
321    retval, = ret.bindings
322    self.assertIs(retval.data, self._vm.convert.unsolvable)
323
324  def test_call_with_multiple_arg_bindings(self):
325    f = self._make_pytd_function(
326        (self._vm.lookup_builtin("builtins.str"),))
327    arg = self._vm.program.NewVariable()
328    arg.AddBinding(self._vm.convert.primitive_class_instances[str], [],
329                   self._vm.root_node)
330    arg.AddBinding(self._vm.convert.primitive_class_instances[int], [],
331                   self._vm.root_node)
332    node, ret = self._call_pytd_function(f, (arg,))
333    self.assertIs(node, self._vm.root_node)
334    retval, = ret.bindings
335    self.assertIs(retval.data, self._vm.convert.unsolvable)
336
337  def test_call_with_skipped_combination(self):
338    f = self._make_pytd_function(
339        (self._vm.lookup_builtin("builtins.str"),))
340    node = self._vm.root_node.ConnectNew()
341    arg = self._vm.convert.primitive_class_instances[str].to_variable(node)
342    node, ret = self._call_pytd_function(f, (arg,))
343    self.assertIs(node, self._vm.root_node)
344    self.assertFalse(ret.bindings)
345
346  def test_signature_from_pytd(self):
347    # def f(self: Any, *args: Any)
348    self_param = pytd.Parameter("self", pytd.AnythingType(), False, False, None)
349    args_param = pytd.Parameter("args", pytd.AnythingType(), False, True, None)
350    sig = function.Signature.from_pytd(
351        self._vm, "f", pytd.Signature(
352            (self_param,), args_param, None, pytd.AnythingType(), (), ()))
353    self.assertEqual(repr(sig), "def f(self: Any, *args: Any) -> Any")
354    self.assertEqual(sig.name, "f")
355    self.assertSequenceEqual(sig.param_names, ("self",))
356    self.assertEqual(sig.varargs_name, "args")
357    self.assertFalse(sig.kwonly_params)
358    self.assertIs(sig.kwargs_name, None)
359    self.assertSetEqual(set(sig.annotations), {"self", "args", "return"})
360    self.assertTrue(sig.has_return_annotation)
361    self.assertTrue(sig.has_param_annotations)
362
363  def test_signature_from_callable(self):
364    # Callable[[int, str], Any]
365    params = {0: self._vm.convert.int_type, 1: self._vm.convert.str_type}
366    params[abstract_utils.ARGS] = abstract.Union(
367        (params[0], params[1]), self._vm)
368    params[abstract_utils.RET] = self._vm.convert.unsolvable
369    callable_val = abstract.CallableClass(
370        self._vm.convert.function_type, params, self._vm)
371    sig = function.Signature.from_callable(callable_val)
372    self.assertEqual(repr(sig), "def <callable>(_0: int, _1: str) -> Any")
373    self.assertEqual(sig.name, "<callable>")
374    self.assertSequenceEqual(sig.param_names, ("_0", "_1"))
375    self.assertIs(sig.varargs_name, None)
376    self.assertFalse(sig.kwonly_params)
377    self.assertIs(sig.kwargs_name, None)
378    self.assertCountEqual(sig.annotations.keys(), sig.param_names)
379    self.assertFalse(sig.has_return_annotation)
380    self.assertTrue(sig.has_param_annotations)
381
382  def test_signature_annotations(self):
383    # def f(self: Any, *args: Any)
384    self_param = pytd.Parameter("self", pytd.AnythingType(), False, False, None)
385    # Imitate the parser's conversion of '*args: Any' to '*args: Tuple[Any]'.
386    tup = pytd.ClassType("builtins.tuple")
387    tup.cls = self._vm.convert.tuple_type.pytd_cls
388    any_tuple = pytd.GenericType(tup, (pytd.AnythingType(),))
389    args_param = pytd.Parameter("args", any_tuple, False, True, None)
390    sig = function.Signature.from_pytd(
391        self._vm, "f", pytd.Signature(
392            (self_param,), args_param, None, pytd.AnythingType(), (), ()))
393    self.assertEqual(repr(sig),
394                     "def f(self: Any, *args: Tuple[Any, ...]) -> Any")
395    self.assertIs(sig.annotations["self"], self._vm.convert.unsolvable)
396    args_type = sig.annotations["args"]
397    self.assertIsInstance(args_type, abstract.ParameterizedClass)
398    self.assertIs(args_type.base_cls, self._vm.convert.tuple_type)
399    self.assertListEqual(list(args_type.formal_type_parameters.items()),
400                         [(abstract_utils.T, self._vm.convert.unsolvable)])
401    self.assertIs(sig.drop_first_parameter().annotations["args"], args_type)
402
403  def test_signature_annotations_existence(self):
404    # def f(v: "X") -> "Y"
405    sig = function.Signature(
406        name="f",
407        param_names=("v",),
408        varargs_name=None,
409        kwonly_params=(),
410        kwargs_name=None,
411        defaults={},
412        annotations={},
413    )
414    self.assertFalse(sig.has_param_annotations)
415    self.assertFalse(sig.has_return_annotation)
416    sig.set_annotation("v", self._vm.convert.unsolvable)
417    self.assertTrue(sig.has_param_annotations)
418    self.assertFalse(sig.has_return_annotation)
419    sig.set_annotation("return", self._vm.convert.unsolvable)
420    self.assertTrue(sig.has_param_annotations)
421    self.assertTrue(sig.has_return_annotation)
422
423  def test_signature_posarg_only_param_count(self):
424    # def f(x): ...
425    sig = function.Signature(
426        name="f",
427        param_names=("x",),
428        varargs_name=None,
429        kwonly_params=(),
430        kwargs_name=None,
431        defaults={},
432        annotations={},
433    )
434    self.assertEqual(repr(sig), "def f(x) -> Any")
435    self.assertEqual(sig.mandatory_param_count(), 1)
436    self.assertEqual(sig.maximum_param_count(), 1)
437
438  def test_signature_posarg_and_kwarg_param_count(self):
439    # def f(x, y=None): ...
440    sig = function.Signature(
441        name="f",
442        param_names=("x", "y",),
443        varargs_name=None,
444        kwonly_params=(),
445        kwargs_name=None,
446        defaults={"y": self._vm.convert.none_type.to_variable(self._node)},
447        annotations={},
448    )
449    self.assertEqual(repr(sig), "def f(x, y = None) -> Any")
450    self.assertEqual(sig.mandatory_param_count(), 1)
451    self.assertEqual(sig.maximum_param_count(), 2)
452
453  def test_signature_varargs_param_count(self):
454    # def f(*args): ...
455    sig = function.Signature(
456        name="f",
457        param_names=(),
458        varargs_name="args",
459        kwonly_params=(),
460        kwargs_name=None,
461        defaults={},
462        annotations={},
463    )
464    self.assertEqual(repr(sig), "def f(*args) -> Any")
465    self.assertEqual(sig.mandatory_param_count(), 0)
466    self.assertIsNone(sig.maximum_param_count())
467
468  def test_signature_kwargs_param_count(self):
469    # def f(**kwargs): ...
470    sig = function.Signature(
471        name="f",
472        param_names=(),
473        varargs_name=None,
474        kwonly_params=(),
475        kwargs_name="kwargs",
476        defaults={},
477        annotations={},
478    )
479    self.assertEqual(repr(sig), "def f(**kwargs) -> Any")
480    self.assertEqual(sig.mandatory_param_count(), 0)
481    self.assertIsNone(sig.maximum_param_count())
482
483  def test_signature_kwonly_param_count(self):
484    # def f(*, y=None): ...
485    sig = function.Signature(
486        name="f",
487        param_names=(),
488        varargs_name=None,
489        kwonly_params=("y",),
490        kwargs_name=None,
491        defaults={"y": self._vm.convert.none_type.to_variable(self._node)},
492        annotations={},
493    )
494    self.assertEqual(repr(sig), "def f(*, y = None) -> Any")
495    self.assertEqual(sig.mandatory_param_count(), 0)
496    self.assertEqual(sig.maximum_param_count(), 1)
497
498  def test_signature_has_param(self):
499    # def f(x, *args, y, **kwargs): ...
500    sig = function.Signature(
501        name="f",
502        param_names=("x",),
503        varargs_name="args",
504        kwonly_params={"y"},
505        kwargs_name="kwargs",
506        defaults={},
507        annotations={},
508    )
509    self.assertEqual(repr(sig), "def f(x, *args, y, **kwargs) -> Any")
510    for param in ("x", "args", "y", "kwargs"):
511      self.assertTrue(sig.has_param(param))
512    self.assertFalse(sig.has_param("rumpelstiltskin"))
513
514  def test_signature_insert_varargs_and_kwargs(self):
515    # def f(x, *args, y, **kwargs): ...
516    sig = function.Signature(
517        name="f",
518        param_names=("x",),
519        varargs_name="args",
520        kwonly_params={"y"},
521        kwargs_name="kwargs",
522        defaults={},
523        annotations={},
524    )
525    # f(1, 2, y=3, z=4)
526    int_inst = self._vm.convert.primitive_class_instances[int]
527    int_binding = int_inst.to_binding(self._node)
528    arg_dict = {
529        "x": int_binding, "_1": int_binding, "y": int_binding, "z": int_binding}
530    sig = sig.insert_varargs_and_kwargs(arg_dict)
531    self.assertEqual(sig.name, "f")
532    self.assertSequenceEqual(sig.param_names, ("x", "_1", "z"))
533    self.assertEqual(sig.varargs_name, "args")
534    self.assertSetEqual(sig.kwonly_params, {"y"})
535    self.assertEqual(sig.kwargs_name, "kwargs")
536    self.assertFalse(sig.annotations)
537
538  def test_signature_del_param_annotation(self):
539    # def f(x) -> int: ...
540    sig = function.Signature(
541        name="f",
542        param_names=("x",),
543        varargs_name=None,
544        kwonly_params=(),
545        kwargs_name=None,
546        defaults={},
547        annotations={"x": self._vm.convert.unsolvable,
548                     "return": self._vm.convert.unsolvable},
549    )
550    sig.del_annotation("x")
551    self.assertCountEqual(sig.annotations.keys(), {"return"})
552    self.assertFalse(sig.has_param_annotations)
553    self.assertTrue(sig.has_return_annotation)
554
555  def test_signature_del_return_annotation(self):
556    # def f(x) -> int: ...
557    sig = function.Signature(
558        name="f",
559        param_names=("x",),
560        varargs_name=None,
561        kwonly_params=(),
562        kwargs_name=None,
563        defaults={},
564        annotations={"x": self._vm.convert.unsolvable,
565                     "return": self._vm.convert.unsolvable},
566    )
567    sig.del_annotation("return")
568    self.assertCountEqual(sig.annotations.keys(), {"x"})
569    self.assertTrue(sig.has_param_annotations)
570    self.assertFalse(sig.has_return_annotation)
571
572  def test_signature_del_nonexistent_annotation(self):
573    # def f(): ...
574    sig = function.Signature(
575        name="f",
576        param_names=(),
577        varargs_name=None,
578        kwonly_params=(),
579        kwargs_name=None,
580        defaults={},
581        annotations={},
582    )
583    self.assertRaises(KeyError, sig.del_annotation, "rumpelstiltskin")
584
585  def test_constructor_args(self):
586    f = abstract.PyTDFunction.make("open", self._vm, "builtins")
587    self.assertEqual(f.full_name, "builtins.open")
588    self.assertCountEqual(
589        {sig.pytd_sig for sig in f.signatures},
590        self._vm.lookup_builtin("builtins.open").signatures)
591    self.assertIs(f.kind, pytd.MethodTypes.METHOD)
592    self.assertIs(f.vm, self._vm)
593
594  def test_constructor_args_pyval(self):
595    sig = pytd.Signature((), None, None, pytd.AnythingType(), (), ())
596    pyval = pytd.Function("blah", (sig,), pytd.MethodTypes.STATICMETHOD, 0)
597    f = abstract.PyTDFunction.make("open", self._vm, "builtins", pyval=pyval)
598    self.assertEqual(f.full_name, "builtins.open")
599    f_sig, = f.signatures
600    self.assertIs(f_sig.pytd_sig, sig)
601    self.assertIs(f.kind, pytd.MethodTypes.STATICMETHOD)
602    self.assertIs(f.vm, self._vm)
603
604  def test_get_constructor_args(self):
605    f = abstract.PyTDFunction.make(
606        "TypeVar", self._vm, "typing", pyval_name="_typevar_new")
607    self.assertEqual(f.full_name, "typing.TypeVar")
608    self.assertCountEqual(
609        {sig.pytd_sig for sig in f.signatures},
610        self._vm.loader.import_name("typing").Lookup(
611            "typing._typevar_new").signatures)
612    self.assertIs(f.kind, pytd.MethodTypes.METHOD)
613    self.assertIs(f.vm, self._vm)
614
615  def test_bound_function_repr(self):
616    f = self._make_pytd_function(params=())
617    callself = self._vm.program.NewVariable(
618        [abstract.BaseValue(name, self._vm) for name in ("test1", "test2")], [],
619        self._vm.root_node)
620    bound = abstract.BoundFunction(callself, f)
621    self.assertCountEqual(bound.repr_names(), ["test1.f", "test2.f"])
622    self.assertRegex(repr(bound), r"test(1|2)\.f")
623
624  def test_bound_function_callself_repr(self):
625    f = self._make_pytd_function(params=())
626    callself = self._vm.program.NewVariable(
627        [abstract.BaseValue("test", self._vm)], [], self._vm.root_node)
628    bound = abstract.BoundFunction(callself, f)
629    callself_repr = lambda v: v.name + "foo"
630    self.assertCountEqual(bound.repr_names(callself_repr), ["testfoo.f"])
631
632  def test_bound_function_nested_repr(self):
633    f = self._make_pytd_function(params=())
634    callself1 = self._vm.program.NewVariable(
635        [abstract.BaseValue("test1", self._vm)], [], self._vm.root_node)
636    bound1 = abstract.BoundFunction(callself1, f)
637    callself2 = self._vm.program.NewVariable(
638        [abstract.BaseValue("test2", self._vm)], [], self._vm.root_node)
639    bound2 = abstract.BoundFunction(callself2, bound1)
640    # `bound2` is BoundFunction(test2, BoundFunction(test1, f))
641    self.assertCountEqual(bound2.repr_names(), ["test2.f"])
642
643  def test_bound_function_repr_no_callself(self):
644    f = self._make_pytd_function(params=())
645    callself = self._vm.program.NewVariable()
646    bound = abstract.BoundFunction(callself, f)
647    self.assertCountEqual(bound.repr_names(), ["<class>.f"])
648
649  def test_bound_function_repr_replace_parent(self):
650    f = self._make_pytd_function(params=(), name="foo.f")
651    callself = self._vm.program.NewVariable(
652        [abstract.BaseValue("test", self._vm)], [], self._vm.root_node)
653    bound = abstract.BoundFunction(callself, f)
654    self.assertCountEqual(bound.repr_names(), ["test.f"])
655
656
657class AbstractMethodsTest(AbstractTestBase):
658
659  def test_abstract_method(self):
660    func = abstract.Function("f", self._vm).to_variable(self._vm.root_node)
661    func.data[0].is_abstract = True
662    cls = abstract.InterpreterClass("X", [], {"f": func}, None, self._vm)
663    self.assertCountEqual(cls.abstract_methods, {"f"})
664
665  def test_inherited_abstract_method(self):
666    sized_pytd = self._vm.loader.typing.Lookup("typing.Sized")
667    sized = self._vm.convert.constant_to_value(sized_pytd, {},
668                                               self._vm.root_node)
669    cls = abstract.InterpreterClass("X",
670                                    [sized.to_variable(self._vm.root_node)], {},
671                                    None, self._vm)
672    self.assertCountEqual(cls.abstract_methods, {"__len__"})
673
674  def test_overridden_abstract_method(self):
675    sized_pytd = self._vm.loader.typing.Lookup("typing.Sized")
676    sized = self._vm.convert.constant_to_value(sized_pytd, {},
677                                               self._vm.root_node)
678    bases = [sized.to_variable(self._vm.root_node)]
679    members = {"__len__": self._vm.new_unsolvable(self._vm.root_node)}
680    cls = abstract.InterpreterClass("X", bases, members, None, self._vm)
681    self.assertFalse(cls.abstract_methods)
682
683  def test_overridden_abstract_method_still_abstract(self):
684    sized_pytd = self._vm.loader.typing.Lookup("typing.Sized")
685    sized = self._vm.convert.constant_to_value(sized_pytd, {},
686                                               self._vm.root_node)
687    bases = [sized.to_variable(self._vm.root_node)]
688    func = abstract.Function("__len__", self._vm)
689    func.is_abstract = True
690    members = {"__len__": func.to_variable(self._vm.root_node)}
691    cls = abstract.InterpreterClass("X", bases, members, None, self._vm)
692    self.assertCountEqual(cls.abstract_methods, {"__len__"})
693
694
695class SimpleFunctionTest(AbstractTestBase):
696
697  def _make_func(self, name="_", param_names=None, varargs_name=None,
698                 kwonly_params=(), kwargs_name=None, defaults=(),
699                 annotations=None):
700    return abstract.SimpleFunction(name, param_names or (), varargs_name,
701                                   kwonly_params, kwargs_name, defaults,
702                                   annotations or {}, self._vm)
703
704  def _simple_sig(self, param_types, ret_type=None):
705    annots = {("_%d" % i): t for i, t in enumerate(param_types)}
706    params = tuple(annots.keys())
707    if ret_type:
708      annots["return"] = ret_type
709    return self._make_func(param_names=params, annotations=annots)
710
711  def test_simple_call(self):
712    f = self._simple_sig([self._vm.convert.str_type],
713                         ret_type=self._vm.convert.int_type)
714    args = function.Args((self._vm.convert.build_string(self._vm.root_node,
715                                                        "hello"),))
716    node, ret = f.call(self._vm.root_node, f, args)
717    self.assertIs(node, self._vm.root_node)
718    ret_val, = ret.data
719    self.assertEqual(ret_val.cls, self._vm.convert.int_type)
720
721  def test_call_with_bad_arg(self):
722    f = self._make_func(param_names=("test",),
723                        annotations={"test": self._vm.convert.str_type})
724    args = function.Args((self._vm.convert.build_int(self._vm.root_node),))
725    self.assertRaises(function.WrongArgTypes, f.call, self._vm.root_node, f,
726                      args)
727
728  def test_call_with_no_args(self):
729    f = self._simple_sig([self._vm.convert.str_type, self._vm.convert.int_type])
730    args = function.Args(())
731    self.assertRaises(function.MissingParameter, f.call, self._vm.root_node, f,
732                      args)
733
734  def test_call_with_multiple_arg_bindings(self):
735    f = self._simple_sig([self._vm.convert.str_type])
736    arg = self._vm.program.NewVariable()
737    arg.AddBinding(self._vm.convert.primitive_class_instances[str], [],
738                   self._vm.root_node)
739    arg.AddBinding(self._vm.convert.primitive_class_instances[int], [],
740                   self._vm.root_node)
741    args = function.Args((arg,))
742    node, ret = f.call(self._vm.root_node, f, args)
743    self.assertIs(node, self._vm.root_node)
744    self.assertIs(ret.data[0], self._vm.convert.none)
745
746  def test_call_with_varargs(self):
747    f = self._make_func(
748        varargs_name="arg",
749        annotations={"arg": self._vm.convert.str_type,
750                     "return": self._vm.convert.str_type}
751    )
752    starargs = abstract.Tuple(
753        (self._vm.convert.build_string(self._vm.root_node, ""),),
754        self._vm).to_variable(self._vm.root_node)
755    args = function.Args(posargs=(), starargs=starargs)
756    node, ret = f.call(self._vm.root_node, f, args)
757    self.assertIs(node, self._vm.root_node)
758    self.assertIs(ret.data[0].cls, self._vm.convert.str_type)
759
760  def test_call_with_bad_varargs(self):
761    f = self._make_func(
762        varargs_name="arg",
763        annotations={"arg": self._vm.convert.str_type})
764    starargs = abstract.Tuple(
765        (self._vm.convert.build_string(self._vm.root_node, ""),
766         self._vm.convert.build_int(self._vm.root_node)),
767        self._vm).to_variable(self._vm.root_node)
768    args = function.Args(posargs=(), starargs=starargs)
769    self.assertRaises(function.WrongArgTypes, f.call, self._vm.root_node, f,
770                      args)
771
772  def test_call_with_multiple_varargs_bindings(self):
773    f = self._make_func(
774        varargs_name="arg",
775        annotations={"arg": self._vm.convert.str_type})
776    arg = self._vm.program.NewVariable()
777    arg.AddBinding(self._vm.convert.primitive_class_instances[str], [],
778                   self._vm.root_node)
779    arg.AddBinding(self._vm.convert.primitive_class_instances[int], [],
780                   self._vm.root_node)
781    starargs = abstract.Tuple((arg,), self._vm)
782    starargs = starargs.to_variable(self._vm.root_node)
783    args = function.Args(posargs=(), starargs=starargs)
784    f.call(self._vm.root_node, f, args)
785
786  def test_call_with_kwargs(self):
787    f = self._make_func(
788        kwargs_name="kwarg",
789        annotations={"kwarg": self._vm.convert.str_type})
790    kwargs = abstract.Dict(self._vm)
791    kwargs.update(
792        self._vm.root_node, {
793            "_1": self._vm.convert.build_string(self._vm.root_node, "1"),
794            "_2": self._vm.convert.build_string(self._vm.root_node, "2")
795        })
796    kwargs = kwargs.to_variable(self._vm.root_node)
797    args = function.Args(
798        posargs=(),
799        namedargs=abstract.Dict(self._vm),
800        starstarargs=kwargs
801    )
802    f.call(self._vm.root_node, f, args)
803
804  def test_call_with_bad_kwargs(self):
805    f = self._make_func(
806        kwargs_name="kwarg",
807        annotations={"kwarg": self._vm.convert.str_type})
808    kwargs = abstract.Dict(self._vm)
809    kwargs.update(self._vm.root_node,
810                  {"_1": self._vm.convert.build_int(self._vm.root_node)})
811    kwargs = kwargs.to_variable(self._vm.root_node)
812    args = function.Args(
813        posargs=(),
814        namedargs=abstract.Dict(self._vm),
815        starstarargs=kwargs
816    )
817    self.assertRaises(function.WrongArgTypes, f.call, self._vm.root_node, f,
818                      args)
819
820  def test_call_with_kwonly_args(self):
821    f = self._make_func(
822        param_names=("test",),
823        kwonly_params=("a", "b"),
824        annotations={
825            "test": self._vm.convert.str_type,
826            "a": self._vm.convert.str_type,
827            "b": self._vm.convert.str_type
828        }
829    )
830    kwargs = abstract.Dict(self._vm)
831    kwargs.update(
832        self._vm.root_node, {
833            "a": self._vm.convert.build_string(self._vm.root_node, "2"),
834            "b": self._vm.convert.build_string(self._vm.root_node, "3")
835        })
836    kwargs = kwargs.to_variable(self._vm.root_node)
837    args = function.Args(
838        posargs=(self._vm.convert.build_string(self._vm.root_node, "1"),),
839        namedargs=abstract.Dict(self._vm),
840        starstarargs=kwargs)
841    f.call(self._vm.root_node, f, args)
842    kwargs = abstract.Dict(self._vm)
843    kwargs.update(self._vm.root_node,
844                  {"b": self._vm.convert.build_string(self._vm.root_node, "3")})
845    kwargs = kwargs.to_variable(self._vm.root_node)
846    args = function.Args(
847        posargs=(self._vm.convert.build_string(self._vm.root_node, "1"),
848                 self._vm.convert.build_int(self._vm.root_node)),
849        namedargs=abstract.Dict(self._vm),
850        starstarargs=kwargs)
851    self.assertRaises(function.MissingParameter, f.call, self._vm.root_node, f,
852                      args)
853
854  def test_call_with_all_args(self):
855    f = self._make_func(
856        param_names=("a", "b", "c"),
857        varargs_name="arg",
858        kwargs_name="kwarg",
859        defaults=(self._vm.convert.build_int(self._vm.root_node),),
860        annotations={
861            "a": self._vm.convert.str_type,
862            "b": self._vm.convert.int_type,
863            "c": self._vm.convert.int_type,
864            "arg": self._vm.convert.primitive_classes[float],
865            "kwarg": self._vm.convert.primitive_classes[bool]
866        })
867    posargs = (self._vm.convert.build_string(self._vm.root_node, "1"),
868               self._vm.convert.build_int(self._vm.root_node))
869    float_inst = self._vm.convert.primitive_class_instances[float]
870    stararg = abstract.Tuple((float_inst.to_variable(self._vm.root_node),),
871                             self._vm).to_variable(self._vm.root_node)
872    namedargs = abstract.Dict(self._vm)
873    kwarg = abstract.Dict(self._vm)
874    kwarg.update(
875        self._vm.root_node, {
876            "x": self._vm.convert.build_bool(self._vm.root_node),
877            "y": self._vm.convert.build_bool(self._vm.root_node)
878        })
879    kwarg = kwarg.to_variable(self._vm.root_node)
880    args = function.Args(posargs, namedargs, stararg, kwarg)
881    f.call(self._vm.root_node, f, args)
882
883  def test_call_with_defaults(self):
884    f = self._make_func(
885        param_names=("a", "b", "c"),
886        defaults=(self._vm.convert.build_int(self._vm.root_node),),
887        annotations={
888            "a": self._vm.convert.int_type,
889            "b": self._vm.convert.int_type,
890            "c": self._vm.convert.int_type
891        })
892    args = function.Args(
893        posargs=(self._vm.convert.build_int(self._vm.root_node),
894                 self._vm.convert.build_int(self._vm.root_node)))
895    f.call(self._vm.root_node, f, args)
896    args = function.Args(
897        posargs=(self._vm.convert.build_int(self._vm.root_node),
898                 self._vm.convert.build_int(self._vm.root_node),
899                 self._vm.convert.build_int(self._vm.root_node)))
900    f.call(self._vm.root_node, f, args)
901    args = function.Args(
902        posargs=(self._vm.convert.build_int(self._vm.root_node),))
903    self.assertRaises(function.MissingParameter, f.call, self._vm.root_node, f,
904                      args)
905
906  def test_call_with_bad_default(self):
907    f = self._make_func(
908        param_names=("a", "b"),
909        defaults=(self._vm.convert.build_string(self._vm.root_node, ""),),
910        annotations={
911            "a": self._vm.convert.int_type,
912            "b": self._vm.convert.str_type
913        })
914    args = function.Args(
915        posargs=(self._vm.convert.build_int(self._vm.root_node),
916                 self._vm.convert.build_int(self._vm.root_node)))
917    self.assertRaises(function.WrongArgTypes, f.call, self._vm.root_node, f,
918                      args)
919
920  def test_call_with_duplicate_keyword(self):
921    f = self._simple_sig([self._vm.convert.int_type]*2)
922    args = function.Args(
923        posargs=(self._vm.convert.build_int(self._vm.root_node),
924                 self._vm.convert.build_int(self._vm.root_node)),
925        namedargs={"_1": self._vm.convert.build_int(self._vm.root_node)})
926    self.assertRaises(function.DuplicateKeyword, f.call, self._vm.root_node, f,
927                      args)
928
929  def test_call_with_wrong_arg_count(self):
930    f = self._simple_sig([self._vm.convert.int_type])
931    args = function.Args(
932        posargs=(self._vm.convert.build_int(self._vm.root_node),
933                 self._vm.convert.build_int(self._vm.root_node)))
934    self.assertRaises(function.WrongArgCount, f.call, self._vm.root_node, f,
935                      args)
936
937  def test_change_defaults(self):
938    f = self._make_func(
939        param_names=("a", "b", "c"),
940        defaults=(self._vm.convert.build_int(self._vm.root_node),))
941    args = function.Args(
942        posargs=(self._vm.convert.build_int(self._vm.root_node),
943                 self._vm.convert.build_int(self._vm.root_node)))
944    f.call(self._vm.root_node, f, args)
945    new_defaults = abstract.Tuple((self._vm.convert.build_int(
946        self._vm.root_node), self._vm.convert.build_int(self._vm.root_node)),
947                                  self._vm).to_variable(self._vm.root_node)
948    f.set_function_defaults(self._vm.root_node, new_defaults)
949    f.call(self._vm.root_node, f, args)
950    args = function.Args(
951        posargs=(self._vm.convert.build_int(self._vm.root_node),))
952    f.call(self._vm.root_node, f, args)
953
954  def test_call_with_type_parameter(self):
955    ret_cls = abstract.ParameterizedClass(
956        self._vm.convert.list_type,
957        {abstract_utils.T: abstract.TypeParameter(abstract_utils.T, self._vm)},
958        self._vm
959    )
960    f = self._make_func(
961        param_names=("test",),
962        annotations={
963            "test": abstract.TypeParameter(abstract_utils.T, self._vm),
964            "return": ret_cls
965        }
966    )
967    args = function.Args(
968        posargs=(self._vm.convert.build_int(self._vm.root_node),))
969    _, ret = f.call(self._vm.root_node, f, args)
970    # ret is an Instance(ParameterizedClass(list, {abstract_utils.T: int}))
971    # but we really only care about T.
972    self.assertIs(ret.data[0].cls.formal_type_parameters[abstract_utils.T],
973                  self._vm.convert.int_type)
974
975  def test_signature_func_output_basic(self):
976    node = self._vm.root_node
977    f = self._make_func(name="basic", param_names=("a", "b"))
978    fp = self._vm.convert.pytd_convert.value_to_pytd_def(node, f, f.name)
979    self.assertEqual(pytd_utils.Print(fp), "def basic(a, b) -> None: ...")
980
981  def test_signature_func_output_annotations(self):
982    node = self._vm.root_node
983    f = self._make_func(
984        name="annots",
985        param_names=("a", "b"),
986        annotations={
987            "a": self._vm.convert.int_type,
988            "b": self._vm.convert.str_type,
989            "return": self._vm.convert.int_type
990        }
991    )
992    fp = self._vm.convert.pytd_convert.value_to_pytd_def(node, f, f.name)
993    self.assertEqual(pytd_utils.Print(fp),
994                     "def annots(a: int, b: str) -> int: ...")
995
996  def test_signature_func_output(self):
997    node = self._vm.root_node
998    dict_type = abstract.ParameterizedClass(
999        self._vm.convert.dict_type,
1000        {abstract_utils.K: self._vm.convert.str_type,
1001         abstract_utils.V: self._vm.convert.int_type},
1002        self._vm)
1003    f = self._make_func(
1004        name="test",
1005        param_names=("a", "b"),
1006        varargs_name="c",
1007        kwonly_params=("d", "e"),
1008        kwargs_name="f",
1009        defaults={
1010            "b": self._vm.convert.build_int(node),
1011            "d": self._vm.convert.build_int(node)
1012        },
1013        annotations={
1014            "a": self._vm.convert.str_type,
1015            "b": self._vm.convert.int_type,
1016            "c": self._vm.convert.str_type,
1017            "d": dict_type,
1018            "e": self._vm.convert.int_type,
1019            "f": self._vm.convert.str_type,
1020            "return": self._vm.convert.str_type
1021        }
1022    )
1023    fp = self._vm.convert.pytd_convert.value_to_pytd_def(node, f, f.name)
1024    f_str = ("def test(a: str, b: int = ..., *c: str, d: Dict[str, int] = ...,"
1025             " e: int, **f: str) -> str: ...")
1026    self.assertEqual(pytd_utils.Print(fp), f_str)
1027
1028
1029class AbstractTest(AbstractTestBase):
1030
1031  def test_interpreter_class_official_name(self):
1032    cls = abstract.InterpreterClass("X", [], {}, None, self._vm)
1033    cls.update_official_name("Z")
1034    self.assertEqual(cls.official_name, "Z")
1035    cls.update_official_name("A")  # takes effect because A < Z
1036    self.assertEqual(cls.official_name, "A")
1037    cls.update_official_name("Z")  # no effect
1038    self.assertEqual(cls.official_name, "A")
1039    cls.update_official_name("X")  # takes effect because X == cls.name
1040    self.assertEqual(cls.official_name, "X")
1041    cls.update_official_name("A")  # no effect
1042    self.assertEqual(cls.official_name, "X")
1043
1044  def test_type_parameter_official_name(self):
1045    param = abstract.TypeParameter("T", self._vm)
1046    self._vm.frame = frame_state.SimpleFrame()  # for error logging
1047    param.update_official_name("T")
1048    self.assertFalse(self._vm.errorlog.has_error())
1049    param.update_official_name("Q")
1050    self.assertTrue(self._vm.errorlog.has_error())
1051
1052  def test_type_parameter_equality(self):
1053    param1 = abstract.TypeParameter("S", self._vm)
1054    param2 = abstract.TypeParameter("T", self._vm)
1055    cls = abstract.InterpreterClass("S", [], {}, None, self._vm)
1056    self.assertEqual(param1, param1)
1057    self.assertNotEqual(param1, param2)
1058    self.assertNotEqual(param1, cls)
1059
1060  def test_union_equality(self):
1061    union1 = abstract.Union((self._vm.convert.unsolvable,), self._vm)
1062    union2 = abstract.Union((self._vm.convert.none,), self._vm)
1063    cls = abstract.InterpreterClass("Union", [], {}, None, self._vm)
1064    self.assertEqual(union1, union1)
1065    self.assertNotEqual(union1, union2)
1066    self.assertNotEqual(union1, cls)
1067
1068  def test_instantiate_type_parameter_type(self):
1069    params = {
1070        abstract_utils.T: abstract.TypeParameter(abstract_utils.T, self._vm)}
1071    cls = abstract.ParameterizedClass(
1072        self._vm.convert.type_type, params, self._vm)
1073    self.assertListEqual(cls.instantiate(self._node).data,
1074                         [self._vm.convert.unsolvable])
1075
1076  def test_super_type(self):
1077    supercls = special_builtins.Super(self._vm)
1078    self.assertEqual(supercls.get_class(), self._vm.convert.type_type)
1079
1080  def test_instantiate_interpreter_class(self):
1081    cls = abstract.InterpreterClass("X", [], {}, None, self._vm)
1082    # When there is no current frame, create a new instance every time.
1083    v1 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
1084    v2 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
1085    self.assertIsNot(v1, v2)
1086    # Create one instance per opcode.
1087    fake_opcode = object()
1088    self._vm.push_frame(frame_state.SimpleFrame(fake_opcode))
1089    v3 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
1090    v4 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
1091    self.assertIsNot(v1, v3)
1092    self.assertIsNot(v2, v3)
1093    self.assertIs(v3, v4)
1094
1095  def test_set_module_on_module(self):
1096    # A module's 'module' attribute should always remain None, and no one
1097    # should attempt to set it to something besides the module's name or None.
1098    ast = pytd_utils.CreateModule("some_mod")
1099    mod = abstract.Module(self._vm, ast.name, {}, ast)
1100    mod.module = ast.name
1101    self.assertIsNone(mod.module)
1102    self.assertEqual(ast.name, mod.full_name)
1103    mod.module = None
1104    self.assertIsNone(mod.module)
1105    self.assertEqual(ast.name, mod.full_name)
1106    def set_module():
1107      mod.module = "other_mod"
1108    self.assertRaises(AssertionError, set_module)
1109
1110  def test_call_type_parameter_instance(self):
1111    instance = abstract.Instance(self._vm.convert.list_type, self._vm)
1112    instance.merge_instance_type_parameter(
1113        self._vm.root_node, abstract_utils.T,
1114        self._vm.convert.int_type.to_variable(self._vm.root_node))
1115    t = abstract.TypeParameter(abstract_utils.T, self._vm)
1116    t_instance = abstract.TypeParameterInstance(t, instance, self._vm)
1117    node, ret = t_instance.call(self._node, t_instance.to_binding(self._node),
1118                                function.Args(posargs=()))
1119    self.assertIs(node, self._node)
1120    retval, = ret.data
1121    self.assertEqual(retval.cls, self._vm.convert.int_type)
1122
1123  def test_call_empty_type_parameter_instance(self):
1124    instance = abstract.Instance(self._vm.convert.list_type, self._vm)
1125    t = abstract.TypeParameter(abstract_utils.T, self._vm)
1126    t_instance = abstract.TypeParameterInstance(t, instance, self._vm)
1127    node, ret = t_instance.call(self._node, t_instance.to_binding(self._node),
1128                                function.Args(posargs=()))
1129    self.assertIs(node, self._node)
1130    retval, = ret.data
1131    self.assertIs(retval, self._vm.convert.empty)
1132
1133  def test_call_type_parameter_instance_with_wrong_args(self):
1134    instance = abstract.Instance(self._vm.convert.list_type, self._vm)
1135    instance.merge_instance_type_parameter(
1136        self._vm.root_node, abstract_utils.T,
1137        self._vm.convert.int_type.to_variable(self._vm.root_node))
1138    t = abstract.TypeParameter(abstract_utils.T, self._vm)
1139    t_instance = abstract.TypeParameterInstance(t, instance, self._vm)
1140    posargs = (self._vm.new_unsolvable(self._node),) * 3
1141    node, ret = t_instance.call(self._node, t_instance.to_binding(self._node),
1142                                function.Args(posargs=posargs))
1143    self.assertIs(node, self._node)
1144    self.assertTrue(ret.bindings)
1145    error, = self._vm.errorlog
1146    self.assertEqual(error.name, "wrong-arg-count")
1147
1148  def test_instantiate_tuple_class_for_sub(self):
1149    type_param = abstract.TypeParameter(abstract_utils.K, self._vm)
1150    cls = abstract.TupleClass(
1151        self._vm.convert.tuple_type,
1152        {0: type_param, abstract_utils.T: type_param}, self._vm)
1153    # Instantiate the tuple class.
1154    subst_value = cls.instantiate(self._vm.root_node,
1155                                  abstract_utils.DUMMY_CONTAINER)
1156    # Recover the class from the instance.
1157    subbed_cls = self._vm.annotations_util.sub_one_annotation(
1158        self._vm.root_node, type_param, [{
1159            abstract_utils.K: subst_value
1160        }])
1161    self.assertEqual(cls, subbed_cls)
1162
1163  def test_singleton(self):
1164    self.assertIs(abstract.Unsolvable(self._vm), abstract.Unsolvable(self._vm))
1165
1166  def test_singleton_subclass(self):
1167    self.assertIs(abstract.Empty(self._vm), abstract.Empty(self._vm))
1168    self.assertIsNot(abstract.Deleted(self._vm), abstract.Empty(self._vm))
1169
1170
1171if __name__ == "__main__":
1172  unittest.main()
1173