API refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-07 16:25:52 +09:00
parent 76d0d86211
commit 91c7e04474
1171 changed files with 81940 additions and 44117 deletions

View File

@@ -0,0 +1,6 @@
# ext/mypy/__init__.py
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php

View File

@@ -1,5 +1,5 @@
# ext/mypy/apply.py
# Copyright (C) 2021 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -161,9 +161,9 @@ def re_apply_declarative_assignments(
# update the SQLAlchemyAttribute with the better
# information
mapped_attr_lookup[
stmt.lvalues[0].name
].type = python_type_for_type
mapped_attr_lookup[stmt.lvalues[0].name].type = (
python_type_for_type
)
update_cls_metadata = True
@@ -199,11 +199,15 @@ def apply_type_to_mapped_statement(
To one that describes the final Python behavior to Mypy::
... format: off
class User(Base):
# ...
attrname : Mapped[Optional[int]] = <meaningless temp node>
... format: on
"""
left_node = lvalue.node
assert isinstance(left_node, Var)
@@ -223,9 +227,11 @@ def apply_type_to_mapped_statement(
lvalue.is_inferred_def = False
left_node.type = api.named_type(
NAMED_TYPE_SQLA_MAPPED,
[AnyType(TypeOfAny.special_form)]
if python_type_for_type is None
else [python_type_for_type],
(
[AnyType(TypeOfAny.special_form)]
if python_type_for_type is None
else [python_type_for_type]
),
)
# so to have it skip the right side totally, we can do this:

View File

@@ -1,5 +1,5 @@
# ext/mypy/decl_class.py
# Copyright (C) 2021 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -58,9 +58,9 @@ def scan_declarative_assignments_and_apply_types(
elif cls.fullname.startswith("builtins"):
return None
mapped_attributes: Optional[
List[util.SQLAlchemyAttribute]
] = util.get_mapped_attributes(info, api)
mapped_attributes: Optional[List[util.SQLAlchemyAttribute]] = (
util.get_mapped_attributes(info, api)
)
# used by assign.add_additional_orm_attributes among others
util.establish_as_sqlalchemy(info)

View File

@@ -1,5 +1,5 @@
# ext/mypy/infer.py
# Copyright (C) 2021 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -385,9 +385,9 @@ def _infer_type_from_decl_column(
class MyClass:
# ...
a : Mapped[int]
a: Mapped[int]
b : Mapped[str]
b: Mapped[str]
c: Mapped[int]

View File

@@ -1,5 +1,5 @@
# ext/mypy/names.py
# Copyright (C) 2021 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -58,6 +58,14 @@ NAMED_TYPE_BUILTINS_STR = "builtins.str"
NAMED_TYPE_BUILTINS_LIST = "builtins.list"
NAMED_TYPE_SQLA_MAPPED = "sqlalchemy.orm.base.Mapped"
_RelFullNames = {
"sqlalchemy.orm.relationships.Relationship",
"sqlalchemy.orm.relationships.RelationshipProperty",
"sqlalchemy.orm.relationships._RelationshipDeclared",
"sqlalchemy.orm.Relationship",
"sqlalchemy.orm.RelationshipProperty",
}
_lookup: Dict[str, Tuple[int, Set[str]]] = {
"Column": (
COLUMN,
@@ -66,24 +74,9 @@ _lookup: Dict[str, Tuple[int, Set[str]]] = {
"sqlalchemy.sql.Column",
},
),
"Relationship": (
RELATIONSHIP,
{
"sqlalchemy.orm.relationships.Relationship",
"sqlalchemy.orm.relationships.RelationshipProperty",
"sqlalchemy.orm.Relationship",
"sqlalchemy.orm.RelationshipProperty",
},
),
"RelationshipProperty": (
RELATIONSHIP,
{
"sqlalchemy.orm.relationships.Relationship",
"sqlalchemy.orm.relationships.RelationshipProperty",
"sqlalchemy.orm.Relationship",
"sqlalchemy.orm.RelationshipProperty",
},
),
"Relationship": (RELATIONSHIP, _RelFullNames),
"RelationshipProperty": (RELATIONSHIP, _RelFullNames),
"_RelationshipDeclared": (RELATIONSHIP, _RelFullNames),
"registry": (
REGISTRY,
{
@@ -304,7 +297,7 @@ def type_id_for_callee(callee: Expression) -> Optional[int]:
def type_id_for_named_node(
node: Union[NameExpr, MemberExpr, SymbolNode]
node: Union[NameExpr, MemberExpr, SymbolNode],
) -> Optional[int]:
type_id, fullnames = _lookup.get(node.name, (None, None))

View File

@@ -1,5 +1,5 @@
# ext/mypy/plugin.py
# Copyright (C) 2021-2023 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under

View File

@@ -1,5 +1,5 @@
# ext/mypy/util.py
# Copyright (C) 2021-2023 the SQLAlchemy authors and contributors
# Copyright (C) 2021-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -80,7 +80,7 @@ class SQLAlchemyAttribute:
"name": self.name,
"line": self.line,
"column": self.column,
"type": self.type.serialize(),
"type": serialize_type(self.type),
}
def expand_typevar_from_subtype(self, sub_type: TypeInfo) -> None:
@@ -212,8 +212,7 @@ def add_global(
@overload
def get_callexpr_kwarg(
callexpr: CallExpr, name: str, *, expr_types: None = ...
) -> Optional[Union[CallExpr, NameExpr]]:
...
) -> Optional[Union[CallExpr, NameExpr]]: ...
@overload
@@ -222,8 +221,7 @@ def get_callexpr_kwarg(
name: str,
*,
expr_types: Tuple[TypingType[_TArgType], ...],
) -> Optional[_TArgType]:
...
) -> Optional[_TArgType]: ...
def get_callexpr_kwarg(
@@ -315,9 +313,11 @@ def unbound_to_instance(
return Instance(
bound_type,
[
unbound_to_instance(api, arg)
if isinstance(arg, UnboundType)
else arg
(
unbound_to_instance(api, arg)
if isinstance(arg, UnboundType)
else arg
)
for arg in typ.args
],
)
@@ -336,3 +336,22 @@ def info_for_cls(
return sym.node
return cls.info
def serialize_type(typ: Type) -> Union[str, JsonDict]:
try:
return typ.serialize()
except Exception:
pass
if hasattr(typ, "args"):
typ.args = tuple(
(
a.resolve_string_annotation()
if hasattr(a, "resolve_string_annotation")
else a
)
for a in typ.args
)
elif hasattr(typ, "resolve_string_annotation"):
typ = typ.resolve_string_annotation()
return typ.serialize()