Exemple #1
0
    def type_check_inputs(self, pvalueish):
        type_hints = self.get_type_hints()
        input_types = type_hints.input_types
        if input_types:
            args, kwargs = self.raw_side_inputs

            def element_type(side_input):
                if isinstance(side_input, pvalue.AsSideInput):
                    return side_input.element_type
                return instance_to_type(side_input)

            arg_types = [pvalueish.element_type
                         ] + [element_type(v) for v in args]
            kwargs_types = {k: element_type(v) for (k, v) in kwargs.items()}
            argspec_fn = self._process_argspec_fn()
            bindings = getcallargs_forhints(argspec_fn, *arg_types,
                                            **kwargs_types)
            hints = getcallargs_forhints(argspec_fn, *input_types[0],
                                         **input_types[1])
            for arg, hint in hints.items():
                if arg.startswith('__unknown__'):
                    continue
                if hint is None:
                    continue
                if not typehints.is_consistent_with(
                        bindings.get(arg, typehints.Any), hint):
                    raise TypeCheckError(
                        'Type hint violation for \'{label}\': requires {hint} but got '
                        '{actual_type} for {arg}\nFull type hint:\n{debug_str}'
                        .format(label=self.label,
                                hint=hint,
                                actual_type=bindings[arg],
                                arg=arg,
                                debug_str=type_hints.debug_str()))
Exemple #2
0
 def type_check_inputs_or_outputs(self, pvalueish, input_or_output):
     hints = getattr(self.get_type_hints(), input_or_output + '_types')
     if not hints:
         return
     arg_hints, kwarg_hints = hints
     if arg_hints and kwarg_hints:
         raise TypeCheckError(
             'PTransform cannot have both positional and keyword type hints '
             'without overriding %s._type_check_%s()' %
             (self.__class__, input_or_output))
     root_hint = (arg_hints[0]
                  if len(arg_hints) == 1 else arg_hints or kwarg_hints)
     for context, pvalue_, hint in _ZipPValues().visit(
             pvalueish, root_hint):
         if pvalue_.element_type is None:
             # TODO(robertwb): It's a bug that we ever get here. (typecheck)
             continue
         if hint and not typehints.is_consistent_with(
                 pvalue_.element_type, hint):
             at_context = ' %s %s' % (input_or_output,
                                      context) if context else ''
             raise TypeCheckError(
                 '%s type hint violation at %s%s: expected %s, got %s' %
                 (input_or_output.title(), self.label, at_context, hint,
                  pvalue_.element_type))
Exemple #3
0
 def type_check_inputs_or_outputs(self, pvalueish, input_or_output):
     type_hints = self.get_type_hints()
     hints = getattr(type_hints, input_or_output + '_types')
     if hints is None or not any(hints):
         return
     arg_hints, kwarg_hints = hints
     if arg_hints and kwarg_hints:
         raise TypeCheckError(
             'PTransform cannot have both positional and keyword type hints '
             'without overriding %s._type_check_%s()' %
             (self.__class__, input_or_output))
     root_hint = (arg_hints[0]
                  if len(arg_hints) == 1 else arg_hints or kwarg_hints)
     for context, pvalue_, hint in _ZipPValues().visit(
             pvalueish, root_hint):
         if isinstance(pvalue_, DoOutputsTuple):
             continue
         if pvalue_.element_type is None:
             # TODO(robertwb): It's a bug that we ever get here. (typecheck)
             continue
         if hint and not typehints.is_consistent_with(
                 pvalue_.element_type, hint):
             at_context = ' %s %s' % (input_or_output,
                                      context) if context else ''
             raise TypeCheckError(
                 '{type} type hint violation at {label}{context}: expected {hint}, '
                 'got {actual_type}\nFull type hint:\n{debug_str}'.format(
                     type=input_or_output.title(),
                     label=self.label,
                     context=at_context,
                     hint=hint,
                     actual_type=pvalue_.element_type,
                     debug_str=type_hints.debug_str()))
Exemple #4
0
    def type_check_inputs(self, pvalueish):
        type_hints = self.get_type_hints().input_types
        if type_hints:
            args, kwargs = self.raw_side_inputs

            def element_type(side_input):
                if isinstance(side_input, pvalue.AsSideInput):
                    return side_input.element_type
                return instance_to_type(side_input)

            arg_types = [pvalueish.element_type
                         ] + [element_type(v) for v in args]
            kwargs_types = {k: element_type(v) for (k, v) in kwargs.items()}
            argspec_fn = self._process_argspec_fn()
            bindings = getcallargs_forhints(argspec_fn, *arg_types,
                                            **kwargs_types)
            hints = getcallargs_forhints(argspec_fn, *type_hints[0],
                                         **type_hints[1])
            for arg, hint in hints.items():
                if arg.startswith('%unknown%'):
                    continue
                if hint is None:
                    continue
                if not typehints.is_consistent_with(
                        bindings.get(arg, typehints.Any), hint):
                    raise TypeCheckError(
                        'Type hint violation for \'%s\': requires %s but got %s for %s'
                        % (self.label, hint, bindings[arg], arg))
  def type_check_inputs(self, pvalueish):
    type_hints = self.get_type_hints().input_types
    if type_hints:
      args, kwargs = self.raw_side_inputs

      def element_type(side_input):
        if isinstance(side_input, pvalue.AsSideInput):
          return side_input.element_type
        return instance_to_type(side_input)

      arg_types = [pvalueish.element_type] + [element_type(v) for v in args]
      kwargs_types = {k: element_type(v) for (k, v) in kwargs.items()}
      argspec_fn = self._process_argspec_fn()
      bindings = getcallargs_forhints(argspec_fn, *arg_types, **kwargs_types)
      hints = getcallargs_forhints(argspec_fn, *type_hints[0], **type_hints[1])
      for arg, hint in hints.items():
        if arg.startswith('%unknown%'):
          continue
        if hint is None:
          continue
        if not typehints.is_consistent_with(
            bindings.get(arg, typehints.Any), hint):
          raise TypeCheckError(
              'Type hint violation for \'%s\': requires %s but got %s for %s'
              % (self.label, hint, bindings[arg], arg))
 def test_hint_helper(self):
     self.assertTrue(is_consistent_with(Any, int))
     self.assertTrue(is_consistent_with(int, Any))
     self.assertTrue(is_consistent_with(str, object))
     self.assertFalse(is_consistent_with(object, str))
     self.assertTrue(is_consistent_with(str, Union[str, int]))
     self.assertFalse(is_consistent_with(Union[str, int], str))
 def test_hint_helper(self):
   self.assertTrue(is_consistent_with(Any, int))
   self.assertTrue(is_consistent_with(int, Any))
   self.assertTrue(is_consistent_with(str, object))
   self.assertFalse(is_consistent_with(object, str))
   self.assertTrue(is_consistent_with(str, Union[str, int]))
   self.assertFalse(is_consistent_with(Union[str, int], str))
Exemple #8
0
def _unpack_positional_arg_hints(arg, hint):
  """Unpacks the given hint according to the nested structure of arg.

  For example, if arg is [[a, b], c] and hint is Tuple[Any, int], then
  this function would return ((Any, Any), int) so it can be used in conjunction
  with inspect.getcallargs.
  """
  if isinstance(arg, list):
    tuple_constraint = typehints.Tuple[[typehints.Any] * len(arg)]
    if not typehints.is_consistent_with(hint, tuple_constraint):
      raise TypeCheckError('Bad tuple arguments for %s: expected %s, got %s' %
                           (arg, tuple_constraint, hint))
    if isinstance(hint, typehints.TupleConstraint):
      return tuple(_unpack_positional_arg_hints(a, t)
                   for a, t in zip(arg, hint.tuple_types))
    return (typehints.Any,) * len(arg)
  return hint
def _unpack_positional_arg_hints(arg, hint):
  """Unpacks the given hint according to the nested structure of arg.

  For example, if arg is [[a, b], c] and hint is Tuple[Any, int], than
  this function would return ((Any, Any), int) so it can be used in conjunction
  with inspect.getcallargs.
  """
  if isinstance(arg, list):
    tuple_constraint = typehints.Tuple[[typehints.Any] * len(arg)]
    if not typehints.is_consistent_with(hint, tuple_constraint):
      raise TypeCheckError('Bad tuple arguments for %s: expected %s, got %s' %
                           (arg, tuple_constraint, hint))
    if isinstance(hint, typehints.TupleConstraint):
      return tuple(_unpack_positional_arg_hints(a, t)
                   for a, t in zip(arg, hint.tuple_types))
    return (typehints.Any,) * len(arg)
  return hint
Exemple #10
0
 def type_check_inputs_or_outputs(self, pvalueish, input_or_output):
   hints = getattr(self.get_type_hints(), input_or_output + '_types')
   if not hints:
     return
   arg_hints, kwarg_hints = hints
   if arg_hints and kwarg_hints:
     raise TypeCheckError(
         'PTransform cannot have both positional and keyword type hints '
         'without overriding %s._type_check_%s()' % (
             self.__class__, input_or_output))
   root_hint = (
       arg_hints[0] if len(arg_hints) == 1 else arg_hints or kwarg_hints)
   for context, pvalue_, hint in _ZipPValues().visit(pvalueish, root_hint):
     if pvalue_.element_type is None:
       # TODO(robertwb): It's a bug that we ever get here. (typecheck)
       continue
     if hint and not typehints.is_consistent_with(pvalue_.element_type, hint):
       at_context = ' %s %s' % (input_or_output, context) if context else ''
       raise TypeCheckError(
           '%s type hint violation at %s%s: expected %s, got %s' % (
               input_or_output.title(), self.label, at_context, hint,
               pvalue_.element_type))
 def assertNotCompatible(self, base, sub):  # pylint: disable=invalid-name
     self.assertFalse(is_consistent_with(sub, base),
                      '%s is consistent with %s' % (sub, base))
Exemple #12
0
 def assertNotCompatible(self, base, sub):  # pylint: disable=invalid-name
     base, sub = native_type_compatibility.convert_to_beam_type([base, sub])
     self.assertFalse(is_consistent_with(sub, base),
                      '%s is consistent with %s' % (sub, base))
 def assertCompatible(self, base, sub):  # pylint: disable=invalid-name
   self.assertTrue(
       is_consistent_with(sub, base),
       '%s is not consistent with %s' % (sub, base))
Exemple #14
0
 def _consistent_with_check_(self, sub):
     return (isinstance(sub, self.__class__)
             and typehints.is_consistent_with(sub.key_type, self.key_type))