def _call(fn, parameter_type, arg): arg_type = type_conversions.infer_type(arg) if not parameter_type.is_assignable_from(arg_type): raise TypeError('Expected an argument of type {}, found {}.'.format( parameter_type, arg_type)) if type_analysis.is_anon_tuple_with_py_container(arg, parameter_type): arg = type_conversions.type_to_py_container(arg, parameter_type) return fn(arg)
def _unpack_and_call(fn, arg_types, kwarg_types, arg): """An interceptor function that unpacks 'arg' before calling `fn`. The function verifies the actual parameters before it forwards the call as a last-minute check. Args: fn: The function or defun to invoke. arg_types: The list of positional argument types (guaranteed to all be instances of computation_types.Types). kwarg_types: The dictionary of keyword argument types (guaranteed to all be instances of computation_types.Types). arg: The argument to unpack. Returns: The result of invoking `fn` on the unpacked arguments. Raises: TypeError: if types don't match. """ py_typecheck.check_type( arg, (anonymous_tuple.AnonymousTuple, value_base.Value)) args = [] for idx, expected_type in enumerate(arg_types): element_value = arg[idx] actual_type = type_conversions.infer_type(element_value) if not type_analysis.is_assignable_from( expected_type, actual_type): raise TypeError( 'Expected element at position {} to be of type {}, found {}.' .format(idx, expected_type, actual_type)) if isinstance(element_value, anonymous_tuple.AnonymousTuple): element_value = type_conversions.type_to_py_container( element_value, expected_type) args.append(element_value) kwargs = {} for name, expected_type in kwarg_types.items(): element_value = getattr(arg, name) actual_type = type_conversions.infer_type(element_value) if not type_analysis.is_assignable_from( expected_type, actual_type): raise TypeError( 'Expected element named {} to be of type {}, found {}.' .format(name, expected_type, actual_type)) if type_analysis.is_anon_tuple_with_py_container( element_value, expected_type): element_value = type_conversions.type_to_py_container( element_value, expected_type) kwargs[name] = element_value return fn(*args, **kwargs)
async def _invoke(executor, comp, arg): """A coroutine that handles invocation. Args: executor: An instance of `executor_base.Executor`. comp: The first argument to `context_base.Context.invoke()`. arg: The optional second argument to `context_base.Context.invoke()`. Returns: The result of the invocation. """ py_typecheck.check_type(comp.type_signature, computation_types.FunctionType) result_type = comp.type_signature.result if arg is not None: py_typecheck.check_type(arg, executor_value_base.ExecutorValue) comp = await executor.create_value(comp) result = await executor.create_call(comp, arg) py_typecheck.check_type(result, executor_value_base.ExecutorValue) result_val = _unwrap(await result.compute()) if type_analysis.is_anon_tuple_with_py_container(result_val, result_type): return type_conversions.type_to_py_container(result_val, result_type) else: return result_val
def test_returns_false_with_named_tuple_type_spec(self): value = anonymous_tuple.AnonymousTuple([('a', 0.0)]) type_spec = computation_types.NamedTupleType([('a', tf.float32)]) self.assertFalse( type_analysis.is_anon_tuple_with_py_container(value, type_spec))
def test_returns_false_with_none_value(self): value = None type_spec = computation_types.NamedTupleTypeWithPyContainerType( [('a', tf.float32)], dict) self.assertFalse( type_analysis.is_anon_tuple_with_py_container(value, type_spec))
def test_returns_true(self): value = anonymous_tuple.AnonymousTuple([('a', 0.0)]) type_spec = computation_types.NamedTupleTypeWithPyContainerType( [('a', tf.float32)], dict) self.assertTrue( type_analysis.is_anon_tuple_with_py_container(value, type_spec))