Improve SQLAlchemy type aliases (#8252)

* Remove `sqlalchemy.dbapi` (in favor of `_typeshed.dbapi`).
* Don't re-export mypy imports from `sqlalchemy.ext.mypy.*`.
This commit is contained in:
Alex Waygood
2022-07-07 13:11:08 +01:00
committed by GitHub
parent 42c5633bf6
commit 850bc78a45
10 changed files with 94 additions and 134 deletions

View File

@@ -1,6 +1,3 @@
# stub-only module
sqlalchemy.dbapi
# wrong argument name in implementation ("self" instead of "cls")
sqlalchemy.engine.URL.__new__
sqlalchemy.engine.url.URL.__new__

View File

@@ -1,37 +0,0 @@
# TODO: Tempory copy of _typeshed.dbapi, until that file is available in all typecheckers.
# Does not exist at runtime.
from collections.abc import Mapping, Sequence
from typing import Any, Protocol
from typing_extensions import TypeAlias
DBAPITypeCode: TypeAlias = Any | None
# Strictly speaking, this should be a Sequence, but the type system does
# not support fixed-length sequences.
DBAPIColumnDescription: TypeAlias = tuple[str, DBAPITypeCode, int | None, int | None, int | None, int | None, bool | None]
class DBAPIConnection(Protocol):
def close(self) -> object: ...
def commit(self) -> object: ...
# optional:
# def rollback(self) -> Any: ...
def cursor(self) -> DBAPICursor: ...
class DBAPICursor(Protocol):
@property
def description(self) -> Sequence[DBAPIColumnDescription] | None: ...
@property
def rowcount(self) -> int: ...
# optional:
# def callproc(self, __procname: str, __parameters: Sequence[Any] = ...) -> Sequence[Any]: ...
def close(self) -> object: ...
def execute(self, __operation: str, __parameters: Sequence[Any] | Mapping[str, Any] = ...) -> object: ...
def executemany(self, __operation: str, __seq_of_parameters: Sequence[Sequence[Any]]) -> object: ...
def fetchone(self) -> Sequence[Any] | None: ...
def fetchmany(self, __size: int = ...) -> Sequence[Sequence[Any]]: ...
def fetchall(self) -> Sequence[Sequence[Any]]: ...
# optional:
# def nextset(self) -> None | Literal[True]: ...
arraysize: int
def setinputsizes(self, __sizes: Sequence[DBAPITypeCode | int | None]) -> object: ...
def setoutputsize(self, __size: int, __column: int = ...) -> object: ...

View File

@@ -1,11 +1,11 @@
from _typeshed import Self
from _typeshed.dbapi import DBAPIConnection
from abc import abstractmethod
from collections.abc import Callable, Mapping
from types import TracebackType
from typing import Any, TypeVar, overload
from typing_extensions import TypeAlias
from ..dbapi import DBAPIConnection
from ..log import Identified, _EchoFlag, echo_property
from ..pool import Pool
from ..sql.compiler import Compiled

View File

@@ -1,8 +1,8 @@
from _typeshed.dbapi import DBAPIConnection, DBAPICursor
from abc import abstractmethod
from collections.abc import Callable, Collection, Mapping
from typing import Any, ClassVar, overload
from ..dbapi import DBAPIConnection, DBAPICursor
from ..exc import StatementError
from ..sql.compiler import Compiled as Compiled, IdentifierPreparer, TypeCompiler as TypeCompiler
from ..sql.ddl import DDLElement

View File

@@ -3,25 +3,25 @@ from typing_extensions import TypeAlias
from . import util
AssignmentStmt: TypeAlias = Any # from mypy.nodes
NameExpr: TypeAlias = Any # from mypy.nodes
StrExpr: TypeAlias = Any # from mypy.nodes
SemanticAnalyzerPluginInterface: TypeAlias = Any # from mypy.plugin
ProperType: TypeAlias = Any # from mypy.types
_AssignmentStmt: TypeAlias = Any # mypy.nodes.AssignmentStmt
_NameExpr: TypeAlias = Any # mypy.nodes.NameExpr
_StrExpr: TypeAlias = Any # mypy.nodes.StrExpr
_SemanticAnalyzerPluginInterface: TypeAlias = Any # mypy.plugin.SemanticAnalyzerPluginInterface
_ProperType: TypeAlias = Any # mypy.types.ProperType
def apply_mypy_mapped_attr(
cls, api: SemanticAnalyzerPluginInterface, item: NameExpr | StrExpr, attributes: list[util.SQLAlchemyAttribute]
cls, api: _SemanticAnalyzerPluginInterface, item: _NameExpr | _StrExpr, attributes: list[util.SQLAlchemyAttribute]
) -> None: ...
def re_apply_declarative_assignments(
cls, api: SemanticAnalyzerPluginInterface, attributes: list[util.SQLAlchemyAttribute]
cls, api: _SemanticAnalyzerPluginInterface, attributes: list[util.SQLAlchemyAttribute]
) -> None: ...
def apply_type_to_mapped_statement(
api: SemanticAnalyzerPluginInterface,
stmt: AssignmentStmt,
lvalue: NameExpr,
left_hand_explicit_type: ProperType | None,
python_type_for_type: ProperType | None,
api: _SemanticAnalyzerPluginInterface,
stmt: _AssignmentStmt,
lvalue: _NameExpr,
left_hand_explicit_type: _ProperType | None,
python_type_for_type: _ProperType | None,
) -> None: ...
def add_additional_orm_attributes(
cls, api: SemanticAnalyzerPluginInterface, attributes: list[util.SQLAlchemyAttribute]
cls, api: _SemanticAnalyzerPluginInterface, attributes: list[util.SQLAlchemyAttribute]
) -> None: ...

View File

@@ -3,8 +3,8 @@ from typing_extensions import TypeAlias
from . import util
SemanticAnalyzerPluginInterface: TypeAlias = Any # from mypy.plugin
_SemanticAnalyzerPluginInterface: TypeAlias = Any # mypy.plugin.SemanticAnalyzerPluginInterface
def scan_declarative_assignments_and_apply_types(
cls, api: SemanticAnalyzerPluginInterface, is_mixin_scan: bool = ...
cls, api: _SemanticAnalyzerPluginInterface, is_mixin_scan: bool = ...
) -> list[util.SQLAlchemyAttribute] | None: ...

View File

@@ -2,25 +2,25 @@ from collections.abc import Sequence
from typing import Any
from typing_extensions import TypeAlias
AssignmentStmt: TypeAlias = Any # from mypy.nodes
Expression: TypeAlias = Any # from mypy.nodes
RefExpr: TypeAlias = Any # from mypy.nodes
TypeInfo: TypeAlias = Any # from mypy.nodes
Var: TypeAlias = Any # from mypy.nodes
StrExpr: TypeAlias = Any # from mypy.nodes
SemanticAnalyzerPluginInterface: TypeAlias = Any # from mypy.plugin
ProperType: TypeAlias = Any # from mypy.types
_AssignmentStmt: TypeAlias = Any # mypy.nodes.AssignmentStmt
_Expression: TypeAlias = Any # mypy.nodes.Expression
_RefExpr: TypeAlias = Any # mypy.nodes.RefExpr
_TypeInfo: TypeAlias = Any # mypy.nodes.TypeInfo
_Var: TypeAlias = Any # mypy.nodes.Var
_StrExpr: TypeAlias = Any # mypy.nodes.StrExpr
_SemanticAnalyzerPluginInterface: TypeAlias = Any # mypy.plugin.SemanticAnalyzerPluginInterface
_ProperType: TypeAlias = Any # mypy.types.ProperType
def infer_type_from_right_hand_nameexpr(
api: SemanticAnalyzerPluginInterface,
stmt: AssignmentStmt,
node: Var,
left_hand_explicit_type: ProperType | None,
infer_from_right_side: RefExpr,
) -> ProperType | None: ...
api: _SemanticAnalyzerPluginInterface,
stmt: _AssignmentStmt,
node: _Var,
left_hand_explicit_type: _ProperType | None,
infer_from_right_side: _RefExpr,
) -> _ProperType | None: ...
def infer_type_from_left_hand_type_only(
api: SemanticAnalyzerPluginInterface, node: Var, left_hand_explicit_type: ProperType | None
) -> ProperType | None: ...
api: _SemanticAnalyzerPluginInterface, node: _Var, left_hand_explicit_type: _ProperType | None
) -> _ProperType | None: ...
def extract_python_type_from_typeengine(
api: SemanticAnalyzerPluginInterface, node: TypeInfo, type_args: Sequence[Expression]
) -> ProperType: ...
api: _SemanticAnalyzerPluginInterface, node: _TypeInfo, type_args: Sequence[_Expression]
) -> _ProperType: ...

View File

@@ -3,14 +3,14 @@ from typing_extensions import TypeAlias
from ...util import symbol
ClassDef: TypeAlias = Any # from mypy.nodes
Expression: TypeAlias = Any # from mypy.nodes
MemberExpr: TypeAlias = Any # from mypy.nodes
NameExpr: TypeAlias = Any # from mypy.nodes
SymbolNode: TypeAlias = Any # from mypy.nodes
TypeInfo: TypeAlias = Any # from mypy.nodes
SemanticAnalyzerPluginInterface: TypeAlias = Any # from mypy.plugin
UnboundType: TypeAlias = Any # from mypy.types
_ClassDef: TypeAlias = Any # mypy.nodes.ClassDef
_Expression: TypeAlias = Any # mypy.nodes.Expression
_MemberExpr: TypeAlias = Any # mypy.nodes.MemberExpr
_NameExpr: TypeAlias = Any # mypy.nodes.NameExpr
_SymbolNode: TypeAlias = Any # mypy.nodes.SymbolNode
_TypeInfo: TypeAlias = Any # mypy.nodes.TypeInfo
_SemanticAnalyzerPluginInterface: TypeAlias = Any # mypy.plugin.SemanticAnalyzerPluginInterface
_UnboundType: TypeAlias = Any # mypy.types.UnboundType
COLUMN: symbol
RELATIONSHIP: symbol
@@ -30,9 +30,9 @@ AS_DECLARATIVE_BASE: symbol
DECLARATIVE_MIXIN: symbol
QUERY_EXPRESSION: symbol
def has_base_type_id(info: TypeInfo, type_id: int) -> bool: ...
def mro_has_id(mro: list[TypeInfo], type_id: int) -> bool: ...
def type_id_for_unbound_type(type_: UnboundType, cls: ClassDef, api: SemanticAnalyzerPluginInterface) -> int | None: ...
def type_id_for_callee(callee: Expression) -> int | None: ...
def type_id_for_named_node(node: NameExpr | MemberExpr | SymbolNode) -> int | None: ...
def has_base_type_id(info: _TypeInfo, type_id: int) -> bool: ...
def mro_has_id(mro: list[_TypeInfo], type_id: int) -> bool: ...
def type_id_for_unbound_type(type_: _UnboundType, cls: _ClassDef, api: _SemanticAnalyzerPluginInterface) -> int | None: ...
def type_id_for_callee(callee: _Expression) -> int | None: ...
def type_id_for_named_node(node: _NameExpr | _MemberExpr | _SymbolNode) -> int | None: ...
def type_id_for_fullname(fullname: str) -> int | None: ...

View File

@@ -2,20 +2,20 @@ from collections.abc import Callable
from typing import Any
from typing_extensions import TypeAlias
MypyFile: TypeAlias = Any # from mypy.nodes
AttributeContext: TypeAlias = Any # from mypy.plugin
ClassDefContext: TypeAlias = Any # from mypy.plugin
DynamicClassDefContext: TypeAlias = Any # from mypy.plugin
Plugin: TypeAlias = Any # from mypy.plugin
Type: TypeAlias = Any # from mypy.types
_MypyFile: TypeAlias = Any # mypy.nodes.MypyFile
_AttributeContext: TypeAlias = Any # mypy.plugin.AttributeContext
_ClassDefContext: TypeAlias = Any # mypy.plugin.ClassDefContext
_DynamicClassDefContext: TypeAlias = Any # mypy.plugin.DynamicClassDefContext
_Plugin: TypeAlias = Any # mypy.plugin.Plugin
_Type: TypeAlias = Any # mypy.types.Type
class SQLAlchemyPlugin(Plugin):
def get_dynamic_class_hook(self, fullname: str) -> Callable[[DynamicClassDefContext], None] | None: ...
def get_customize_class_mro_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None: ...
def get_class_decorator_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None: ...
def get_metaclass_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None: ...
def get_base_class_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None: ...
def get_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None: ...
def get_additional_deps(self, file: MypyFile) -> list[tuple[int, str, int]]: ...
class SQLAlchemyPlugin(_Plugin):
def get_dynamic_class_hook(self, fullname: str) -> Callable[[_DynamicClassDefContext], None] | None: ...
def get_customize_class_mro_hook(self, fullname: str) -> Callable[[_ClassDefContext], None] | None: ...
def get_class_decorator_hook(self, fullname: str) -> Callable[[_ClassDefContext], None] | None: ...
def get_metaclass_hook(self, fullname: str) -> Callable[[_ClassDefContext], None] | None: ...
def get_base_class_hook(self, fullname: str) -> Callable[[_ClassDefContext], None] | None: ...
def get_attribute_hook(self, fullname: str) -> Callable[[_AttributeContext], _Type] | None: ...
def get_additional_deps(self, file: _MypyFile) -> list[tuple[int, str, int]]: ...
def plugin(version: str) -> type[SQLAlchemyPlugin]: ...

View File

@@ -2,19 +2,19 @@ from collections.abc import Iterable, Iterator
from typing import Any, TypeVar, overload
from typing_extensions import TypeAlias
CallExpr: TypeAlias = Any # from mypy.nodes
Context: TypeAlias = Any # from mypy.nodes
Expression: TypeAlias = Any # from mypy.nodes
JsonDict: TypeAlias = Any # from mypy.nodes
NameExpr: TypeAlias = Any # from mypy.nodes
Statement: TypeAlias = Any # from mypy.nodes
TypeInfo: TypeAlias = Any # from mypy.nodes
ClassDefContext: TypeAlias = Any # from mypy.plugin
DynamicClassDefContext: TypeAlias = Any # from mypy.plugin
SemanticAnalyzerPluginInterface: TypeAlias = Any # from mypy.plugin
Type: TypeAlias = Any # from mypy.types
_CallExpr: TypeAlias = Any # mypy.nodes._CallExpr
_Context: TypeAlias = Any # mypy.nodes._Context
_Expression: TypeAlias = Any # mypy.nodes._Expression
_JsonDict: TypeAlias = Any # mypy.nodes._JsonDict
_NameExpr: TypeAlias = Any # mypy.nodes._NameExpr
_Statement: TypeAlias = Any # mypy.nodes._Statement
_TypeInfo: TypeAlias = Any # mypy.nodes._TypeInfo
_ClassDefContext: TypeAlias = Any # mypy.plugin._ClassDefContext
_DynamicClassDefContext: TypeAlias = Any # mypy.plugin._DynamicClassDefContext
_SemanticAnalyzerPluginInterface: TypeAlias = Any # mypy.plugin._SemanticAnalyzerPluginInterface
_Type: TypeAlias = Any # mypy.types._Type
_TArgType = TypeVar("_TArgType", bound=CallExpr | NameExpr)
_TArgType = TypeVar("_TArgType", bound=_CallExpr | _NameExpr)
class SQLAlchemyAttribute:
name: Any
@@ -22,28 +22,28 @@ class SQLAlchemyAttribute:
column: Any
type: Any
info: Any
def __init__(self, name: str, line: int, column: int, typ: Type | None, info: TypeInfo) -> None: ...
def serialize(self) -> JsonDict: ...
def expand_typevar_from_subtype(self, sub_type: TypeInfo) -> None: ...
def __init__(self, name: str, line: int, column: int, typ: _Type | None, info: _TypeInfo) -> None: ...
def serialize(self) -> _JsonDict: ...
def expand_typevar_from_subtype(self, sub_type: _TypeInfo) -> None: ...
@classmethod
def deserialize(cls, info: TypeInfo, data: JsonDict, api: SemanticAnalyzerPluginInterface) -> SQLAlchemyAttribute: ...
def deserialize(cls, info: _TypeInfo, data: _JsonDict, api: _SemanticAnalyzerPluginInterface) -> SQLAlchemyAttribute: ...
def name_is_dunder(name): ...
def establish_as_sqlalchemy(info: TypeInfo) -> None: ...
def set_is_base(info: TypeInfo) -> None: ...
def get_is_base(info: TypeInfo) -> bool: ...
def has_declarative_base(info: TypeInfo) -> bool: ...
def set_has_table(info: TypeInfo) -> None: ...
def get_has_table(info: TypeInfo) -> bool: ...
def get_mapped_attributes(info: TypeInfo, api: SemanticAnalyzerPluginInterface) -> list[SQLAlchemyAttribute] | None: ...
def set_mapped_attributes(info: TypeInfo, attributes: list[SQLAlchemyAttribute]) -> None: ...
def fail(api: SemanticAnalyzerPluginInterface, msg: str, ctx: Context) -> None: ...
def add_global(ctx: ClassDefContext | DynamicClassDefContext, module: str, symbol_name: str, asname: str) -> None: ...
def establish_as_sqlalchemy(info: _TypeInfo) -> None: ...
def set_is_base(info: _TypeInfo) -> None: ...
def get_is_base(info: _TypeInfo) -> bool: ...
def has_declarative_base(info: _TypeInfo) -> bool: ...
def set_has_table(info: _TypeInfo) -> None: ...
def get_has_table(info: _TypeInfo) -> bool: ...
def get_mapped_attributes(info: _TypeInfo, api: _SemanticAnalyzerPluginInterface) -> list[SQLAlchemyAttribute] | None: ...
def set_mapped_attributes(info: _TypeInfo, attributes: list[SQLAlchemyAttribute]) -> None: ...
def fail(api: _SemanticAnalyzerPluginInterface, msg: str, ctx: _Context) -> None: ...
def add_global(ctx: _ClassDefContext | _DynamicClassDefContext, module: str, symbol_name: str, asname: str) -> None: ...
@overload
def get_callexpr_kwarg(callexpr: CallExpr, name: str, *, expr_types: None = ...) -> CallExpr | NameExpr | None: ...
def get_callexpr_kwarg(callexpr: _CallExpr, name: str, *, expr_types: None = ...) -> _CallExpr | _NameExpr | None: ...
@overload
def get_callexpr_kwarg(callexpr: CallExpr, name: str, *, expr_types: tuple[type[_TArgType], ...]) -> _TArgType | None: ...
def flatten_typechecking(stmts: Iterable[Statement]) -> Iterator[Statement]: ...
def unbound_to_instance(api: SemanticAnalyzerPluginInterface, typ: Type) -> Type: ...
def info_for_cls(cls, api: SemanticAnalyzerPluginInterface) -> TypeInfo | None: ...
def expr_to_mapped_constructor(expr: Expression) -> CallExpr: ...
def get_callexpr_kwarg(callexpr: _CallExpr, name: str, *, expr_types: tuple[type[_TArgType], ...]) -> _TArgType | None: ...
def flatten_typechecking(stmts: Iterable[_Statement]) -> Iterator[_Statement]: ...
def unbound_to_instance(api: _SemanticAnalyzerPluginInterface, typ: _Type) -> _Type: ...
def info_for_cls(cls, api: _SemanticAnalyzerPluginInterface) -> _TypeInfo | None: ...
def expr_to_mapped_constructor(expr: _Expression) -> _CallExpr: ...