Example #1
0
 def p_type_and(self, p):
     """type : type AND type"""
     # TODO: Unless we bring interfaces back, it's not clear when
     #              "type1 and type2" would be useful for anything. We
     #              should remove it.
     # This rule depends on precedence specification
     if (isinstance(p[1], pytd.IntersectionType)
             and isinstance(p[3], pytd.NamedType)):
         p[0] = pytd.IntersectionType(p[1].type_list + (p[3], ))
     elif (isinstance(p[1], pytd.NamedType)
           and isinstance(p[3], pytd.IntersectionType)):
         # associative
         p[0] = pytd.IntersectionType(((p[1], ) + p[3].type_list))
     else:
         p[0] = pytd.IntersectionType((p[1], p[3]))
Example #2
0
  def testComplexCombinedType(self):
    """Test parsing a type with both union and intersection."""

    data1 = r"def foo(a: Foo or Bar and Zot) -> object"
    data2 = r"def foo(a: Foo or (Bar and Zot)) -> object"
    result1 = self.Parse(data1)
    result2 = self.Parse(data2)
    f = pytd.Function(
        name="foo",
        signatures=(pytd.Signature(
            params=(
                pytd.Parameter(
                    name="a",
                    type=pytd.UnionType(
                        type_list=(
                            pytd.NamedType("Foo"),
                            pytd.IntersectionType(
                                type_list=(
                                    pytd.NamedType("Bar"),
                                    pytd.NamedType("Zot"))))
                    )
                ),),
            return_type=pytd.NamedType("object"),
            template=(), has_optional=False,
            exceptions=()),))
    self.assertEqual(f, result1.Lookup("foo"))
    self.assertEqual(f, result2.Lookup("foo"))
Example #3
0
 def p_type_and(self, p):
     """type : type AND type"""
     # TODO: Unless we bring interfaces back, it's not clear when
     #              "type1 and type2" would be useful for anything. We
     #              should remove it.
     # This rule depends on precedence specification
     # IntersectionType flattens any contained IntersectinType's
     p[0] = pytd.IntersectionType((p[1], p[3]))
    def testIntersectionError(self):
        """Typechecking fct with intersection types (error).
    """
        with self.assertRaises(checker.CheckTypeAnnotationError) as context:
            union.DoSomeIOStuff(
                union.Readable())  # we want Readable & Writable

        expected = checker.ParamTypeErrorMsg(
            "DoSomeIOStuff", "f", union.Readable,
            pytd.IntersectionType([union.Readable, union.Writable]))

        [actual] = context.exception.args[0]
        self.assertEquals(expected, actual)
Example #5
0
def ConvertToType(module, type_node):
  """Helper for converting a type node to a valid Python type.

  Args:
    module: The module to look up symbols/types
    type_node: A type node to convert into a python type

  Returns:
    A valid Python type. Note that None is considered a type in
    the declaration language, but a value in Python. So a string
    None is converted to a NoneType. We use the module object to look
    up potential type definitions defined inside that module.

  Raises:
    TypeError: if the type node passed is not supported/unknown
  """
  # TODO: Convert this to a visitor.

  # clean up str
  if isinstance(type_node, pytd.NamedType):
    if type_node.name == "None":
      return types.NoneType
    elif type_node.name == "generator":
      return types.GeneratorType
    else:
      res = _EvalWithModuleContext(type_node.name, module)
      assert isinstance(res, type), (type_node.name, repr(res))
      return res

  elif isinstance(type_node, pytd.UnionType):
    return pytd.UnionType([ConvertToType(module, t)
                           for t in type_node.type_list])

  elif isinstance(type_node, pytd.IntersectionType):
    return pytd.IntersectionType([ConvertToType(module, t)
                                  for t in type_node.type_list])

  elif isinstance(type_node, pytd.GenericType):
    return pytd.GenericType(ConvertToType(module,
                                          type_node.base_type),
                            type_node.parameters)

  elif isinstance(type_node, pytd.HomogeneousContainerType):
    return pytd.HomogeneousContainerType(ConvertToType(module,
                                                       type_node.base_type),
                                         ConvertToType(module,
                                                       type_node.element_type))

  else:
    raise TypeError("Unknown type of type_node: {!r}".format(type_node))
Example #6
0
 def VisitIntersectionType(self, node):
     return pytd.IntersectionType(tuple(sorted(node.type_list)))