コード例 #1
0
 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])
コード例 #2
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
コード例 #3
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])