Fixed mypy regression where the release of mypy 0.930 added additional
internal checks to the format of "named types", requiring that they be
fully qualified and locatable. This broke the mypy plugin for SQLAlchemy,
raising an assertion error, as there was use of symbols such as
``__builtins__`` and other un-locatable or unqualified names that
previously had not raised any assertions.
Fixes: #7496
Change-Id: I037680606a1d51158ef6503508ec76c5d5adc946
(cherry picked from commit
aded8b11d9eccbd1f2b645a94338e34a3d234bc9)
--- /dev/null
+.. change::
+ :tags: bug, mypy
+ :tickets: 7496
+
+ Fixed mypy regression where the release of mypy 0.930 added additional
+ internal checks to the format of "named types", requiring that they be
+ fully qualified and locatable. This broke the mypy plugin for SQLAlchemy,
+ raising an assertion error, as there was use of symbols such as
+ ``__builtins__`` and other un-locatable or unqualified names that
+ previously had not raised any assertions.
+
from . import infer
from . import util
+from .names import NAMED_TYPE_SQLA_MAPPED
def apply_mypy_mapped_attr(
and isinstance(stmt.rvalue.callee.expr, NameExpr)
and stmt.rvalue.callee.expr.node is not None
and stmt.rvalue.callee.expr.node.fullname
- == "sqlalchemy.orm.attributes.Mapped"
+ == NAMED_TYPE_SQLA_MAPPED
and stmt.rvalue.callee.name == "_empty_constructor"
and isinstance(stmt.rvalue.args[0], CallExpr)
and isinstance(stmt.rvalue.args[0].callee, RefExpr)
if python_type_for_type is not None:
left_node.type = api.named_type(
- "__sa_Mapped", [python_type_for_type]
+ NAMED_TYPE_SQLA_MAPPED, [python_type_for_type]
)
if update_cls_metadata:
if left_hand_explicit_type is not None:
left_node.type = api.named_type(
- "__sa_Mapped", [left_hand_explicit_type]
+ NAMED_TYPE_SQLA_MAPPED, [left_hand_explicit_type]
)
else:
lvalue.is_inferred_def = False
left_node.type = api.named_type(
- "__sa_Mapped",
+ NAMED_TYPE_SQLA_MAPPED,
[] if python_type_for_type is None else [python_type_for_type],
)
)
left_node.node.type = api.named_type(
- "__sa_Mapped", [left_hand_explicit_type]
+ names.NAMED_TYPE_SQLA_MAPPED, [left_hand_explicit_type]
)
# this will ignore the rvalue entirely
type_is_a_collection = True
if python_type_for_type is not None:
python_type_for_type = api.named_type(
- "__builtins__.list", [python_type_for_type]
+ names.NAMED_TYPE_BUILTINS_LIST, [python_type_for_type]
)
elif (
uselist_arg is None or api.parse_bool(uselist_arg) is True
if not is_subtype(left_hand_explicit_type, python_type_for_type):
effective_type = api.named_type(
- "__sa_Mapped", [orig_python_type_for_type]
+ names.NAMED_TYPE_SQLA_MAPPED, [orig_python_type_for_type]
)
msg = (
)
util.fail(api, msg.format(node.name), node)
- return api.named_type("__sa_Mapped", [AnyType(TypeOfAny.special_form)])
+ return api.named_type(
+ names.NAMED_TYPE_SQLA_MAPPED, [AnyType(TypeOfAny.special_form)]
+ )
else:
# use type from the left hand side
return Instance(first_arg.node, [])
# TODO: support other pep-435 types here
else:
- return api.named_type("__builtins__.str", [])
+ return api.named_type(names.NAMED_TYPE_BUILTINS_STR, [])
assert node.has_base("sqlalchemy.sql.type_api.TypeEngine"), (
"could not extract Python type from node: %s" % node
DECLARATIVE_MIXIN: int = util.symbol("DECLARATIVE_MIXIN") # type: ignore
QUERY_EXPRESSION: int = util.symbol("QUERY_EXPRESSION") # type: ignore
+# names that must succeed with mypy.api.named_type
+NAMED_TYPE_BUILTINS_OBJECT = "builtins.object"
+NAMED_TYPE_BUILTINS_STR = "builtins.str"
+NAMED_TYPE_BUILTINS_LIST = "builtins.list"
+NAMED_TYPE_SQLA_MAPPED = "sqlalchemy.orm.attributes.Mapped"
+
_lookup: Dict[str, Tuple[int, Set[str]]] = {
"Column": (
COLUMN,
)
info.bases = [Instance(cls_arg.node, [])]
else:
- obj = ctx.api.named_type("__builtins__.object")
+ obj = ctx.api.named_type(names.NAMED_TYPE_BUILTINS_OBJECT)
info.bases = [obj]
util.fail(
ctx.api, "Not able to calculate MRO for declarative base", ctx.call
)
- obj = ctx.api.named_type("__builtins__.object")
+ obj = ctx.api.named_type(names.NAMED_TYPE_BUILTINS_OBJECT)
info.bases = [obj]
info.fallback_to_any = True