def visit_FunctionDef(self, n: ast35.FunctionDef) -> Node: 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: try: func_type_ast = ast35.parse(n.type_comment, '<func_type>', 'func_type') except SyntaxError: raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, n.lineno) 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 TypeConverter(line=n.lineno).visit_list(func_type_ast.argtypes)] return_type = TypeConverter(line=n.lineno).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 = TypeConverter(line=n.lineno).visit(n.returns) if isinstance(return_type, UnboundType): return_type.is_ret_type = True func_type = None if any(arg_types) or return_type: 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.visit_list(n.decorator_list), var) else: return func_def
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 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 do_func_def(self, n: Union[ast3.FunctionDef, ast3.AsyncFunctionDef], is_coroutine: bool = False) -> Union[FuncDef, Decorator]: """Helper shared between visit_FunctionDef and visit_AsyncFunctionDef.""" no_type_check = bool( n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)) args = self.transform_args(n.args, n.lineno, no_type_check=no_type_check) 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 no_type_check: arg_types = [None] * len(args) return_type = None elif n.type_comment is not None: 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)): if n.returns: # PEP 484 disallows both type annotations and type comments self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) 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 n.returns or any(a.type_annotation is not None for a in args): self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) translated_args = (TypeConverter( self.errors, line=n.lineno).translate_expr_list( func_type_ast.argtypes)) arg_types = [ a if a is not None else AnyType() for a in translated_args ] return_type = TypeConverter(self.errors, line=n.lineno).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 = TypeConverter(self.errors, line=n.lineno).visit(n.returns) 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(implicit=True) for a in arg_types ], arg_kinds, arg_names, return_type if return_type is not None else AnyType( implicit=True), None) func_def = FuncDef(n.name, args, self.as_block(n.body, n.lineno), func_type) if is_coroutine: # A coroutine is also a generator, mostly for internal reasons. func_def.is_generator = func_def.is_coroutine = True 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 do_func_def(self, n: Union[ast35.FunctionDef, ast35.AsyncFunctionDef], is_coroutine: bool = False) -> Union[FuncDef, Decorator]: """Helper shared between visit_FunctionDef and visit_AsyncFunctionDef.""" 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: 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: translated_args = (TypeConverter(line=n.lineno) .translate_expr_list(func_type_ast.argtypes)) arg_types = [a if a is not None else AnyType() for a in translated_args] return_type = TypeConverter(line=n.lineno).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 = TypeConverter(line=n.lineno).visit(n.returns) 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: 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 is_coroutine: # A coroutine is also a generator, mostly for internal reasons. func_def.is_generator = func_def.is_coroutine = True 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(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] # 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.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 do_func_def(self, n: Union[ast35.FunctionDef, ast35.AsyncFunctionDef], is_coroutine: bool = False) -> Union[FuncDef, Decorator]: """Helper shared between visit_FunctionDef and visit_AsyncFunctionDef.""" no_type_check = bool(n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)) args = self.transform_args(n.args, n.lineno, no_type_check=no_type_check) 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 no_type_check: arg_types = [None] * len(args) return_type = None elif n.type_comment is not None: 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)): if n.returns: # PEP 484 disallows both type annotations and type comments self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) 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 n.returns or any(a.type_annotation is not None for a in args): self.fail(messages.DUPLICATE_TYPE_SIGNATURES, n.lineno, n.col_offset) translated_args = (TypeConverter(self.errors, line=n.lineno) .translate_expr_list(func_type_ast.argtypes)) arg_types = [a if a is not None else AnyType() for a in translated_args] return_type = TypeConverter(self.errors, line=n.lineno).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 = TypeConverter(self.errors, line=n.lineno).visit(n.returns) 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(implicit=True) for a in arg_types], arg_kinds, arg_names, return_type if return_type is not None else AnyType(implicit=True), None) func_def = FuncDef(n.name, args, self.as_block(n.body, n.lineno), func_type) if is_coroutine: # A coroutine is also a generator, mostly for internal reasons. func_def.is_generator = func_def.is_coroutine = True 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 do_func_def(self, n: Union[ast3.FunctionDef, ast3.AsyncFunctionDef], is_coroutine: bool = False) -> Union[FuncDef, Decorator]: """Helper shared between visit_FunctionDef and visit_AsyncFunctionDef.""" no_type_check = bool( n.decorator_list and any(is_no_type_check_decorator(d) for d in n.decorator_list)) args = self.transform_args(n.args, n.lineno, no_type_check=no_type_check) 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 no_type_check: arg_types = [None] * len(args) return_type = None elif n.type_comment is not None: 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)): if n.returns: # PEP 484 disallows both type annotations and type comments self.fail(errorcode.DUPLICATE_TYPE_SIGNATURES(), n.lineno, n.col_offset) 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 n.returns or any(a.type_annotation is not None for a in args): self.fail(errorcode.DUPLICATE_TYPE_SIGNATURES(), n.lineno, n.col_offset) translated_args = (TypeConverter( self.errors, line=n.lineno).translate_expr_list( func_type_ast.argtypes)) arg_types = [ a if a is not None else AnyType(TypeOfAny.unannotated) for a in translated_args ] return_type = TypeConverter(self.errors, line=n.lineno).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(errorcode.SYNTAX_ERROR_TYPE_COMMENT(), n.lineno, n.col_offset) if n.type_comment and n.type_comment[0] != "(": self.note( errorcode.MSG_SHOW( 'Suggestion: wrap argument types in parentheses'), 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 = TypeConverter( self.errors, line=n.returns.lineno if n.returns else n.lineno).visit( n.returns) 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( errorcode. ELLIPSES_CANNOT_ACC_OTHER_ARG_TYPES_IN_FUNCTION_TYPE_SIGNATURE( ), n.lineno, 0) elif len(arg_types) > len(arg_kinds): self.fail(errorcode.TYPE_SIGNATURE_HAS_TOO_MANY_ARGUMENTS(), n.lineno, 0) elif len(arg_types) < len(arg_kinds): self.fail(errorcode.TYPE_SIGNATURE_HAS_TOO_FEW_ARGUMENTS(), n.lineno, 0) else: func_type = CallableType([ a if a is not None else AnyType(TypeOfAny.unannotated) for a in arg_types ], arg_kinds, arg_names, return_type if return_type is not None else AnyType(TypeOfAny.unannotated), _dummy_fallback) func_def = FuncDef(n.name, args, self.as_required_block(n.body, n.lineno), func_type) if is_coroutine: # A coroutine is also a generator, mostly for internal reasons. func_def.is_generator = func_def.is_coroutine = True 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(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
def do_func_def(self, n: Union[ast35.FunctionDef, ast35.AsyncFunctionDef], is_coroutine: bool = False) -> Union[FuncDef, Decorator]: """Helper shared between visit_FunctionDef and visit_AsyncFunctionDef.""" 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: 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: translated_args = (TypeConverter(line=n.lineno) .translate_expr_list(func_type_ast.argtypes)) arg_types = [a if a is not None else AnyType() for a in translated_args] return_type = TypeConverter(line=n.lineno).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 = TypeConverter(line=n.lineno).visit(n.returns) 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 is_coroutine: # A coroutine is also a generator, mostly for internal reasons. func_def.is_generator = func_def.is_coroutine = True 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