From e545298e35ea9f126054b337e4b5ba01988b29f7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 24 Jan 2022 17:04:27 -0500 Subject: establish mypy / typing approach for v2.0 large patch to get ORM / typing efforts started. this is to support adding new test cases to mypy, support dropping sqlalchemy2-stubs entirely from the test suite, validate major ORM typing reorganization to eliminate the need for the mypy plugin. * New declarative approach which uses annotation introspection, fixes: #7535 * Mapped[] is now at the base of all ORM constructs that find themselves in classes, to support direct typing without plugins * Mypy plugin updated for new typing structures * Mypy test suite broken out into "plugin" tests vs. "plain" tests, and enhanced to better support test structures where we assert that various objects are introspected by the type checker as we expect. as we go forward with typing, we will add new use cases to "plain" where we can assert that types are introspected as we expect. * For typing support, users will be much more exposed to the class names of things. Add these all to "sqlalchemy" import space. * Column(ForeignKey()) no longer needs to be `@declared_attr` if the FK refers to a remote table * composite() attributes mapped to a dataclass no longer need to implement a `__composite_values__()` method * with_variant() accepts multiple dialect names Change-Id: I22797c0be73a8fbbd2d6f5e0c0b7258b17fe145d Fixes: #7535 Fixes: #7551 References: #6810 --- lib/sqlalchemy/sql/selectable.py | 67 +++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) (limited to 'lib/sqlalchemy/sql/selectable.py') diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index e1bbcffec..b0985f75d 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -12,14 +12,13 @@ SQL tables and derived rowsets. """ import collections +from enum import Enum import itertools from operator import attrgetter import typing from typing import Any as TODO_Any from typing import Optional from typing import Tuple -from typing import Type -from typing import Union from . import cache_key from . import coercions @@ -28,6 +27,7 @@ from . import roles from . import traversals from . import type_api from . import visitors +from ._typing import _ColumnsClauseElement from .annotation import Annotated from .annotation import SupportsCloneAnnotations from .base import _clone @@ -847,8 +847,11 @@ class FromClause(roles.AnonymizedFromClauseRole, Selectable): return self.alias(name=name) -LABEL_STYLE_NONE = util.symbol( - "LABEL_STYLE_NONE", +class SelectLabelStyle(Enum): + """Label style constants that may be passed to + :meth:`_sql.Select.set_label_style`.""" + + LABEL_STYLE_NONE = 0 """Label style indicating no automatic labeling should be applied to the columns clause of a SELECT statement. @@ -867,11 +870,9 @@ LABEL_STYLE_NONE = util.symbol( .. versionadded:: 1.4 -""", # noqa E501 -) + """ # noqa E501 -LABEL_STYLE_TABLENAME_PLUS_COL = util.symbol( - "LABEL_STYLE_TABLENAME_PLUS_COL", + LABEL_STYLE_TABLENAME_PLUS_COL = 1 """Label style indicating all columns should be labeled as ``_`` when generating the columns clause of a SELECT statement, to disambiguate same-named columns referenced from different @@ -897,12 +898,9 @@ LABEL_STYLE_TABLENAME_PLUS_COL = util.symbol( .. versionadded:: 1.4 -""", # noqa E501 -) + """ # noqa: E501 - -LABEL_STYLE_DISAMBIGUATE_ONLY = util.symbol( - "LABEL_STYLE_DISAMBIGUATE_ONLY", + LABEL_STYLE_DISAMBIGUATE_ONLY = 2 """Label style indicating that columns with a name that conflicts with an existing name should be labeled with a semi-anonymizing label when generating the columns clause of a SELECT statement. @@ -924,17 +922,24 @@ LABEL_STYLE_DISAMBIGUATE_ONLY = util.symbol( .. versionadded:: 1.4 -""", # noqa: E501, -) + """ # noqa: E501 + LABEL_STYLE_DEFAULT = LABEL_STYLE_DISAMBIGUATE_ONLY + """The default label style, refers to + :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY`. -LABEL_STYLE_DEFAULT = LABEL_STYLE_DISAMBIGUATE_ONLY -"""The default label style, refers to -:data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY`. + .. versionadded:: 1.4 -.. versionadded:: 1.4 + """ -""" + +( + LABEL_STYLE_NONE, + LABEL_STYLE_TABLENAME_PLUS_COL, + LABEL_STYLE_DISAMBIGUATE_ONLY, +) = list(SelectLabelStyle) + +LABEL_STYLE_DEFAULT = LABEL_STYLE_DISAMBIGUATE_ONLY class Join(roles.DMLTableRole, FromClause): @@ -2870,10 +2875,12 @@ class SelectStatementGrouping(GroupedElement, SelectBase): else: return self - def get_label_style(self): + def get_label_style(self) -> SelectLabelStyle: return self._label_style - def set_label_style(self, label_style): + def set_label_style( + self, label_style: SelectLabelStyle + ) -> "SelectStatementGrouping": return SelectStatementGrouping( self.element.set_label_style(label_style) ) @@ -3018,7 +3025,7 @@ class GenerativeSelect(SelectBase): ) return self - def get_label_style(self): + def get_label_style(self) -> SelectLabelStyle: """ Retrieve the current label style. @@ -3027,14 +3034,16 @@ class GenerativeSelect(SelectBase): """ return self._label_style - def set_label_style(self, style): + def set_label_style( + self: SelfGenerativeSelect, style: SelectLabelStyle + ) -> SelfGenerativeSelect: """Return a new selectable with the specified label style. There are three "label styles" available, - :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY`, - :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL`, and - :data:`_sql.LABEL_STYLE_NONE`. The default style is - :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL`. + :attr:`_sql.SelectLabelStyle.LABEL_STYLE_DISAMBIGUATE_ONLY`, + :attr:`_sql.SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL`, and + :attr:`_sql.SelectLabelStyle.LABEL_STYLE_NONE`. The default style is + :attr:`_sql.SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL`. In modern SQLAlchemy, there is not generally a need to change the labeling style, as per-expression labels are more effectively used by @@ -4131,7 +4140,7 @@ class Select( stmt.__dict__.update(kw) return stmt - def __init__(self, *entities: Union[roles.ColumnsClauseRole, Type]): + def __init__(self, *entities: _ColumnsClauseElement): r"""Construct a new :class:`_expression.Select`. The public constructor for :class:`_expression.Select` is the -- cgit v1.2.1