def _create_new_unknown_value(self, action): if not action or not self.vm.frame: return abstract.Unknown(self.vm) # We allow only one Unknown at each point in the program, regardless of # what the call stack is. key = ("unknown", self.vm.frame.current_opcode, action) if key not in self._convert_cache: self._convert_cache[key] = abstract.Unknown(self.vm) return self._convert_cache[key]
def test_is_instance(self): def check(expected, left, right): self.assertEquals(expected, self._is_instance._is_instance(left, right)) obj_class = self._vm.convert.primitive_classes[object].bindings[0].data # Unknown and Unsolvable are ambiguous. check(None, abstract.Unknown(self._vm), obj_class) check(None, abstract.Unsolvable(self._vm), obj_class) # If the object's class has multiple bindings, result is ambiguous. obj = abstract.SimpleAbstractValue("foo", self._vm) check(None, obj, obj_class) obj.set_class(self._node, self.new_var(self._str_class, self._int_class)) check(None, obj, self._str_class) # If the class_spec is not a class, result is ambiguous. check(None, self._str, self._str) # Result is True/False depending on if the class is in the object's mro. check(True, self._str, obj_class) check(True, self._str, self._str_class) check(False, self._str, self._int_class)
def test_call_single_bindings(self): right = self.new_var("right", self._str_class) self.assert_call({self._vm.convert.true: {"left:0 right:0"}}, self.new_var("left", self._str), right) self.assert_call({self._vm.convert.false: {"left:0 right:0"}}, self.new_var("left", self._int), right) self.assert_call({self._bool: {"left:0 right:0"}}, self.new_var("left", abstract.Unknown(self._vm)), right)
def test_call_wrong_keywords(self): self._vm.push_frame(FakeFrame()) x = self.new_var("x", abstract.Unknown(self._vm)) node, result = self._is_instance.call(self._node, None, (x, x), self.new_dict(foo=x)) self.assertEquals(self._node, node) self.assertIsInstance(abstract.get_atomic_value(result), abstract.Unsolvable) self.assertRegexpMatches(str(self._vm.errorlog), r"foo.*isinstance.*\[wrong-keyword-args\]")
def test_call_wrong_keywords(self): self._vm.push_frame(frame_state.SimpleFrame()) x = self.new_var(abstract.Unknown(self._vm)) node, result = self._is_instance.call( self._node, None, function.Args( (x, x), self.new_dict(foo=x), None, None)) self.assertEqual(self._node, node) self.assertIsInstance(abstract_utils.get_atomic_value(result), abstract.Unsolvable) six.assertRegex(self, str(self._vm.errorlog), r"foo.*isinstance.*\[wrong-keyword-args\]")
def test_flatten(self): def maybe_var(v): return v if isinstance(v, cfg.Variable) else self.new_var("v", v) def new_tuple(*args): pyval = tuple(maybe_var(a) for a in args) return abstract.AbstractOrConcreteValue( pyval, self._vm.convert.tuple_type, self._vm, self._node) def check(expected_ambiguous, expected_classes, value): classes = [] ambiguous = self._is_instance._flatten(value, classes) self.assertEquals(expected_ambiguous, ambiguous) self.assertEquals(expected_classes, classes) unknown = abstract.Unknown(self._vm) # Simple values. check(False, [self._str_class], self._str_class) check(True, [], self._str) check(True, [], unknown) # (str, int) check(False, [self._str_class, self._int_class], new_tuple(self._str_class, self._int_class)) # (str, ?, int) check(True, [self._str_class, self._int_class], new_tuple(self._str_class, unknown, self._int_class)) # (str, (int, object)) check(False, [self._str_class, self._int_class, self._obj_class], new_tuple( self._str_class, new_tuple(self._int_class, self._obj_class))) # (str, (?, object)) check(True, [self._str_class, self._obj_class], new_tuple( self._str_class, new_tuple(unknown, self._obj_class))) # A variable with multiple bindings is ambiguous. # (str, int | object) check(True, [self._str_class], new_tuple(self._str_class, self.new_var("v", self._int_class, self._obj_class)))
def setUp(self): super(TupleTest, self).setUp() self._var = self._program.NewVariable() self._var.AddBinding(abstract.Unknown(self._vm), [], self._node)
def test_compatible_with__after_unknown_update(self): # Updating an empty dict with an unknown value makes the former ambiguous. self._d.update(self._node, abstract.Unknown(self._vm)) self.assertIs(True, self._d.compatible_with(True)) self.assertIs(True, self._d.compatible_with(False))
def test_compatible_with__after_update(self): # Updating an empty dict also makes it ambiguous. self._d.update(self._node, abstract.Unknown(self._vm)) self.assertIs(True, self._d.compatible_with(True)) self.assertIs(True, self._d.compatible_with(False))
def setUp(self): super(DictTest, self).setUp() self._d = abstract.Dict("test_dict", self._vm, self._node) self._var = self._program.NewVariable("test_var") self._var.AddBinding(abstract.Unknown(self._vm))
def setUp(self): super().setUp() self._d = abstract.Dict(self._vm) self._var = self._program.NewVariable() self._var.AddBinding(abstract.Unknown(self._vm), [], self._node)
def create_argument(self, node, method_name, i): name = "arg %d of %s" % (i, method_name) return abstract.Unknown(self).to_variable(node, name)
def build_any(name, vm, node, inner=None): del name del node del inner return abstract.Unknown(vm)