Exemplo n.º 1
0
    def visit_Call(self, e: ast3.Call) -> Type:
        # Parse the arg constructor
        f = e.func
        constructor = stringify_name(f)

        if not isinstance(self.parent(), ast3.List):
            self.fail(errorcode.TYPE_COMMENT_OR_ANNOTATION_AST_ERROR(),
                      self.line, e.col_offset)
            if constructor:
                self.note(errorcode.ARGS_CONSTRUCTOR_SUGGESTION(constructor),
                          self.line, e.col_offset)
            return AnyType(TypeOfAny.from_error)
        if not constructor:
            self.fail(errorcode.EXPECTED_ARGS_CONSTRUCTOR_NAME(), e.lineno,
                      e.col_offset)

        name = None  # type: Optional[str]
        default_type = AnyType(TypeOfAny.special_form)
        typ = default_type  # type: Type
        for i, arg in enumerate(e.args):
            if i == 0:
                converted = self.visit(arg)
                assert converted is not None
                typ = converted
            elif i == 1:
                name = self._extract_argument_name(arg)
            else:
                self.fail(
                    errorcode.TOO_MANY_ARGUMENTS_FOR_ARGUMENT_CONSTRUCTOR(),
                    f.lineno, f.col_offset)
        for k in e.keywords:
            value = k.value
            if k.arg == "name":
                if name is not None:
                    self.fail(
                        errorcode.GETS_MULTIPLE_VALUES_FOR_KEYWORD_ARG_TYPE(
                            constructor), f.lineno, f.col_offset)
                name = self._extract_argument_name(value)
            elif k.arg == "type":
                if typ is not default_type:
                    self.fail(
                        errorcode.GETS_MULTIPLE_VALUES_FOR_KEYWORD_ARG_TYPE(
                            constructor), f.lineno, f.col_offset)
                converted = self.visit(value)
                assert converted is not None
                typ = converted
            else:
                self.fail(
                    errorcode.UNEXPECTED_ARGUMENT_FOR_CONSTRUCTOR_ARG(k.arg),
                    value.lineno, value.col_offset)
        return CallableArgument(typ, name, constructor, e.lineno, e.col_offset)
Exemplo n.º 2
0
    def visit_Call(self, e: ast3.Call) -> Type:
        # Parse the arg constructor
        f = e.func
        constructor = stringify_name(f)

        if not isinstance(self.parent(), ast3.List):
            self.fail(TYPE_COMMENT_AST_ERROR, self.line, e.col_offset)
            if constructor:
                self.note(
                    "Suggestion: use {}[...] instead of {}(...)".format(
                        constructor, constructor), self.line, e.col_offset)
            return AnyType(TypeOfAny.from_error)
        if not constructor:
            self.fail("Expected arg constructor name", e.lineno, e.col_offset)

        name = None  # type: Optional[str]
        default_type = AnyType(TypeOfAny.special_form)
        typ = default_type  # type: Type
        for i, arg in enumerate(e.args):
            if i == 0:
                converted = self.visit(arg)
                assert converted is not None
                typ = converted
            elif i == 1:
                name = self._extract_argument_name(arg)
            else:
                self.fail("Too many arguments for argument constructor",
                          f.lineno, f.col_offset)
        for k in e.keywords:
            value = k.value
            if k.arg == "name":
                if name is not None:
                    self.fail(
                        '"{}" gets multiple values for keyword argument "name"'
                        .format(constructor), f.lineno, f.col_offset)
                name = self._extract_argument_name(value)
            elif k.arg == "type":
                if typ is not default_type:
                    self.fail(
                        '"{}" gets multiple values for keyword argument "type"'
                        .format(constructor), f.lineno, f.col_offset)
                converted = self.visit(value)
                assert converted is not None
                typ = converted
            else:
                self.fail(
                    'Unexpected argument "{}" for argument constructor'.format(
                        k.arg), value.lineno, value.col_offset)
        return CallableArgument(typ, name, constructor, e.lineno, e.col_offset)
Exemplo n.º 3
0
 def visit_Call(self, e: ast3.Call) -> Type:
     # Parse the arg constructor
     if not isinstance(self.parent(), ast3.List):
         return self.generic_visit(e)
     f = e.func
     constructor = stringify_name(f)
     if not constructor:
         self.fail("Expected arg constructor name", e.lineno, e.col_offset)
     name = None  # type: Optional[str]
     default_type = AnyType(implicit=True)
     typ = default_type  # type: Type
     for i, arg in enumerate(e.args):
         if i == 0:
             typ = self.visit(arg)
         elif i == 1:
             name = self._extract_argument_name(arg)
         else:
             self.fail("Too many arguments for argument constructor",
                       f.lineno, f.col_offset)
     for k in e.keywords:
         value = k.value
         if k.arg == "name":
             if name is not None:
                 self.fail(
                     '"{}" gets multiple values for keyword argument "name"'
                     .format(constructor), f.lineno, f.col_offset)
             name = self._extract_argument_name(value)
         elif k.arg == "type":
             if typ is not default_type:
                 self.fail(
                     '"{}" gets multiple values for keyword argument "type"'
                     .format(constructor), f.lineno, f.col_offset)
             typ = self.visit(value)
         else:
             self.fail(
                 'Unexpected argument "{}" for argument constructor'.format(
                     k.arg), value.lineno, value.col_offset)
     return CallableArgument(typ, name, constructor, e.lineno, e.col_offset)
Exemplo n.º 4
0
def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = None) -> ProperType:
    """Translate an expression to the corresponding type.

    The result is not semantically analyzed. It can be UnboundType or TypeList.
    Raise TypeTranslationError if the expression cannot represent a type.
    """
    # The `parent` parameter is used in recursive calls to provide context for
    # understanding whether an CallableArgument is ok.
    name = None  # type: Optional[str]
    if isinstance(expr, NameExpr):
        name = expr.name
        if name == 'True':
            return RawExpressionType(True, 'builtins.bool', line=expr.line, column=expr.column)
        elif name == 'False':
            return RawExpressionType(False, 'builtins.bool', line=expr.line, column=expr.column)
        else:
            return UnboundType(name, line=expr.line, column=expr.column)
    elif isinstance(expr, MemberExpr):
        fullname = get_member_expr_fullname(expr)
        if fullname:
            return UnboundType(fullname, line=expr.line, column=expr.column)
        else:
            raise TypeTranslationError()
    elif isinstance(expr, IndexExpr):
        base = expr_to_unanalyzed_type(expr.base, expr)
        if isinstance(base, UnboundType):
            if base.args:
                raise TypeTranslationError()
            if isinstance(expr.index, TupleExpr):
                args = expr.index.items
            else:
                args = [expr.index]
            base.args = tuple(expr_to_unanalyzed_type(arg, expr) for arg in args)
            if not base.args:
                base.empty_tuple_index = True
            return base
        else:
            raise TypeTranslationError()
    elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr):
        c = expr.callee
        names = []
        # Go through the dotted member expr chain to get the full arg
        # constructor name to look up
        while True:
            if isinstance(c, NameExpr):
                names.append(c.name)
                break
            elif isinstance(c, MemberExpr):
                names.append(c.name)
                c = c.expr
            else:
                raise TypeTranslationError()
        arg_const = '.'.join(reversed(names))

        # Go through the constructor args to get its name and type.
        name = None
        default_type = AnyType(TypeOfAny.unannotated)
        typ = default_type  # type: Type
        for i, arg in enumerate(expr.args):
            if expr.arg_names[i] is not None:
                if expr.arg_names[i] == "name":
                    if name is not None:
                        # Two names
                        raise TypeTranslationError()
                    name = _extract_argument_name(arg)
                    continue
                elif expr.arg_names[i] == "type":
                    if typ is not default_type:
                        # Two types
                        raise TypeTranslationError()
                    typ = expr_to_unanalyzed_type(arg, expr)
                    continue
                else:
                    raise TypeTranslationError()
            elif i == 0:
                typ = expr_to_unanalyzed_type(arg, expr)
            elif i == 1:
                name = _extract_argument_name(arg)
            else:
                raise TypeTranslationError()
        return CallableArgument(typ, name, arg_const, expr.line, expr.column)
    elif isinstance(expr, ListExpr):
        return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items],
                        line=expr.line, column=expr.column)
    elif isinstance(expr, StrExpr):
        return parse_type_string(expr.value, 'builtins.str', expr.line, expr.column,
                                 assume_str_is_unicode=expr.from_python_3)
    elif isinstance(expr, BytesExpr):
        return parse_type_string(expr.value, 'builtins.bytes', expr.line, expr.column,
                                 assume_str_is_unicode=False)
    elif isinstance(expr, UnicodeExpr):
        return parse_type_string(expr.value, 'builtins.unicode', expr.line, expr.column,
                                 assume_str_is_unicode=True)
    elif isinstance(expr, UnaryExpr):
        typ = expr_to_unanalyzed_type(expr.expr)
        if isinstance(typ, RawExpressionType):
            if isinstance(typ.literal_value, int) and expr.op == '-':
                typ.literal_value *= -1
                return typ
        raise TypeTranslationError()
    elif isinstance(expr, IntExpr):
        return RawExpressionType(expr.value, 'builtins.int', line=expr.line, column=expr.column)
    elif isinstance(expr, FloatExpr):
        # Floats are not valid parameters for RawExpressionType , so we just
        # pass in 'None' for now. We'll report the appropriate error at a later stage.
        return RawExpressionType(None, 'builtins.float', line=expr.line, column=expr.column)
    elif isinstance(expr, ComplexExpr):
        # Same thing as above with complex numbers.
        return RawExpressionType(None, 'builtins.complex', line=expr.line, column=expr.column)
    elif isinstance(expr, EllipsisExpr):
        return EllipsisType(expr.line)
    else:
        raise TypeTranslationError()
Exemplo n.º 5
0
def expr_to_unanalyzed_type(expr: Expression,
                            _parent: Optional[Expression] = None) -> Type:
    """Translate an expression to the corresponding type.

    The result is not semantically analyzed. It can be UnboundType or TypeList.
    Raise TypeTranslationError if the expression cannot represent a type.
    """
    # The `parent` parameter is used in recursive calls to provide context for
    # understanding whether an CallableArgument is ok.
    name = None  # type: Optional[str]
    if isinstance(expr, NameExpr):
        name = expr.name
        return UnboundType(name, line=expr.line, column=expr.column)
    elif isinstance(expr, MemberExpr):
        fullname = get_member_expr_fullname(expr)
        if fullname:
            return UnboundType(fullname, line=expr.line, column=expr.column)
        else:
            raise TypeTranslationError()
    elif isinstance(expr, IndexExpr):
        base = expr_to_unanalyzed_type(expr.base, expr)
        if isinstance(base, UnboundType):
            if base.args:
                raise TypeTranslationError()
            if isinstance(expr.index, TupleExpr):
                args = expr.index.items
            else:
                args = [expr.index]
            base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args]
            if not base.args:
                base.empty_tuple_index = True
            return base
        else:
            raise TypeTranslationError()
    elif isinstance(expr, CallExpr) and isinstance(_parent, ListExpr):
        c = expr.callee
        names = []
        # Go through the dotted member expr chain to get the full arg
        # constructor name to look up
        while True:
            if isinstance(c, NameExpr):
                names.append(c.name)
                break
            elif isinstance(c, MemberExpr):
                names.append(c.name)
                c = c.expr
            else:
                raise TypeTranslationError()
        arg_const = '.'.join(reversed(names))

        # Go through the constructor args to get its name and type.
        name = None
        default_type = AnyType(TypeOfAny.unannotated)
        typ = default_type  # type: Type
        for i, arg in enumerate(expr.args):
            if expr.arg_names[i] is not None:
                if expr.arg_names[i] == "name":
                    if name is not None:
                        # Two names
                        raise TypeTranslationError()
                    name = _extract_argument_name(arg)
                    continue
                elif expr.arg_names[i] == "type":
                    if typ is not default_type:
                        # Two types
                        raise TypeTranslationError()
                    typ = expr_to_unanalyzed_type(arg, expr)
                    continue
                else:
                    raise TypeTranslationError()
            elif i == 0:
                typ = expr_to_unanalyzed_type(arg, expr)
            elif i == 1:
                name = _extract_argument_name(arg)
            else:
                raise TypeTranslationError()
        return CallableArgument(typ, name, arg_const, expr.line, expr.column)
    elif isinstance(expr, ListExpr):
        return TypeList([expr_to_unanalyzed_type(t, expr) for t in expr.items],
                        line=expr.line,
                        column=expr.column)
    elif isinstance(expr, (StrExpr, BytesExpr, UnicodeExpr)):
        # Parse string literal type.
        try:
            result = parse_type_comment(expr.value, expr.line, None)
            assert result is not None
        except SyntaxError:
            raise TypeTranslationError()
        return result
    elif isinstance(expr, EllipsisExpr):
        return EllipsisType(expr.line)
    else:
        raise TypeTranslationError()