def get_type(self, i: int, type_comments: Sequence[Optional[str]], converter: TypeConverter) -> Optional[Type]: if i < len(type_comments): comment = type_comments[i] if comment is not None: return converter.visit_raw_str(comment) return None
def get_type(self, i: int, type_comments: Sequence[Optional[str]], converter: TypeConverter) -> Optional[Type]: if i < len(type_comments): comment = type_comments[i] if comment is not None: return converter.visit_raw_str(comment) return None
def parse_type_comment(type_comment: str, line: int) -> Type: try: typ = ast35.parse(type_comment, '<type_comment>', 'eval') except SyntaxError as e: raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, line, e.offset) else: assert isinstance(typ, ast35.Expression) return TypeConverter(line=line).visit(typ.body)
def transform_args( self, n: ast27.arguments, line: int, ) -> Tuple[List[Argument], List[Statement]]: type_comments: Sequence[Optional[str]] = n.type_comments converter = TypeConverter(self.errors, line=line, assume_str_is_unicode=self.unicode_literals) decompose_stmts: List[Statement] = [] n_args = n.args args = [(self.convert_arg(i, arg, line, decompose_stmts), self.get_type(i, type_comments, converter)) for i, arg in enumerate(n_args)] defaults = self.translate_expr_list(n.defaults) names: List[str] = [ name for arg in n_args for name in self.extract_names(arg) ] new_args: List[Argument] = [] num_no_defaults = len(args) - len(defaults) # positional arguments without defaults for a, annotation in args[:num_no_defaults]: new_args.append(Argument(a, annotation, None, ARG_POS)) # positional arguments with defaults for (a, annotation), d in zip(args[num_no_defaults:], defaults): new_args.append(Argument(a, annotation, d, ARG_OPT)) # *arg if n.vararg is not None: new_args.append( Argument(Var(n.vararg), self.get_type(len(args), type_comments, converter), None, ARG_STAR)) names.append(n.vararg) # **kwarg if n.kwarg is not None: typ = self.get_type( len(args) + (0 if n.vararg is None else 1), type_comments, converter) new_args.append(Argument(Var(n.kwarg), typ, None, ARG_STAR2)) names.append(n.kwarg) for arg in new_args: if argument_elide_name(arg.variable.name): arg.pos_only = True # We don't have any context object to give, but we have closed around the line num def fail_arg(msg: str, arg: None) -> None: self.fail(msg, line, 0) check_arg_names(names, [None] * len(names), fail_arg) return new_args, decompose_stmts
def transform_args(self, n: ast27.arguments, line: int) -> List[Argument]: # TODO: remove the cast once https://github.com/python/typeshed/pull/522 # is accepted and synced type_comments = cast(List[str], n.type_comments) # type: ignore converter = TypeConverter(line=line) def convert_arg(arg: ast27.expr) -> Var: if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): # TODO: An `arg` object may be a Tuple instead of just an identifier in the # case of Python 2 function definitions/lambdas that use the tuple unpacking # syntax. The `typed_ast.conversions` module ended up just simply passing the # the arg object unmodified (instead of converting it into more args, etc). # This isn't typesafe, since we will no longer be always passing in a string # to `Var`, but we'll do the same here for consistency. v = arg # type: ignore else: raise RuntimeError("'{}' is not a valid argument.".format( ast27.dump(arg))) return Var(v) def get_type(i: int) -> Optional[Type]: if i < len(type_comments) and type_comments[i] is not None: return converter.visit_raw_str(type_comments[i]) return None args = [(convert_arg(arg), get_type(i)) for i, arg in enumerate(n.args)] defaults = self.translate_expr_list(n.defaults) new_args = [] # type: List[Argument] num_no_defaults = len(args) - len(defaults) # positional arguments without defaults for a, annotation in args[:num_no_defaults]: new_args.append(Argument(a, annotation, None, ARG_POS)) # positional arguments with defaults for (a, annotation), d in zip(args[num_no_defaults:], defaults): new_args.append(Argument(a, annotation, d, ARG_OPT)) # *arg if n.vararg is not None: new_args.append( Argument(Var(n.vararg), get_type(len(args)), None, ARG_STAR)) # **kwarg if n.kwarg is not None: typ = get_type(len(args) + (0 if n.vararg is None else 1)) new_args.append(Argument(Var(n.kwarg), typ, None, ARG_STAR2)) return new_args
def get_type(self, i: int, type_comments: Sequence[Optional[str]], converter: TypeConverter) -> Optional[Type]: if i < len(type_comments): comment = type_comments[i] if comment is not None: typ = converter.visit_raw_str(comment) extra_ignore = TYPE_IGNORE_PATTERN.match(comment) if extra_ignore: tag = cast(Any, extra_ignore).group(1) # type: Optional[str] ignored = parse_type_ignore_tag(tag) self.type_ignores[converter.line] = ignored return typ return None
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: self.class_and_function_stack.append('F') lineno = n.lineno converter = TypeConverter(self.errors, line=lineno, override_column=n.col_offset, assume_str_is_unicode=self.unicode_literals) args, decompose_stmts = self.transform_args(n.args, lineno) if special_function_elide_names(n.name): for arg in args: arg.pos_only = True arg_kinds = [arg.kind for arg in args] arg_names = [ None if arg.pos_only else arg.variable.name for arg in args ] arg_types: List[Optional[Type]] = [] type_comment = n.type_comment if (n.decorator_list and any( is_no_type_check_decorator(d) for d in n.decorator_list)): arg_types = [None] * len(args) return_type = None elif type_comment is not None and len(type_comment) > 0: try: func_type_ast = ast3_parse(type_comment, '<func_type>', 'func_type') assert isinstance(func_type_ast, ast3.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance( func_type_ast.argtypes[0], ast3.Ellipsis)): arg_types = [ a.type_annotation if a.type_annotation is not None else AnyType(TypeOfAny.unannotated) for a in args ] else: # PEP 484 disallows both type annotations and type comments if any(a.type_annotation is not None for a in args): self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset) arg_types = [ a if a is not None else AnyType(TypeOfAny.unannotated) for a in converter.translate_expr_list( func_type_ast.argtypes) ] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_method_scope() and len(arg_types) < len(args): arg_types.insert(0, AnyType(TypeOfAny.special_form)) except SyntaxError: stripped_type = type_comment.split("#", 2)[0].strip() err_msg = '{} "{}"'.format(TYPE_COMMENT_SYNTAX_ERROR, stripped_type) self.fail(err_msg, lineno, n.col_offset) arg_types = [AnyType(TypeOfAny.from_error)] * len(args) return_type = AnyType(TypeOfAny.from_error) else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) func_type = None if any(arg_types) or return_type: if len(arg_types) != 1 and any( isinstance(t, EllipsisType) for t in arg_types): self.fail( "Ellipses cannot accompany other argument types " "in function type signature", lineno, n.col_offset) elif len(arg_types) > len(arg_kinds): self.fail('Type signature has too many arguments', lineno, n.col_offset, blocker=False) elif len(arg_types) < len(arg_kinds): self.fail('Type signature has too few arguments', lineno, n.col_offset, blocker=False) else: any_type = AnyType(TypeOfAny.unannotated) func_type = CallableType( [a if a is not None else any_type for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else any_type, _dummy_fallback) body = self.as_required_block(n.body, lineno) if decompose_stmts: body.body = decompose_stmts + body.body func_def = FuncDef(n.name, args, body, func_type) if isinstance(func_def.type, CallableType): # semanal.py does some in-place modifications we want to avoid func_def.unanalyzed_type = func_def.type.copy_modified() if func_type is not None: func_type.definition = func_def func_type.line = lineno if n.decorator_list: var = Var(func_def.name) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) dec = Decorator(func_def, self.translate_expr_list(n.decorator_list), var) dec.set_line(lineno, n.col_offset) retval: Statement = dec else: # Overrides set_line -- can't use self.set_line func_def.set_line(lineno, n.col_offset) retval = func_def self.class_and_function_stack.pop() return retval
def transform_args(self, n: ast27.arguments, line: int, ) -> Tuple[List[Argument], List[Statement]]: type_comments = n.type_comments converter = TypeConverter(self.errors, line=line) decompose_stmts = [] # type: List[Statement] def extract_names(arg: ast27.expr) -> List[str]: if isinstance(arg, ast27.Name): return [arg.id] elif isinstance(arg, ast27.Tuple): return [name for elt in arg.elts for name in extract_names(elt)] else: return [] def convert_arg(index: int, arg: ast27.expr) -> Var: if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): v = '__tuple_arg_{}'.format(index + 1) rvalue = NameExpr(v) rvalue.set_line(line) assignment = AssignmentStmt([self.visit(arg)], rvalue) assignment.set_line(line) decompose_stmts.append(assignment) else: raise RuntimeError("'{}' is not a valid argument.".format(ast27.dump(arg))) return Var(v) def get_type(i: int) -> Optional[Type]: if i < len(type_comments) and type_comments[i] is not None: return converter.visit_raw_str(type_comments[i]) return None args = [(convert_arg(i, arg), get_type(i)) for i, arg in enumerate(n.args)] defaults = self.translate_expr_list(n.defaults) names = [name for arg in n.args for name in extract_names(arg)] # type: List[str] new_args = [] # type: List[Argument] num_no_defaults = len(args) - len(defaults) # positional arguments without defaults for a, annotation in args[:num_no_defaults]: new_args.append(Argument(a, annotation, None, ARG_POS)) # positional arguments with defaults for (a, annotation), d in zip(args[num_no_defaults:], defaults): new_args.append(Argument(a, annotation, d, ARG_OPT)) # *arg if n.vararg is not None: new_args.append(Argument(Var(n.vararg), get_type(len(args)), None, ARG_STAR)) names.append(n.vararg) # **kwarg if n.kwarg is not None: typ = get_type(len(args) + (0 if n.vararg is None else 1)) new_args.append(Argument(Var(n.kwarg), typ, None, ARG_STAR2)) names.append(n.kwarg) # We don't have any context object to give, but we have closed around the line num def fail_arg(msg: str, arg: None) -> None: self.fail(msg, line, 0) check_arg_names(names, [None] * len(names), fail_arg) return new_args, decompose_stmts
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: converter = TypeConverter(self.errors, line=n.lineno) args, decompose_stmts = self.transform_args(n.args, n.lineno) arg_kinds = [arg.kind for arg in args] arg_names = [arg.variable.name() for arg in args] # type: List[Optional[str]] arg_names = [None if argument_elide_name(name) else name for name in arg_names] if special_function_elide_names(n.name): arg_names = [None] * len(arg_names) arg_types = [] # type: List[Optional[Type]] if (n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)): arg_types = [None] * len(args) return_type = None elif n.type_comment is not None and len(n.type_comment) > 0: try: func_type_ast = ast3.parse(n.type_comment, '<func_type>', 'func_type') assert isinstance(func_type_ast, ast3.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance(func_type_ast.argtypes[0], ast3.Ellipsis)): arg_types = [a.type_annotation if a.type_annotation is not None else AnyType(TypeOfAny.unannotated) for a in args] else: # PEP 484 disallows both type annotations and type comments if any(a.type_annotation is not None for a in args): self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) arg_types = [a if a is not None else AnyType(TypeOfAny.unannotated) for a in converter.translate_expr_list(func_type_ast.argtypes)] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_class() and len(arg_types) < len(args): arg_types.insert(0, AnyType(TypeOfAny.special_form)) except SyntaxError: self.fail(TYPE_COMMENT_SYNTAX_ERROR, n.lineno, n.col_offset) arg_types = [AnyType(TypeOfAny.from_error)] * len(args) return_type = AnyType(TypeOfAny.from_error) else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) func_type = None if any(arg_types) or return_type: if len(arg_types) != 1 and any(isinstance(t, EllipsisType) for t in arg_types): self.fail("Ellipses cannot accompany other argument types " "in function type signature.", n.lineno, 0) elif len(arg_types) > len(arg_kinds): self.fail('Type signature has too many arguments', n.lineno, 0) elif len(arg_types) < len(arg_kinds): self.fail('Type signature has too few arguments', n.lineno, 0) else: any_type = AnyType(TypeOfAny.unannotated) func_type = CallableType([a if a is not None else any_type for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else any_type, _dummy_fallback) body = self.as_required_block(n.body, n.lineno) if decompose_stmts: body.body = decompose_stmts + body.body func_def = FuncDef(n.name, args, body, func_type) if func_type is not None: func_type.definition = func_def func_type.line = n.lineno if n.decorator_list: var = Var(func_def.name()) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(n.lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) return Decorator(func_def, self.translate_expr_list(n.decorator_list), var) else: return func_def
def transform_args( self, n: ast27.arguments, line: int, ) -> Tuple[List[Argument], List[Statement]]: # TODO: remove the cast once https://github.com/python/typeshed/pull/522 # is accepted and synced type_comments = cast(List[str], n.type_comments) # type: ignore converter = TypeConverter(self.errors, line=line) decompose_stmts = [] # type: List[Statement] def extract_names(arg: ast27.expr) -> List[str]: if isinstance(arg, ast27.Name): return [arg.id] elif isinstance(arg, ast27.Tuple): return [ name for elt in arg.elts for name in extract_names(elt) ] else: return [] def convert_arg(index: int, arg: ast27.expr) -> Var: if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): v = '__tuple_arg_{}'.format(index + 1) rvalue = NameExpr(v) rvalue.set_line(line) assignment = AssignmentStmt([self.visit(arg)], rvalue) assignment.set_line(line) decompose_stmts.append(assignment) else: raise RuntimeError("'{}' is not a valid argument.".format( ast27.dump(arg))) return Var(v) def get_type(i: int) -> Optional[Type]: if i < len(type_comments) and type_comments[i] is not None: return converter.visit_raw_str(type_comments[i]) return None args = [(convert_arg(i, arg), get_type(i)) for i, arg in enumerate(n.args)] defaults = self.translate_expr_list(n.defaults) names = [name for arg in n.args for name in extract_names(arg)] # type: List[str] new_args = [] # type: List[Argument] num_no_defaults = len(args) - len(defaults) # positional arguments without defaults for a, annotation in args[:num_no_defaults]: new_args.append(Argument(a, annotation, None, ARG_POS)) # positional arguments with defaults for (a, annotation), d in zip(args[num_no_defaults:], defaults): new_args.append(Argument(a, annotation, d, ARG_OPT)) # *arg if n.vararg is not None: new_args.append( Argument(Var(n.vararg), get_type(len(args)), None, ARG_STAR)) names.append(n.vararg) # **kwarg if n.kwarg is not None: typ = get_type(len(args) + (0 if n.vararg is None else 1)) new_args.append(Argument(Var(n.kwarg), typ, None, ARG_STAR2)) names.append(n.kwarg) seen_names = set() # type: Set[str] for name in names: if name in seen_names: self.fail( "duplicate argument '{}' in function definition".format( name), line, 0) break seen_names.add(name) return new_args, decompose_stmts
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: converter = TypeConverter(line=n.lineno) args = self.transform_args(n.args, n.lineno) arg_kinds = [arg.kind for arg in args] arg_names = [arg.variable.name() for arg in args] arg_types = None # type: List[Type] if n.type_comment is not None and len(n.type_comment) > 0: try: func_type_ast = ast35.parse(n.type_comment, '<func_type>', 'func_type') except SyntaxError: raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, n.lineno, n.col_offset) assert isinstance(func_type_ast, ast35.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance(func_type_ast.argtypes[0], ast35.Ellipsis)): arg_types = [ a.type_annotation if a.type_annotation is not None else AnyType() for a in args ] else: arg_types = [ a if a is not None else AnyType() for a in converter.translate_expr_list(func_type_ast.argtypes) ] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_class() and len(arg_types) < len(args): arg_types.insert(0, AnyType()) else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) if isinstance(return_type, UnboundType): return_type.is_ret_type = True func_type = None if any(arg_types) or return_type: if len(arg_types) > len(arg_kinds): raise FastParserError('Type signature has too many arguments', n.lineno, offset=0) if len(arg_types) < len(arg_kinds): raise FastParserError('Type signature has too few arguments', n.lineno, offset=0) func_type = CallableType( [a if a is not None else AnyType() for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else AnyType(), None) func_def = FuncDef(n.name, args, self.as_block(n.body, n.lineno), func_type) if func_type is not None: func_type.definition = func_def func_type.line = n.lineno if n.decorator_list: var = Var(func_def.name()) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(n.lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) return Decorator(func_def, self.translate_expr_list(n.decorator_list), var) else: return func_def
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: converter = TypeConverter(line=n.lineno) args = self.transform_args(n.args, n.lineno) arg_kinds = [arg.kind for arg in args] arg_names = [arg.variable.name() for arg in args] arg_types = None # type: List[Type] if n.type_comment is not None and len(n.type_comment) > 0: try: func_type_ast = ast35.parse(n.type_comment, '<func_type>', 'func_type') except SyntaxError: raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, n.lineno, n.col_offset) assert isinstance(func_type_ast, ast35.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance(func_type_ast.argtypes[0], ast35.Ellipsis)): arg_types = [a.type_annotation if a.type_annotation is not None else AnyType() for a in args] else: arg_types = [a if a is not None else AnyType() for a in converter.translate_expr_list(func_type_ast.argtypes)] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_class() and len(arg_types) < len(args): arg_types.insert(0, AnyType()) else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) if isinstance(return_type, UnboundType): return_type.is_ret_type = True func_type = None if any(arg_types) or return_type: if len(arg_types) > len(arg_kinds): raise FastParserError('Type signature has too many arguments', n.lineno, offset=0) if len(arg_types) < len(arg_kinds): raise FastParserError('Type signature has too few arguments', n.lineno, offset=0) func_type = CallableType([a if a is not None else AnyType() for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else AnyType(), None) func_def = FuncDef(n.name, args, self.as_block(n.body, n.lineno), func_type) if func_type is not None: func_type.definition = func_def func_type.line = n.lineno if n.decorator_list: var = Var(func_def.name()) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(n.lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) return Decorator(func_def, self.translate_expr_list(n.decorator_list), var) else: return func_def
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: lineno = n.lineno converter = TypeConverter(self.errors, line=lineno, assume_str_is_unicode=self.unicode_literals) args, decompose_stmts = self.transform_args(n.args, lineno) arg_kinds = [arg.kind for arg in args] arg_names = [arg.variable.name() for arg in args] # type: List[Optional[str]] arg_names = [None if argument_elide_name(name) else name for name in arg_names] if special_function_elide_names(n.name): arg_names = [None] * len(arg_names) arg_types = [] # type: List[Optional[Type]] type_comment = n.type_comment if (n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)): arg_types = [None] * len(args) return_type = None elif type_comment is not None and len(type_comment) > 0: try: func_type_ast = ast3_parse(type_comment, '<func_type>', 'func_type') assert isinstance(func_type_ast, ast3.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance(func_type_ast.argtypes[0], ast3.Ellipsis)): arg_types = [a.type_annotation if a.type_annotation is not None else AnyType(TypeOfAny.unannotated) for a in args] else: # PEP 484 disallows both type annotations and type comments if any(a.type_annotation is not None for a in args): self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset) arg_types = [a if a is not None else AnyType(TypeOfAny.unannotated) for a in converter.translate_expr_list(func_type_ast.argtypes)] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_class() and len(arg_types) < len(args): arg_types.insert(0, AnyType(TypeOfAny.special_form)) except SyntaxError: self.fail(TYPE_COMMENT_SYNTAX_ERROR, lineno, n.col_offset) arg_types = [AnyType(TypeOfAny.from_error)] * len(args) return_type = AnyType(TypeOfAny.from_error) else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) func_type = None if any(arg_types) or return_type: if len(arg_types) != 1 and any(isinstance(t, EllipsisType) for t in arg_types): self.fail("Ellipses cannot accompany other argument types " "in function type signature.", lineno, 0) elif len(arg_types) > len(arg_kinds): self.fail('Type signature has too many arguments', lineno, 0) elif len(arg_types) < len(arg_kinds): self.fail('Type signature has too few arguments', lineno, 0) else: any_type = AnyType(TypeOfAny.unannotated) func_type = CallableType([a if a is not None else any_type for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else any_type, _dummy_fallback) body = self.as_required_block(n.body, lineno) if decompose_stmts: body.body = decompose_stmts + body.body func_def = FuncDef(n.name, args, body, func_type) if isinstance(func_def.type, CallableType): # semanal.py does some in-place modifications we want to avoid func_def.unanalyzed_type = func_def.type.copy_modified() if func_type is not None: func_type.definition = func_def func_type.line = lineno if n.decorator_list: var = Var(func_def.name()) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) dec = Decorator(func_def, self.translate_expr_list(n.decorator_list), var) dec.set_line(lineno, n.col_offset) return dec else: # Overrides set_line -- can't use self.set_line func_def.set_line(lineno, n.col_offset) return func_def
def visit_FunctionDef(self, n: ast27.FunctionDef) -> Statement: converter = TypeConverter(self.errors, line=n.lineno) args, decompose_stmts = self.transform_args(n.args, n.lineno) arg_kinds = [arg.kind for arg in args] arg_names = [arg.variable.name() for arg in args] # type: List[Optional[str]] arg_names = [None if argument_elide_name(name) else name for name in arg_names] if special_function_elide_names(n.name): arg_names = [None] * len(arg_names) arg_types = None # type: List[Type] if (n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)): arg_types = [None] * len(args) return_type = None elif n.type_comment is not None and len(n.type_comment) > 0: try: func_type_ast = ast35.parse(n.type_comment, '<func_type>', 'func_type') assert isinstance(func_type_ast, ast35.FunctionType) # for ellipsis arg if (len(func_type_ast.argtypes) == 1 and isinstance(func_type_ast.argtypes[0], ast35.Ellipsis)): arg_types = [a.type_annotation if a.type_annotation is not None else AnyType() for a in args] else: # PEP 484 disallows both type annotations and type comments if any(a.type_annotation is not None for a in args): self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) arg_types = [a if a is not None else AnyType() for a in converter.translate_expr_list(func_type_ast.argtypes)] return_type = converter.visit(func_type_ast.returns) # add implicit self type if self.in_class() and len(arg_types) < len(args): arg_types.insert(0, AnyType()) except SyntaxError: self.fail(TYPE_COMMENT_SYNTAX_ERROR, n.lineno, n.col_offset) arg_types = [AnyType()] * len(args) return_type = AnyType() else: arg_types = [a.type_annotation for a in args] return_type = converter.visit(None) for arg, arg_type in zip(args, arg_types): self.set_type_optional(arg_type, arg.initializer) if isinstance(return_type, UnboundType): return_type.is_ret_type = True func_type = None if any(arg_types) or return_type: if len(arg_types) != 1 and any(isinstance(t, EllipsisType) for t in arg_types): self.fail("Ellipses cannot accompany other argument types " "in function type signature.", n.lineno, 0) elif len(arg_types) > len(arg_kinds): self.fail('Type signature has too many arguments', n.lineno, 0) elif len(arg_types) < len(arg_kinds): self.fail('Type signature has too few arguments', n.lineno, 0) else: func_type = CallableType([a if a is not None else AnyType() for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else AnyType(), None) body = self.as_block(n.body, n.lineno) if decompose_stmts: body.body = decompose_stmts + body.body func_def = FuncDef(n.name, args, body, func_type) if func_type is not None: func_type.definition = func_def func_type.line = n.lineno if n.decorator_list: var = Var(func_def.name()) var.is_ready = False var.set_line(n.decorator_list[0].lineno) func_def.is_decorated = True func_def.set_line(n.lineno + len(n.decorator_list)) func_def.body.set_line(func_def.get_line()) return Decorator(func_def, self.translate_expr_list(n.decorator_list), var) else: return func_def