def pytd_callable( base_type: pytd.NamedType, parameters: Parameters ) -> pytd_node.Node: """Create a pytd.CallableType.""" if isinstance(parameters[0], list): if len(parameters) > 2: raise ParseError( "Expected 2 parameters to Callable, got %d" % len(parameters)) if len(parameters) == 1: # We're usually happy to treat omitted parameters as "Any", but we # need a return type for CallableType, or we wouldn't know whether the # last parameter is an argument or return type. parameters += (pytd.AnythingType(),) if not parameters[0] or parameters[0] == [pytd.NothingType()]: # Callable[[], ret] -> pytd.CallableType(ret) parameters = parameters[1:] else: # Callable[[x, ...], ret] -> pytd.CallableType(x, ..., ret) parameters = tuple(parameters[0]) + parameters[1:] return pytd.CallableType(base_type=base_type, parameters=parameters) else: # Fall back to a generic Callable if first param is Any assert parameters if not is_any(parameters[0]): msg = ("First argument to Callable must be a list of argument types " "(got %r)" % parameters[0]) raise ParseError(msg) return pytd.GenericType(base_type=base_type, parameters=parameters)
def _parameterized_type(self, base_type, parameters): """Return a parameterized type.""" if self._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 self._heterogeneous_tuple(base_type, parameters) elif (self._is_callable_base_type(base_type) and self._is_heterogeneous_tuple(parameters[0])): if len(parameters) > 2: raise ParseError( "Expected 2 parameters to Callable, got %d" % len(parameters)) if len(parameters) == 1: # We're usually happy to treat omitted parameters as "Any", but we # need a return type for CallableType, or we wouldn't know whether the # last parameter is an argument or return type. parameters += (pytd.AnythingType(),) if self._is_empty_tuple(parameters[0]): parameters = parameters[1:] else: parameters = parameters[0].parameters + parameters[1:] return pytd.CallableType(base_type=base_type, parameters=parameters) else: assert parameters if (self._is_callable_base_type(base_type) and not self._is_any(parameters[0])): raise ParseError( "First argument to Callable must be a list of argument types") return pytd.GenericType(base_type=base_type, parameters=parameters)