Ejemplo n.º 1
0
 def visit_del_stmt(self, s):
     if isinstance(s.expr, IndexExpr):
         e = s.expr  # Cast
         m = MemberExpr(e.base, '__delitem__')
         m.line = s.line
         c = CallExpr(m, [e.index], [nodes.ARG_POS], [None])
         c.line = s.line
         return c.accept(self)
     else:
         return None # this case is handled in semantical analysis
Ejemplo n.º 2
0
 def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
     result_expression = StrExpr('')  # type: Expression
     for value_expr in self.translate_expr_list(n.values):
         string_method = MemberExpr(value_expr, '__str__')
         string_method.set_line(value_expr)
         stringified_value_expr = CallExpr(string_method, [], [])
         stringified_value_expr.set_line(value_expr)
         result_expression = OpExpr('+', result_expression,
                                    stringified_value_expr)
         result_expression.set_line(value_expr)
     return result_expression
Ejemplo n.º 3
0
    def visit_call_expr(self, e: CallExpr) -> None:
        if e.analyzed:
            # This is not an ordinary call.
            e.analyzed.accept(self)
            return

        super().visit_call_expr(e)

        # Do no coercions if this is a call to debugging facilities.
        if self.is_debugging_call_expr(e):
            return

        # Get the type of the callable (type variables in the context of the
        # enclosing class).
        ctype = self.get_type(e.callee)

        # Add coercions for the arguments.
        for i in range(len(e.args)):
            arg_type = AnyType()  # type: Type
            if isinstance(ctype, Callable):
                arg_type = ctype.arg_types[i]
            e.args[i] = self.coerce2(e.args[i], arg_type,
                                     self.get_type(e.args[i]),
                                     self.type_context())

        # Prepend type argument values to the call as needed.
        if isinstance(ctype, Callable) and cast(Callable,
                                                ctype).bound_vars != []:
            bound_vars = (cast(Callable, ctype)).bound_vars

            # If this is a constructor call (target is the constructor
            # of a generic type or superclass __init__), include also
            # instance type variables.  Otherwise filter them away --
            # include only generic function type variables.
            if (not (cast(Callable, ctype)).is_type_obj() and
                    not (isinstance(e.callee, SuperExpr) and
                         (cast(SuperExpr, e.callee)).name == '__init__')):
                # Filter instance type variables; only include function tvars.
                bound_vars = [(id, t) for id, t in bound_vars if id < 0]

            args = []  # type: List[Node]
            for i in range(len(bound_vars)):
                # Compile type variables to runtime type variable expressions.
                tv = translate_runtime_type_vars_in_context(
                    bound_vars[i][1],
                    self.type_context(),
                    self.is_java)
                args.append(TypeExpr(tv))
            e.args = args + e.args
Ejemplo n.º 4
0
    def make_superclass_constructor_call(
            self, info: TypeInfo, callee_type: Callable) -> ExpressionStmt:
        """Construct a statement that calls the superclass constructor.

        In particular, it passes any type variables arguments as needed.
        """
        callee = SuperExpr('__init__')
        callee.info = info
        
        # We do not handle generic constructors. Either pass runtime
        # type variables from the current scope or perhaps require
        # explicit constructor in this case.
        
        selftype = self_type(info)    
        
        # FIX overloading
        # FIX default args / varargs
        
        # Map self type to the superclass context.
        base = info.mro[1]
        selftype = map_instance_to_supertype(selftype, base)
        
        super_init = cast(FuncDef, base.get_method('__init__'))
        
        # Add constructor arguments.
        args = [] # type: List[Node]
        for n in range(1, callee_type.min_args):            
            args.append(NameExpr(super_init.args[n].name()))
            self.tf.set_type(args[-1], callee_type.arg_types[n])

        # Store callee type after stripping away the 'self' type.
        self.tf.set_type(callee, nodes.method_callable(callee_type))
        
        call = CallExpr(callee, args, [nodes.ARG_POS] * len(args))
        return ExpressionStmt(call)
Ejemplo n.º 5
0
    def visit_Call(self, n: Call) -> CallExpr:
        arg_types: List[ast27.expr] = []
        arg_kinds: List[ArgKind] = []
        signature: List[Optional[str]] = []

        args = n.args
        arg_types.extend(args)
        arg_kinds.extend(ARG_POS for a in args)
        signature.extend(None for a in args)

        if n.starargs is not None:
            arg_types.append(n.starargs)
            arg_kinds.append(ARG_STAR)
            signature.append(None)

        keywords = n.keywords
        arg_types.extend(k.value for k in keywords)
        arg_kinds.extend(ARG_NAMED for k in keywords)
        signature.extend(k.arg for k in keywords)

        if n.kwargs is not None:
            arg_types.append(n.kwargs)
            arg_kinds.append(ARG_STAR2)
            signature.append(None)

        e = CallExpr(self.visit(n.func), self.translate_expr_list(arg_types),
                     arg_kinds, signature)
        return self.set_line(e, n)
Ejemplo n.º 6
0
def _apply_type_to_mapped_statement(
    api: SemanticAnalyzerPluginInterface,
    stmt: AssignmentStmt,
    lvalue: NameExpr,
    left_hand_explicit_type: Optional[Union[Instance, UnionType]],
    python_type_for_type: Union[Instance, UnionType],
) -> None:
    """Apply the Mapped[<type>] annotation and right hand object to a
    declarative assignment statement.

    This converts a Python declarative class statement such as::

        class User(Base):
            # ...

            attrname = Column(Integer)

    To one that describes the final Python behavior to Mypy::

        class User(Base):
            # ...

            attrname : Mapped[Optional[int]] = <meaningless temp node>

    """
    descriptor = api.modules["sqlalchemy.orm.attributes"].names["Mapped"]

    left_node = lvalue.node

    inst = Instance(descriptor.node, [python_type_for_type])

    if left_hand_explicit_type is not None:
        left_node.type = Instance(descriptor.node, [left_hand_explicit_type])
    else:
        lvalue.is_inferred_def = False
        left_node.type = inst

    # so to have it skip the right side totally, we can do this:
    # stmt.rvalue = TempNode(AnyType(TypeOfAny.special_form))

    # however, if we instead manufacture a new node that uses the old
    # one, then we can still get type checking for the call itself,
    # e.g. the Column, relationship() call, etc.

    # rewrite the node as:
    # <attr> : Mapped[<typ>] =
    # _sa_Mapped._empty_constructor(<original CallExpr from rvalue>)
    # the original right-hand side is maintained so it gets type checked
    # internally
    api.add_symbol_table_node("_sa_Mapped", descriptor)
    column_descriptor = nodes.NameExpr("_sa_Mapped")
    column_descriptor.fullname = "sqlalchemy.orm.Mapped"
    mm = nodes.MemberExpr(column_descriptor, "_empty_constructor")
    orig_call_expr = stmt.rvalue
    stmt.rvalue = CallExpr(
        mm,
        [orig_call_expr],
        [nodes.ARG_POS],
        ["arg1"],
    )
Ejemplo n.º 7
0
    def visit_Call(self, n: ast27.Call) -> CallExpr:
        arg_types = []  # type: List[ast27.expr]
        arg_kinds = []  # type: List[int]
        signature = []  # type: List[Optional[str]]

        arg_types.extend(n.args)
        arg_kinds.extend(ARG_POS for a in n.args)
        signature.extend(None for a in n.args)

        if n.starargs is not None:
            arg_types.append(n.starargs)
            arg_kinds.append(ARG_STAR)
            signature.append(None)

        arg_types.extend(k.value for k in n.keywords)
        arg_kinds.extend(ARG_NAMED for k in n.keywords)
        signature.extend(k.arg for k in n.keywords)

        if n.kwargs is not None:
            arg_types.append(n.kwargs)
            arg_kinds.append(ARG_STAR2)
            signature.append(None)

        return CallExpr(self.visit(n.func),
                        self.translate_expr_list(arg_types),
                        arg_kinds,
                        signature)
Ejemplo n.º 8
0
    def visit_call_expr(self, e: CallExpr) -> None:
        if e.analyzed:
            # This is not an ordinary call.
            e.analyzed.accept(self)
            return

        super().visit_call_expr(e)

        # Do no coercions if this is a call to debugging facilities.
        if self.is_debugging_call_expr(e):
            return

        # Get the type of the callable (type variables in the context of the
        # enclosing class).
        ctype = self.get_type(e.callee)

        # Add coercions for the arguments.
        for i in range(len(e.args)):
            arg_type = AnyType()  # type: Type
            if isinstance(ctype, Callable):
                arg_type = ctype.arg_types[i]
            e.args[i] = self.coerce2(e.args[i], arg_type,
                                     self.get_type(e.args[i]),
                                     self.type_context())

        # Prepend type argument values to the call as needed.
        if isinstance(ctype,
                      Callable) and cast(Callable, ctype).bound_vars != []:
            bound_vars = (cast(Callable, ctype)).bound_vars

            # If this is a constructor call (target is the constructor
            # of a generic type or superclass __init__), include also
            # instance type variables.  Otherwise filter them away --
            # include only generic function type variables.
            if (not (cast(Callable, ctype)).is_type_obj()
                    and not (isinstance(e.callee, SuperExpr) and
                             (cast(SuperExpr, e.callee)).name == '__init__')):
                # Filter instance type variables; only include function tvars.
                bound_vars = [(id, t) for id, t in bound_vars if id < 0]

            args = []  # type: List[Node]
            for i in range(len(bound_vars)):
                # Compile type variables to runtime type variable expressions.
                tv = translate_runtime_type_vars_in_context(
                    bound_vars[i][1], self.type_context(), self.is_java)
                args.append(TypeExpr(tv))
            e.args = args + e.args
Ejemplo n.º 9
0
def expr_to_mapped_constructor(expr: Expression) -> CallExpr:
    column_descriptor = NameExpr("__sa_Mapped")
    column_descriptor.fullname = "sqlalchemy.orm.attributes.Mapped"
    member_expr = MemberExpr(column_descriptor, "_empty_constructor")
    return CallExpr(
        member_expr,
        [expr],
        [ARG_POS],
        ["arg1"],
    )
Ejemplo n.º 10
0
def expr_to_mapped_constructor(expr: Expression) -> CallExpr:
    column_descriptor = NameExpr("__sa_Mapped")
    column_descriptor.fullname = NAMED_TYPE_SQLA_MAPPED
    member_expr = MemberExpr(column_descriptor, "_empty_constructor")
    return CallExpr(
        member_expr,
        [expr],
        [ARG_POS],
        ["arg1"],
    )
Ejemplo n.º 11
0
 def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
     arg_count = len(n.values)
     format_string = StrExpr('{}' * arg_count)
     format_string.set_line(n.lineno, n.col_offset)
     format_method = MemberExpr(format_string, 'format')
     format_method.set_line(format_string)
     format_args = self.translate_expr_list(n.values)
     format_arg_kinds = [ARG_POS] * arg_count
     result_expression = CallExpr(format_method, format_args,
                                  format_arg_kinds)
     return result_expression
Ejemplo n.º 12
0
 def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
     # Each of n.values is a str or FormattedValue; we just concatenate
     # them all using ''.join.
     empty_string = StrExpr('')
     empty_string.set_line(n.lineno, n.col_offset)
     strs_to_join = ListExpr(self.translate_expr_list(n.values))
     strs_to_join.set_line(empty_string)
     join_method = MemberExpr(empty_string, 'join')
     join_method.set_line(empty_string)
     result_expression = CallExpr(join_method, [strs_to_join],
                                  [ARG_POS], [None])
     return result_expression
Ejemplo n.º 13
0
 def visit_FormattedValue(self, n: ast3.FormattedValue) -> Expression:
     # A FormattedValue is a component of a JoinedStr, or it can exist
     # on its own. We translate them to individual '{}'.format(value)
     # calls -- we don't bother with the conversion/format_spec fields.
     exp = self.visit(n.value)
     exp.set_line(n.lineno, n.col_offset)
     format_string = StrExpr('{}')
     format_string.set_line(n.lineno, n.col_offset)
     format_method = MemberExpr(format_string, 'format')
     format_method.set_line(format_string)
     result_expression = CallExpr(format_method, [exp], [ARG_POS])
     return result_expression
Ejemplo n.º 14
0
    def visit_Call(self, n: ast35.Call) -> Node:
        def is_star2arg(k):
            return k.arg is None

        arg_types = self.visit_list(
            [a.value if isinstance(a, ast35.Starred) else a for a in n.args] +
            [k.value for k in n.keywords])
        arg_kinds = ([ARG_STAR if isinstance(a, ast35.Starred) else ARG_POS for a in n.args] +
                     [ARG_STAR2 if is_star2arg(k) else ARG_NAMED for k in n.keywords])
        return CallExpr(self.visit(n.func),
                        arg_types,
                        arg_kinds,
                        cast("List[str]", [None for _ in n.args]) + [k.arg for k in n.keywords])
Ejemplo n.º 15
0
    def visit_Call(self, n: ast3.Call) -> CallExpr:
        def is_star2arg(k: ast3.keyword) -> bool:
            return k.arg is None

        arg_types = self.translate_expr_list(
            [a.value if isinstance(a, ast3.Starred) else a for a in n.args] +
            [k.value for k in n.keywords])
        arg_kinds = ([ARG_STAR if isinstance(a, ast3.Starred) else ARG_POS for a in n.args] +
                     [ARG_STAR2 if is_star2arg(k) else ARG_NAMED for k in n.keywords])
        return CallExpr(self.visit(n.func),
                        arg_types,
                        arg_kinds,
                        cast("List[str]", [None] * len(n.args)) + [k.arg for k in n.keywords])
Ejemplo n.º 16
0
def _check_str_format_call(
    log_msg_expr: t.Union[StrExpr, NameExpr],
    ctx: MethodContext,
) -> None:
    """ Taps into mypy to typecheck something like this:

        ```py
        logger.debug('The bar is "{my_foo.bar}"', my_foo=foo)
        ```

        as if it was written like this:

        ```py
        logger.debug('The bar is "{my_foo.bar}"'.format(my_foo=foo))
        ```
    """
    call_expr = CallExpr(
        callee=MemberExpr(expr=log_msg_expr, name='format'),
        args=ctx.args[1] + ctx.args[2],
        arg_kinds=ctx.arg_kinds[1] + ctx.arg_kinds[2],
        arg_names=ctx.arg_names[1] + ctx.arg_names[2],
    )
    call_expr.set_line(log_msg_expr)

    # WARNING: `ctx.api` *is* technically a `mypy.checker.TypeChecker` so the cast is
    # safe to make, however, mypy says this should be an implementation detail.
    # So, anything that's not part of the `CheckerPluginInterface` should be expected to
    # change. See https://github.com/python/mypy/issues/6617
    try:
        type_checker = t.cast(TypeChecker, ctx.api)
        type_checker.expr_checker.visit_call_expr(call_expr)
    except AttributeError:
        ctx.api.msg.fail(
            ("AttributeError when trying to access mypy's functionality. "
             'This could mean you are trying to use incompatible versions '
             'of mypy and loguru-mypy.'),
            context=log_msg_expr,
        )
Ejemplo n.º 17
0
 def visit_Call(self, n: Call) -> CallExpr:
     args = n.args
     keywords = n.keywords
     keyword_names = [k.arg for k in keywords]
     arg_types = self.translate_expr_list(
         [a.value if isinstance(a, Starred) else a
          for a in args] + [k.value for k in keywords])
     arg_kinds = (
         [ARG_STAR if type(a) is Starred else ARG_POS for a in args] +
         [ARG_STAR2 if arg is None else ARG_NAMED for arg in keyword_names])
     e = CallExpr(
         self.visit(n.func), arg_types, arg_kinds,
         cast('List[Optional[str]]', [None] * len(args)) + keyword_names)
     return self.set_line(e, n)
Ejemplo n.º 18
0
    def make_generic_wrapper_init(self, info: TypeInfo) -> FuncDef:
        """Build constructor of a generic wrapper class."""
        nslots = num_slots(info)
        
        cdefs = [] # type: List[Node]
        
        # Build superclass constructor call.
        base = info.mro[1]
        if base.fullname() != 'builtins.object' and self.tf.is_java:
            s = SuperExpr('__init__')
            cargs = [NameExpr('__o')] # type: List[Node]
            for n in range(num_slots(base)):
                cargs.append(NameExpr(tvar_arg_name(n + 1)))
            for n in range(num_slots(base)):
                cargs.append(NameExpr(tvar_arg_name(n + 1, BOUND_VAR)))
            c = CallExpr(s, cargs, [nodes.ARG_POS] * len(cargs))
            cdefs.append(ExpressionStmt(c))
        
        # Create initialization of the wrapped object.
        cdefs.append(AssignmentStmt([MemberExpr(
                                         self_expr(),
                                         self.object_member_name(info),
                                         direct=True)],
                                    NameExpr('__o')))
        
        # Build constructor arguments.
        args = [Var('self'), Var('__o')]
        init = [None, None] # type: List[Node]
        
        for alt in [False, BOUND_VAR]:
            for n in range(nslots):
                args.append(Var(tvar_arg_name(n + 1, alt)))
                init.append(None)

        nargs = nslots * 2 + 2
        fdef = FuncDef('__init__',
                       args,
                       [nodes.ARG_POS] * nargs,
                       init,
                       Block(cdefs),
                       Callable( [AnyType()] * nargs,
                                [nodes.ARG_POS] * nargs, [None] * nargs,
                                Void(),
                                is_type_obj=False))
        fdef.info = info
        
        self.make_wrapper_slot_initializer(fdef)
        
        return fdef
Ejemplo n.º 19
0
    def visit_Call(self, n):
        def is_stararg(a):
            return isinstance(a, typed_ast.Starred)

        def is_star2arg(k):
            return k.arg is None

        arg_types = self.visit(
            [a.value if is_stararg(a) else a
             for a in n.args] + [k.value for k in n.keywords])
        arg_kinds = (
            [ARG_STAR if is_stararg(a) else ARG_POS for a in n.args] +
            [ARG_STAR2 if is_star2arg(k) else ARG_NAMED for k in n.keywords])
        return CallExpr(self.visit(n.func), arg_types, arg_kinds,
                        [None for _ in n.args] + [k.arg for k in n.keywords])
Ejemplo n.º 20
0
    def call_wrapper(self, fdef: FuncDef, is_dynamic: bool,
                     is_wrapper_class: bool, target_ann: Callable,
                     cur_ann: Callable, target_suffix: str,
                     bound_sig: Callable) -> Node:
        """Return the body of wrapper method.

        The body contains only a call to the wrapped method and a
        return statement (if the call returns a value). Arguments are coerced
        to the target signature.
        """
        args = self.call_args(fdef.args,
                              target_ann,
                              cur_ann,
                              is_dynamic,
                              is_wrapper_class,
                              bound_sig,
                              ismethod=fdef.is_method())
        selfarg = args[0]
        args = args[1:]

        member = fdef.name() + target_suffix
        if not is_wrapper_class:
            callee = MemberExpr(selfarg, member)
        else:
            callee = MemberExpr(
                MemberExpr(self_expr(), self.tf.object_member_name()), member)

        call = CallExpr(callee, args, [nodes.ARG_POS] * len(args),
                        [None] * len(args))  # type: Node
        if bound_sig:
            call = self.tf.coerce(call,
                                  bound_sig.ret_type, target_ann.ret_type,
                                  self.tf.type_context(), is_wrapper_class)
            call = self.tf.coerce(call, cur_ann.ret_type, bound_sig.ret_type,
                                  self.tf.type_context(), is_wrapper_class)
        else:
            call = self.tf.coerce(call, cur_ann.ret_type, target_ann.ret_type,
                                  self.tf.type_context(), is_wrapper_class)
        if not isinstance(target_ann.ret_type, Void):
            return ReturnStmt(call)
        else:
            return ExpressionStmt(call)
Ejemplo n.º 21
0
    def make_type_object_wrapper(self, tdef: ClassDef) -> FuncDef:
        """Construct dynamically typed wrapper function for a class.

        It simple calls the type object and returns the result.
        """
        
        # TODO keyword args, default args and varargs
        # TODO overloads

        type_sig = cast(Callable, type_object_type(tdef.info, None))
        type_sig = cast(Callable, erasetype.erase_typevars(type_sig))
        
        init = cast(FuncDef, tdef.info.get_method('__init__'))
        arg_kinds = type_sig.arg_kinds

        # The wrapper function has a dynamically typed signature.
        wrapper_sig = Callable( [AnyType()] * len(arg_kinds),
                               arg_kinds, [None] * len(arg_kinds),
                               AnyType(), False)
        
        n = NameExpr(tdef.name) # TODO full name
        args = self.func_tf.call_args(
            init.args[1:],
            type_sig,
            wrapper_sig,
            True, False)
        call = CallExpr(n, args, arg_kinds)
        ret = ReturnStmt(call)
        

        fdef = FuncDef(tdef.name + self.tf.dynamic_suffix(),
                       init.args[1:],
                       arg_kinds, [None] * len(arg_kinds),
                       Block([ret]))
        
        fdef.type = wrapper_sig
        return fdef
Ejemplo n.º 22
0
 def visit_call_expr(self, node: CallExpr) -> None:
     super().visit_call_expr(node)
     if isinstance(node.analyzed, SymbolNode):
         node.analyzed = self.fixup(node.analyzed)
Ejemplo n.º 23
0
 def store_namedtuple_info(self, info: TypeInfo, name: str,
                           call: CallExpr, is_typed: bool) -> None:
     self.api.add_symbol(name, info, call)
     call.analyzed = NamedTupleExpr(info, is_typed=is_typed)
     call.analyzed.set_line(call.line, call.column)
Ejemplo n.º 24
0
def _scan_declarative_decorator_stmt(
    cls: ClassDef,
    api: SemanticAnalyzerPluginInterface,
    stmt: Decorator,
    cls_metadata: util.DeclClassApplied,
) -> None:
    """Extract mapping information from a @declared_attr in a declarative
    class.

    E.g.::

        @reg.mapped
        class MyClass:
            # ...

            @declared_attr
            def updated_at(cls) -> Column[DateTime]:
                return Column(DateTime)

    Will resolve in mypy as::

        @reg.mapped
        class MyClass:
            # ...

            updated_at: Mapped[Optional[datetime.datetime]]

    """
    for dec in stmt.decorators:
        if (
            isinstance(dec, (NameExpr, MemberExpr, SymbolNode))
            and names._type_id_for_named_node(dec) is names.DECLARED_ATTR
        ):
            break
    else:
        return

    dec_index = cls.defs.body.index(stmt)

    left_hand_explicit_type: Optional[ProperType] = None

    if isinstance(stmt.func.type, CallableType):
        func_type = stmt.func.type.ret_type
        if isinstance(func_type, UnboundType):
            type_id = names._type_id_for_unbound_type(func_type, cls, api)
        else:
            # this does not seem to occur unless the type argument is
            # incorrect
            return

        if (
            type_id
            in {
                names.MAPPED,
                names.RELATIONSHIP,
                names.COMPOSITE_PROPERTY,
                names.MAPPER_PROPERTY,
                names.SYNONYM_PROPERTY,
                names.COLUMN_PROPERTY,
            }
            and func_type.args
        ):
            left_hand_explicit_type = get_proper_type(func_type.args[0])
        elif type_id is names.COLUMN and func_type.args:
            typeengine_arg = func_type.args[0]
            if isinstance(typeengine_arg, UnboundType):
                sym = api.lookup_qualified(typeengine_arg.name, typeengine_arg)
                if sym is not None and isinstance(sym.node, TypeInfo):
                    if names._has_base_type_id(sym.node, names.TYPEENGINE):
                        left_hand_explicit_type = UnionType(
                            [
                                infer._extract_python_type_from_typeengine(
                                    api, sym.node, []
                                ),
                                NoneType(),
                            ]
                        )
                    else:
                        util.fail(
                            api,
                            "Column type should be a TypeEngine "
                            "subclass not '{}'".format(sym.node.fullname),
                            func_type,
                        )

    if left_hand_explicit_type is None:
        # no type on the decorated function.  our option here is to
        # dig into the function body and get the return type, but they
        # should just have an annotation.
        msg = (
            "Can't infer type from @declared_attr on function '{}';  "
            "please specify a return type from this function that is "
            "one of: Mapped[<python type>], relationship[<target class>], "
            "Column[<TypeEngine>], MapperProperty[<python type>]"
        )
        util.fail(api, msg.format(stmt.var.name), stmt)

        left_hand_explicit_type = AnyType(TypeOfAny.special_form)

    left_node = NameExpr(stmt.var.name)
    left_node.node = stmt.var

    # totally feeling around in the dark here as I don't totally understand
    # the significance of UnboundType.  It seems to be something that is
    # not going to do what's expected when it is applied as the type of
    # an AssignmentStatement.  So do a feeling-around-in-the-dark version
    # of converting it to the regular Instance/TypeInfo/UnionType structures
    # we see everywhere else.
    if isinstance(left_hand_explicit_type, UnboundType):
        left_hand_explicit_type = get_proper_type(
            util._unbound_to_instance(api, left_hand_explicit_type)
        )

    left_node.node.type = api.named_type(
        "__sa_Mapped", [left_hand_explicit_type]
    )

    # this will ignore the rvalue entirely
    # rvalue = TempNode(AnyType(TypeOfAny.special_form))

    # rewrite the node as:
    # <attr> : Mapped[<typ>] =
    # _sa_Mapped._empty_constructor(lambda: <function body>)
    # the function body is maintained so it gets type checked internally
    column_descriptor = nodes.NameExpr("__sa_Mapped")
    column_descriptor.fullname = "sqlalchemy.orm.attributes.Mapped"
    mm = nodes.MemberExpr(column_descriptor, "_empty_constructor")

    arg = nodes.LambdaExpr(stmt.func.arguments, stmt.func.body)
    rvalue = CallExpr(
        mm,
        [arg],
        [nodes.ARG_POS],
        ["arg1"],
    )

    new_stmt = AssignmentStmt([left_node], rvalue)
    new_stmt.type = left_node.node.type

    cls_metadata.mapped_attr_names.append(
        (left_node.name, left_hand_explicit_type)
    )
    cls.defs.body[dec_index] = new_stmt
Ejemplo n.º 25
0
 def visit_call_expr(self, node: CallExpr) -> Node:
     return CallExpr(self.node(node.callee), self.nodes(node.args),
                     node.arg_kinds[:], node.arg_names[:],
                     self.optional_node(node.analyzed))
Ejemplo n.º 26
0
 def visit_call_expr(self, node: CallExpr) -> None:
     node.analyzed = None
     super().visit_call_expr(node)
Ejemplo n.º 27
0
 def visit_call_expr(self, node: CallExpr) -> None:
     node.analyzed = None
     super().visit_call_expr(node)
Ejemplo n.º 28
0
 def store_namedtuple_info(self, info: TypeInfo, name: str,
                           call: CallExpr, is_typed: bool) -> None:
     stnode = SymbolTableNode(GDEF, info)
     self.api.add_symbol_table_node(name, stnode)
     call.analyzed = NamedTupleExpr(info, is_typed=is_typed)
     call.analyzed.set_line(call.line, call.column)
Ejemplo n.º 29
0
 def visit_call_expr(self, node: CallExpr) -> CallExpr:
     return CallExpr(self.expr(node.callee),
                     self.expressions(node.args),
                     node.arg_kinds[:],
                     node.arg_names[:],
                     self.optional_expr(node.analyzed))
Ejemplo n.º 30
0
 def visit_call_expr(self, node: CallExpr) -> None:
     super().visit_call_expr(node)
     if isinstance(node.analyzed, SymbolNode):
         node.analyzed = self.fixup(node.analyzed)
Ejemplo n.º 31
0
 def store_namedtuple_info(self, info: TypeInfo, name: str,
                           call: CallExpr, is_typed: bool) -> None:
     self.api.add_symbol(name, info, call)
     call.analyzed = NamedTupleExpr(info, is_typed=is_typed)
     call.analyzed.set_line(call.line, call.column)
Ejemplo n.º 32
0
 def store_namedtuple_info(self, info: TypeInfo, name: str,
                           call: CallExpr, is_typed: bool) -> None:
     stnode = SymbolTableNode(GDEF, info)
     self.api.add_symbol_table_node(name, stnode)
     call.analyzed = NamedTupleExpr(info, is_typed=is_typed)
     call.analyzed.set_line(call.line, call.column)