def test_callable(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(Callable[[Iterable], bool],
                           Callable[[List], bool], bindings))
     self.assertFalse(unify(Callable[[List], bool],
                            Callable[[Iterable], bool], bindings))
     self.assertTrue(unify(Callable[[int, _T], List[int]],
                           Callable[[int, str], _U], bindings))
     self.assertEqual(realize(Callable[[_U], _T], bindings),
                      Callable[[List[int]], str])
Beispiel #2
0
    def find_key_in_heap(
        self,
        ref: z3.ExprRef,
        typ: Type,
        proxy_generator: Callable[[Type], object],
        snapshot: SnapshotRef = SnapshotRef(-1)
    ) -> object:
        with self.framework():
            for (curref, curtyp,
                 curval) in itertools.chain(*self.heaps[snapshot:]):
                could_match = dynamic_typing.unify(curtyp, typ)
                if not could_match:
                    continue
                if self.smt_fork(curref == ref):
                    debug('HEAP key lookup ', ref, ': Found existing. ',
                          'type:', name_of_type(type(curval)), 'id:',
                          id(curval) % 1000)
                    return curval
            ret = proxy_generator(typ)
            debug('HEAP key lookup ', ref, ': Created new. ', 'type:',
                  name_of_type(type(ret)), 'id:',
                  id(ret) % 1000)

            #assert dynamic_typing.unify(python_type(ret), typ), 'proxy type was {} and type required was {}'.format(type(ret), typ)
            self.add_value_to_heaps(ref, typ, ret)
            return ret
Beispiel #3
0
        def wrapper(*a: object, **kw: Dict[str, object]) -> object:
            #debug('short circuit wrapper ', original)
            space = optional_context_statespace()
            if (not self.engaged) or (not space) or space.running_framework_code:
                return original(*a, **kw)
            # We *heavily* bias towards concrete execution, because it's often the case
            # that a single short-circuit will render the path useless. TODO: consider
            # decaying short-crcuit probability over time.
            use_short_circuit = space.fork_with_confirm_or_else(0.95)
            if not use_short_circuit:
                #debug('short circuit: Choosing not to intercept', original)
                return original(*a, **kw)
            try:
                self.engaged = False
                debug('short circuit: Short circuiting over a call to ', original)
                self.intercepted = True
                return_type = sig.return_annotation

                # Deduce type vars if necessary
                if len(typing_inspect.get_parameters(sig.return_annotation)) > 0 or typing_inspect.is_typevar(sig.return_annotation):
                    typevar_bindings: typing.ChainMap[object, type] = collections.ChainMap(
                    )
                    bound = sig.bind(*a, **kw)
                    bound.apply_defaults()
                    for param in sig.parameters.values():
                        argval = bound.arguments[param.name]
                        value_type = python_type(argval)
                        #debug('unify', value_type, param.annotation)
                        if not dynamic_typing.unify(value_type, param.annotation, typevar_bindings):
                            debug(
                                'aborting intercept due to signature unification failure')
                            return original(*a, **kw)
                        #debug('unify bindings', typevar_bindings)
                    return_type = dynamic_typing.realize(
                        sig.return_annotation, typevar_bindings)
                    debug('short circuit: Deduced return type was ', return_type)

                # adjust arguments that may have been mutated
                assert subconditions is not None
                bound = sig.bind(*a, **kw)
                mutable_args = subconditions.mutable_args
                for argname, arg in bound.arguments.items():
                    if mutable_args is None or argname in mutable_args:
                        forget_contents(arg)

                if return_type is type(None):
                    return None
                # note that the enforcement wrapper ensures postconditions for us, so we
                # can just return a free variable here.
                return proxy_for_type(return_type, 'proxyreturn' + space.uniq())
            finally:
                self.engaged = True
Beispiel #4
0
    def find_key_in_heap(
            self,
            ref: z3.ExprRef,
            typ: Type,
            proxy_generator: Callable[[Type], object],
            snapshot: SnapshotRef = SnapshotRef(-1),
    ) -> object:
        with NoTracing():
            for (curref, curtyp,
                 curval) in itertools.chain(*self.heaps[snapshot:]):
                could_match = dynamic_typing.unify(curtyp, typ)
                if not could_match:
                    continue
                if self.smt_fork(curref == ref):
                    debug(
                        "HEAP key lookup ",
                        ref,
                        ": Found existing. ",
                        "type:",
                        name_of_type(type(curval)),
                        "id:",
                        id(curval) % 1000,
                    )
                    return curval
            ret = proxy_generator(typ)
            debug(
                "HEAP key lookup ",
                ref,
                ": Created new. ",
                "type:",
                name_of_type(type(ret)),
                "id:",
                id(ret) % 1000,
            )

            self.add_value_to_heaps(ref, typ, ret)
            return ret
Beispiel #5
0
 def test_nested_union(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(List[str], Sequence[Union[str, int]], bindings))
Beispiel #6
0
 def test_union_into_union(self):
     bindings = collections.ChainMap()
     self.assertTrue(
         unify(Union[str, int], Union[str, int, float], bindings))
     self.assertFalse(
         unify(Union[str, int, float], Union[str, int], bindings))
Beispiel #7
0
 def test_union_ok(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(int, Union[str, int], bindings))
     self.assertTrue(
         unify(Tuple[int, ...], Union[int, Iterable[_T]], bindings))
     self.assertEqual(bindings[_T], int)
Beispiel #8
0
 def test_union_fail(self):
     bindings = collections.ChainMap()
     self.assertFalse(
         unify(Iterable[int], Union[int, Dict[str, _T]], bindings))
Beispiel #9
0
 def test_tuple(self):
     bindings = collections.ChainMap()
     self.assertFalse(unify(tuple, Tuple[int, str], bindings))
Beispiel #10
0
 def test_uniform_tuple(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(Tuple[int, int], Tuple[_T, ...], bindings))
     self.assertEqual(bindings[_T], int)
     self.assertFalse(unify(Tuple[int, str], Tuple[_T, ...], bindings))
Beispiel #11
0
 def test_plain_callable(self):
     bindings = collections.ChainMap()
     self.assertTrue(
         unify(Callable[[int, str], List[int]], Callable, bindings))
Beispiel #12
0
 def test_zero_type_args_ok(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(map, Iterable[_T]))
     self.assertFalse(unify(map, Iterable[int]))
Beispiel #13
0
 def test_bound_vtypears(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(Dict[str, int], Dict[_T, _U]))
     self.assertFalse(unify(Dict[str, int], Dict[_T, _T]))
Beispiel #14
0
 def test_typevars(self):
     bindings = collections.ChainMap()
     self.assertTrue(
         unify(Tuple[int, str, List[int]], Tuple[int, _T, _U], bindings))
     self.assertEqual(realize(Mapping[_U, _T], bindings), Mapping[List[int],
                                                                  str])
Beispiel #15
0
 def test_raw_tuple(self):
     bindings = collections.ChainMap()
     self.assertTrue(unify(tuple, Iterable[_T], bindings))