Esempio n. 1
0
    def _new_named_tuple(self, class_name: str,
                         fields: List[Tuple[str, Any]]) -> pytd.Class:
        """Generates a pytd class for a named tuple.

    Args:
      class_name: The name of the generated class
      fields: A list of (name, type) tuples.

    Returns:
      A generated class that describes the named tuple.
    """
        class_base = pytdgen.heterogeneous_tuple(pytd.NamedType("tuple"),
                                                 tuple(t for _, t in fields))
        class_constants = tuple(pytd.Constant(n, t) for n, t in fields)
        # Since the user-defined fields are the only namedtuple attributes commonly
        # used, we define all the other attributes as Any for simplicity.
        class_constants += tuple(
            pytd.Constant(name, pytd.AnythingType())
            for name in _NAMEDTUPLE_MEMBERS)
        methods = function.merge_method_signatures(
            [self._make_new(class_name, fields),
             self._make_init()])
        return pytd.Class(name=class_name,
                          metaclass=None,
                          bases=(class_base, ),
                          methods=tuple(methods),
                          constants=class_constants,
                          decorators=(),
                          classes=(),
                          slots=tuple(n for n, _ in fields),
                          template=())
Esempio n. 2
0
 def _parameterized_type(self, base_type, parameters):
     """Return a parameterized type."""
     if self._is_literal_base_type(base_type):
         return types.pytd_literal(parameters)
     elif any(isinstance(p, types.Constant) for p in parameters):
         parameters = ", ".join(
             p.repr_str() if isinstance(p, types.Constant) else "_"
             for p in parameters)
         raise ParseError("%s[%s] not supported" %
                          (pytd_utils.Print(base_type), parameters))
     elif pytdgen.is_any(base_type):
         return pytd.AnythingType()
     elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS and (
             not self._is_callable_base_type(base_type)):
         element_type = parameters[0]
         if element_type is self.ELLIPSIS:
             raise ParseError("[..., ...] not supported")
         return pytd.GenericType(base_type=base_type,
                                 parameters=(element_type, ))
     else:
         parameters = tuple(pytd.AnythingType() if p is self.ELLIPSIS else p
                            for p in parameters)
         if self._is_tuple_base_type(base_type):
             return pytdgen.heterogeneous_tuple(base_type, parameters)
         elif self._is_callable_base_type(base_type):
             return pytdgen.pytd_callable(base_type, parameters)
         else:
             assert parameters
             return pytd.GenericType(base_type=base_type,
                                     parameters=parameters)
Esempio n. 3
0
 def _parameterized_type(self, base_type: Any, parameters):
     """Return a parameterized type."""
     if self._matches_named_type(base_type, _LITERAL_TYPES):
         return pytd_literal(parameters)
     elif self._matches_named_type(base_type, _ANNOTATED_TYPES):
         return pytd_annotated(parameters)
     elif self._matches_named_type(base_type, _FINAL_TYPES):
         typ, = parameters
         return pytd.GenericType(pytd.NamedType("typing.Final"), (typ, ))
     elif self._matches_named_type(base_type, _TYPEGUARD_TYPES):
         # We do not yet support PEP 647, User-Defined Type Guards. To avoid
         # blocking typeshed, convert type guards to plain bools.
         return pytd.NamedType("bool")
     elif any(isinstance(p, types.Pyval) for p in parameters):
         parameters = ", ".join(
             p.repr_str() if isinstance(p, types.Pyval) else "_"
             for p in parameters)
         raise ParseError("%s[%s] not supported" %
                          (pytd_utils.Print(base_type), parameters))
     elif pytdgen.is_any(base_type):
         return pytd.AnythingType()
     elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS and (
             not self._matches_named_type(base_type, _CALLABLE_TYPES)):
         element_type = parameters[0]
         if element_type is self.ELLIPSIS:
             raise ParseError("[..., ...] not supported")
         return pytd.GenericType(base_type=base_type,
                                 parameters=(element_type, ))
     else:
         processed_parameters = []
         # We do not yet support PEP 612, Parameter Specification Variables.
         # To avoid blocking typeshed from adopting this PEP, we convert new
         # features to approximations that only use supported features.
         for p in parameters:
             if p is self.ELLIPSIS:
                 processed = pytd.AnythingType()
             elif (p in self.param_specs and self._matches_full_name(
                     base_type, "typing.Generic")):
                 # Replacing a ParamSpec with a TypeVar isn't correct, but it'll work
                 # for simple cases in which the filled value is also a ParamSpec.
                 if not any(t.name == p.name for t in self.type_params):
                     self.type_params.append(pytd.TypeParameter(p.name))
                 processed = p
             elif (p in self.param_specs
                   or (isinstance(p, pytd.GenericType)
                       and self._matches_full_name(p, _CONCATENATE_TYPES))):
                 processed = pytd.AnythingType()
             else:
                 processed = p
             processed_parameters.append(processed)
         parameters = tuple(processed_parameters)
         if self._matches_named_type(base_type, _TUPLE_TYPES):
             return pytdgen.heterogeneous_tuple(base_type, parameters)
         elif self._matches_named_type(base_type, _CALLABLE_TYPES):
             return pytdgen.pytd_callable(base_type, parameters)
         else:
             assert parameters
             return pytd.GenericType(base_type=base_type,
                                     parameters=parameters)
Esempio n. 4
0
 def _parameterized_type(self, base_type, parameters):
     """Return a parameterized type."""
     if self._matches_named_type(base_type, _LITERAL_TYPES):
         return types.pytd_literal(parameters)
     elif self._matches_named_type(base_type, _ANNOTATED_TYPES):
         return types.pytd_annotated(parameters)
     elif self._matches_named_type(base_type, _TYPEGUARD_TYPES):
         # We do not yet support PEP 647, User-Defined Type Guards. To avoid
         # blocking typeshed, convert type guards to plain bools.
         return pytd.NamedType("bool")
     elif any(isinstance(p, types.Constant) for p in parameters):
         parameters = ", ".join(
             p.repr_str() if isinstance(p, types.Constant) else "_"
             for p in parameters)
         raise ParseError("%s[%s] not supported" %
                          (pytd_utils.Print(base_type), parameters))
     elif pytdgen.is_any(base_type):
         return pytd.AnythingType()
     elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS and (
             not self._matches_named_type(base_type, _CALLABLE_TYPES)):
         element_type = parameters[0]
         if element_type is self.ELLIPSIS:
             raise ParseError("[..., ...] not supported")
         return pytd.GenericType(base_type=base_type,
                                 parameters=(element_type, ))
     else:
         parameters = tuple(pytd.AnythingType() if p is self.ELLIPSIS else p
                            for p in parameters)
         if self._matches_named_type(base_type, _TUPLE_TYPES):
             return pytdgen.heterogeneous_tuple(base_type, parameters)
         elif self._matches_named_type(base_type, _CALLABLE_TYPES):
             callable_parameters = []
             for p in parameters:
                 # We do not yet support PEP 612, Parameter Specification Variables.
                 # To avoid blocking typeshed from adopting this PEP, we convert new
                 # features to Any.
                 if p in self.param_specs or (isinstance(
                         p, pytd.GenericType) and self._matches_full_name(
                             p, _CONCATENATE_TYPES)):
                     callable_parameters.append(pytd.AnythingType())
                 else:
                     callable_parameters.append(p)
             return pytdgen.pytd_callable(base_type,
                                          tuple(callable_parameters))
         else:
             assert parameters
             return pytd.GenericType(base_type=base_type,
                                     parameters=parameters)
Esempio n. 5
0
 def _parameterized_type(self, base_type, parameters):
     """Return a parameterized type."""
     if self._is_literal_base_type(base_type):
         return types.pytd_literal(parameters)
     elif any(isinstance(p, types.Constant) for p in parameters):
         parameters = ", ".join(
             p.repr_str() if isinstance(p, types.Constant) else "_"
             for p in parameters)
         raise ParseError("%s[%s] not supported" %
                          (pytd_utils.Print(base_type), parameters))
     elif pytdgen.is_any(base_type):
         return pytd.AnythingType()
     elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS and (
             not self._is_callable_base_type(base_type)):
         element_type = parameters[0]
         if element_type is self.ELLIPSIS:
             raise ParseError("[..., ...] not supported")
         return pytd.GenericType(base_type=base_type,
                                 parameters=(element_type, ))
     else:
         parameters = tuple(pytd.AnythingType() if p is self.ELLIPSIS else p
                            for p in parameters)
         if self._is_tuple_base_type(base_type):
             return pytdgen.heterogeneous_tuple(base_type, parameters)
         elif self._is_callable_base_type(base_type):
             callable_parameters = []
             for p in parameters:
                 # We do not yet support PEP 612, Parameter Specification Variables.
                 # To avoid blocking typeshed from adopting this PEP, we convert new
                 # features to Any.
                 if p in self.param_specs or (isinstance(
                         p, pytd.GenericType) and self._matches_full_name(
                             p, ("typing.Concatenate",
                                 "typing_extensions.Concatenate"))):
                     callable_parameters.append(pytd.AnythingType())
                 else:
                     callable_parameters.append(p)
             return pytdgen.pytd_callable(base_type,
                                          tuple(callable_parameters))
         else:
             assert parameters
             return pytd.GenericType(base_type=base_type,
                                     parameters=parameters)