Exemple #1
0
 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
Exemple #2
0
  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