async def create_call(self, comp, arg=None): py_typecheck.check_type(comp, LambdaExecutorValue) py_typecheck.check_type(comp.type_signature, computation_types.FunctionType) param_type = comp.type_signature.parameter if param_type is not None: py_typecheck.check_type(arg, LambdaExecutorValue) if not type_utils.is_assignable_from(param_type, arg.type_signature): arg_type = type_utils.get_argument_type(arg.type_signature) type_utils.check_assignable_from(param_type, arg_type) return await self.create_call(comp, await self.create_call(arg)) else: py_typecheck.check_none(arg) comp_repr = comp.internal_representation if isinstance(comp_repr, executor_value_base.ExecutorValue): return LambdaExecutorValue(await self._target_executor.create_call( comp_repr, await self._delegate(arg) if arg is not None else None)) elif callable(comp_repr): return await comp_repr(arg) else: # An anonymous tuple could not possibly have a functional type signature, # so this is the only case left to handle. py_typecheck.check_type(comp_repr, pb.Computation) eval_result = await self._evaluate(comp_repr, comp.scope) py_typecheck.check_type(eval_result, LambdaExecutorValue) if arg is not None: py_typecheck.check_type(eval_result.type_signature, computation_types.FunctionType) type_utils.check_assignable_from(eval_result.type_signature.parameter, arg.type_signature) return await self.create_call(eval_result, arg) elif isinstance(eval_result.type_signature, computation_types.FunctionType): return await self.create_call(eval_result, arg=None) else: return eval_result
async def create_call(self, comp, arg=None): py_typecheck.check_type(comp, LambdaExecutorValue) py_typecheck.check_type(comp.type_signature, computation_types.FunctionType) param_type = comp.type_signature.parameter if param_type is not None: py_typecheck.check_type(arg, LambdaExecutorValue) arg_type = arg.type_signature # pytype: disable=attribute-error if not type_utils.is_assignable_from(param_type, arg_type): adjusted_arg_type = arg_type if isinstance(arg_type, computation_types.FunctionType): # We may have a non-functional type embedded as a no-arg function. adjusted_arg_type = type_utils.get_argument_type(arg_type) # HACK: The second (`or`) check covers the case where a no-arg lambda # was passed to the lambda executor as a value. # `get_function_type` is used above to transform non-function # types into no-arg lambda types, which are unwrapped by # `get_argument_type` above. Since our value of type `( -> T)` # then has an `adjusted_arg_type` of type `T`, the above # check will fail, so we fall back to checking the unadjusted # type. Note: this will permit some values passed in as type `T` # to be used as values of type `( -> T)`. if not (type_utils.is_assignable_from(param_type, adjusted_arg_type) or type_utils.is_assignable_from(param_type, arg_type)): raise TypeError('LambdaExecutor asked to create call with ' 'incompatible type specifications. Function ' 'takes an argument of type {}, but was supplied ' 'an argument of type {} (or possibly {})'.format( param_type, adjusted_arg_type, arg_type)) arg = await self.create_call(arg) return await self.create_call(comp, arg) else: py_typecheck.check_none(arg) comp_repr = comp.internal_representation if isinstance(comp_repr, executor_value_base.ExecutorValue): delegated_arg = await self._delegate(arg) if arg is not None else None return LambdaExecutorValue(await self._target_executor.create_call( comp_repr, delegated_arg)) elif callable(comp_repr): return await comp_repr(arg) else: # An anonymous tuple could not possibly have a functional type signature, # so this is the only case left to handle. py_typecheck.check_type(comp_repr, pb.Computation) eval_result = await self._evaluate(comp_repr, comp.scope) py_typecheck.check_type(eval_result, LambdaExecutorValue) if arg is not None: py_typecheck.check_type(eval_result.type_signature, computation_types.FunctionType) type_utils.check_assignable_from(eval_result.type_signature.parameter, arg.type_signature) return await self.create_call(eval_result, arg) elif isinstance(eval_result.type_signature, computation_types.FunctionType): return await self.create_call(eval_result, arg=None) else: return eval_result
async def create_call(self, comp, arg=None): py_typecheck.check_type(comp, LambdaExecutorValue) py_typecheck.check_type(comp.type_signature, computation_types.FunctionType) param_type = comp.type_signature.parameter if param_type is not None: py_typecheck.check_type(arg, LambdaExecutorValue) arg_type = arg.type_signature # pytype: disable=attribute-error if not type_utils.is_assignable_from(param_type, arg_type): if isinstance(arg_type, computation_types.FunctionType): # We may have a non-functional type embedded as a no-arg function. arg_type = type_utils.get_argument_type(arg_type) if not type_utils.is_assignable_from(param_type, arg_type): raise TypeError( 'LambdaExecutor asked to create call with ' 'incompatible type specifications. Function ' 'takes an argument of type {}, but was supplied ' 'an argument of type {}'.format(param_type, arg_type)) arg = await self.create_call(arg) return await self.create_call(comp, arg) else: py_typecheck.check_none(arg) comp_repr = comp.internal_representation if isinstance(comp_repr, executor_value_base.ExecutorValue): delegated_arg = await self._delegate(arg ) if arg is not None else None return LambdaExecutorValue(await self._target_executor.create_call( comp_repr, delegated_arg)) elif callable(comp_repr): return await comp_repr(arg) else: # An anonymous tuple could not possibly have a functional type signature, # so this is the only case left to handle. py_typecheck.check_type(comp_repr, pb.Computation) eval_result = await self._evaluate(comp_repr, comp.scope) py_typecheck.check_type(eval_result, LambdaExecutorValue) if arg is not None: py_typecheck.check_type(eval_result.type_signature, computation_types.FunctionType) type_utils.check_assignable_from( eval_result.type_signature.parameter, arg.type_signature) return await self.create_call(eval_result, arg) elif isinstance(eval_result.type_signature, computation_types.FunctionType): return await self.create_call(eval_result, arg=None) else: return eval_result