예제 #1
0
 def test_metaclass(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self._ctx)
   meta = abstract.InterpreterClass("M", [], {}, None, self._ctx)
   meta.official_name = "M"
   cls.cls = meta
   pytd_cls = cls.to_pytd_def(self._ctx.root_node, "X")
   self.assertEqual(pytd_cls.metaclass, pytd.NamedType("M"))
예제 #2
0
 def test_class_no_valself(self):
   meta_members = {"x": self.ctx.convert.none.to_variable(self.node)}
   meta = abstract.InterpreterClass("M", [], meta_members, None, self.ctx)
   cls = abstract.InterpreterClass("X", [], {}, meta, self.ctx)
   _, attr_var = self.attribute_handler.get_attribute(self.node, cls, "x")
   # Since `valself` was not passed to get_attribute, we do not look at the
   # metaclass, so M.x is not returned.
   self.assertIsNone(attr_var)
예제 #3
0
 def test_class_with_class_valself(self):
   meta_members = {"x": self.ctx.convert.none.to_variable(self.node)}
   meta = abstract.InterpreterClass("M", [], meta_members, None, self.ctx)
   cls = abstract.InterpreterClass("X", [], {}, meta, self.ctx)
   valself = cls.to_binding(self.node)
   _, attr_var = self.attribute_handler.get_attribute(
       self.node, cls, "x", valself)
   # Since `valself` is X itself, we look at the metaclass and return M.x.
   self.assertEqual(attr_var.data, [self.ctx.convert.none])
예제 #4
0
 def test_class_with_instance_valself(self):
   meta_members = {"x": self.ctx.convert.none.to_variable(self.node)}
   meta = abstract.InterpreterClass("M", [], meta_members, None, self.ctx)
   cls = abstract.InterpreterClass("X", [], {}, meta, self.ctx)
   valself = abstract.Instance(cls, self.ctx).to_binding(self.node)
   _, attr_var = self.attribute_handler.get_attribute(
       self.node, cls, "x", valself)
   # Since `valself` is an instance of X, we do not look at the metaclass, so
   # M.x is not returned.
   self.assertIsNone(attr_var)
예제 #5
0
 def test_metaclass_union(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self._ctx)
   meta1 = abstract.InterpreterClass("M1", [], {}, None, self._ctx)
   meta2 = abstract.InterpreterClass("M2", [], {}, None, self._ctx)
   meta1.official_name = "M1"
   meta2.official_name = "M2"
   cls.cls = abstract.Union([meta1, meta2], self._ctx)
   pytd_cls = cls.to_pytd_def(self._ctx.root_node, "X")
   self.assertEqual(pytd_cls.metaclass, pytd.UnionType(
       (pytd.NamedType("M1"), pytd.NamedType("M2"))))
예제 #6
0
 def test_inherited_metaclass(self):
   base = abstract.InterpreterClass("X", [], {}, None, self._ctx)
   base.official_name = "X"
   meta = abstract.InterpreterClass("M", [], {}, None, self._ctx)
   meta.official_name = "M"
   base.cls = meta
   child = abstract.InterpreterClass("Y",
                                     [base.to_variable(self._ctx.root_node)],
                                     {}, None, self._ctx)
   self.assertIs(child.cls, base.cls)
   pytd_cls = child.to_pytd_def(self._ctx.root_node, "Y")
   self.assertIs(pytd_cls.metaclass, None)
예제 #7
0
 def test_type_parameter_equality(self):
   param1 = abstract.TypeParameter("S", self._ctx)
   param2 = abstract.TypeParameter("T", self._ctx)
   cls = abstract.InterpreterClass("S", [], {}, None, self._ctx)
   self.assertEqual(param1, param1)
   self.assertNotEqual(param1, param2)
   self.assertNotEqual(param1, cls)
예제 #8
0
 def test_union_equality(self):
   union1 = abstract.Union((self._ctx.convert.unsolvable,), self._ctx)
   union2 = abstract.Union((self._ctx.convert.none,), self._ctx)
   cls = abstract.InterpreterClass("Union", [], {}, None, self._ctx)
   self.assertEqual(union1, union1)
   self.assertNotEqual(union1, union2)
   self.assertNotEqual(union1, cls)
예제 #9
0
 def test_inherited_abstract_method(self):
   sized_pytd = self._ctx.loader.typing.Lookup("typing.Sized")
   sized = self._ctx.convert.constant_to_value(sized_pytd, {},
                                               self._ctx.root_node)
   cls = abstract.InterpreterClass("X",
                                   [sized.to_variable(self._ctx.root_node)],
                                   {}, None, self._ctx)
   self.assertCountEqual(cls.abstract_methods, {"__len__"})
예제 #10
0
 def test_overridden_abstract_method(self):
   sized_pytd = self._ctx.loader.typing.Lookup("typing.Sized")
   sized = self._ctx.convert.constant_to_value(sized_pytd, {},
                                               self._ctx.root_node)
   bases = [sized.to_variable(self._ctx.root_node)]
   members = {"__len__": self._ctx.new_unsolvable(self._ctx.root_node)}
   cls = abstract.InterpreterClass("X", bases, members, None, self._ctx)
   self.assertFalse(cls.abstract_methods)
예제 #11
0
 def test_getitem_with_instance_valself(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self.ctx)
   valself = abstract.Instance(cls, self.ctx).to_binding(self.node)
   _, attr_var = self.attribute_handler.get_attribute(
       self.node, cls, "__getitem__", valself)
   # Since we passed in `valself` for this lookup of __getitem__ on a class,
   # it is treated as a normal lookup; X.__getitem__ does not exist.
   self.assertIsNone(attr_var)
예제 #12
0
 def test_getitem_no_valself(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self.ctx)
   _, attr_var = self.attribute_handler.get_attribute(
       self.node, cls, "__getitem__")
   attr, = attr_var.data
   # Since we looked up __getitem__ on a class without passing in `valself`,
   # the class is treated as an annotation.
   self.assertIs(attr.func.__func__, abstract.AnnotationClass.getitem_slot)
예제 #13
0
 def test_overridden_abstract_method_still_abstract(self):
   sized_pytd = self._ctx.loader.typing.Lookup("typing.Sized")
   sized = self._ctx.convert.constant_to_value(sized_pytd, {},
                                               self._ctx.root_node)
   bases = [sized.to_variable(self._ctx.root_node)]
   func = abstract.Function("__len__", self._ctx)
   func.is_abstract = True
   members = {"__len__": func.to_variable(self._ctx.root_node)}
   cls = abstract.InterpreterClass("X", bases, members, None, self._ctx)
   self.assertCountEqual(cls.abstract_methods, {"__len__"})
예제 #14
0
 def test_interpreter_class_official_name(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self._ctx)
   cls.update_official_name("Z")
   self.assertEqual(cls.official_name, "Z")
   cls.update_official_name("A")  # takes effect because A < Z
   self.assertEqual(cls.official_name, "A")
   cls.update_official_name("Z")  # no effect
   self.assertEqual(cls.official_name, "A")
   cls.update_official_name("X")  # takes effect because X == cls.name
   self.assertEqual(cls.official_name, "X")
   cls.update_official_name("A")  # no effect
   self.assertEqual(cls.official_name, "X")
예제 #15
0
 def test_union_set_attribute(self):
   list_instance = abstract.Instance(self._ctx.convert.list_type, self._ctx)
   cls = abstract.InterpreterClass("obj", [], {}, None, self._ctx)
   cls_instance = abstract.Instance(cls, self._ctx)
   union = abstract.Union([cls_instance, list_instance], self._ctx)
   node = self._ctx.attribute_handler.set_attribute(
       self._ctx.root_node, union, "rumpelstiltskin",
       self._ctx.convert.none_type.to_variable(self._ctx.root_node))
   self.assertEqual(cls_instance.members["rumpelstiltskin"].data.pop(),
                    self._ctx.convert.none_type)
   self.assertIs(node, self._ctx.root_node)
   error, = self._ctx.errorlog.unique_sorted_errors()
   self.assertEqual(error.name, "not-writable")
예제 #16
0
 def test_instantiate_interpreter_class(self):
   cls = abstract.InterpreterClass("X", [], {}, None, self._ctx)
   # When there is no current frame, create a new instance every time.
   v1 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
   v2 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
   self.assertIsNot(v1, v2)
   # Create one instance per opcode.
   fake_opcode = object()
   self._ctx.vm.push_frame(frame_state.SimpleFrame(fake_opcode))
   v3 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
   v4 = abstract_utils.get_atomic_value(cls.instantiate(self._node))
   self.assertIsNot(v1, v3)
   self.assertIsNot(v2, v3)
   self.assertIs(v3, v4)
예제 #17
0
 def test_abstract_method(self):
   func = abstract.Function("f", self._ctx).to_variable(self._ctx.root_node)
   func.data[0].is_abstract = True
   cls = abstract.InterpreterClass("X", [], {"f": func}, None, self._ctx)
   self.assertCountEqual(cls.abstract_methods, {"f"})
예제 #18
0
 def test_compatible_with(self):
     cls = abstract.InterpreterClass("X", [], {}, None, self._ctx)
     self.assertTruthy(cls)