Пример #1
0
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)
Пример #2
0
    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