From 21ae9daf1e494460ec1f8a4ee37f57686b67d16f Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Sat, 16 Dec 2023 16:39:44 +0200 Subject: [PATCH] Add TupleAny type --- doc/build/changelog/unreleased_21/10296.rst | 2 +- lib/sqlalchemy/engine/base.py | 21 +++--- lib/sqlalchemy/engine/cursor.py | 21 +++--- lib/sqlalchemy/engine/default.py | 5 +- lib/sqlalchemy/engine/events.py | 3 +- lib/sqlalchemy/engine/result.py | 73 ++++++++----------- lib/sqlalchemy/ext/asyncio/result.py | 13 ++-- lib/sqlalchemy/ext/asyncio/scoping.py | 10 +-- lib/sqlalchemy/orm/context.py | 21 ++---- lib/sqlalchemy/orm/descriptor_props.py | 9 ++- lib/sqlalchemy/orm/interfaces.py | 7 +- lib/sqlalchemy/orm/loading.py | 6 +- lib/sqlalchemy/orm/mapper.py | 3 +- lib/sqlalchemy/orm/query.py | 3 +- lib/sqlalchemy/orm/scoping.py | 9 ++- lib/sqlalchemy/orm/session.py | 21 +++--- lib/sqlalchemy/orm/state.py | 7 +- lib/sqlalchemy/orm/util.py | 11 +-- .../sql/_selectable_constructors.py | 6 +- lib/sqlalchemy/sql/_typing.py | 4 +- lib/sqlalchemy/sql/compiler.py | 5 +- lib/sqlalchemy/sql/dml.py | 7 +- lib/sqlalchemy/sql/elements.py | 11 ++- lib/sqlalchemy/sql/selectable.py | 59 ++++++++------- lib/sqlalchemy/sql/sqltypes.py | 3 +- lib/sqlalchemy/util/typing.py | 2 + tools/normalize_file_headers.py | 2 +- 27 files changed, 170 insertions(+), 174 deletions(-) diff --git a/doc/build/changelog/unreleased_21/10296.rst b/doc/build/changelog/unreleased_21/10296.rst index c674ecbe1a..c58eb85660 100644 --- a/doc/build/changelog/unreleased_21/10296.rst +++ b/doc/build/changelog/unreleased_21/10296.rst @@ -7,4 +7,4 @@ be imported only when the asyncio extension is first imported. Alternatively, the ``greenlet`` library is still imported lazily on first use to support use case that don't make direct use of the - SQLAlchemy asyncio extension. \ No newline at end of file + SQLAlchemy asyncio extension. diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 75b6f1dc93..cd71fe2639 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -43,6 +43,7 @@ from .. import log from .. import util from ..sql import compiler from ..sql import util as sql_util +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -1369,7 +1370,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): parameters: Optional[_CoreAnyExecuteParams] = None, *, execution_options: Optional[CoreExecuteOptionsParameter] = None, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: ... def execute( @@ -1378,7 +1379,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): parameters: Optional[_CoreAnyExecuteParams] = None, *, execution_options: Optional[CoreExecuteOptionsParameter] = None, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: r"""Executes a SQL statement construct and returns a :class:`_engine.CursorResult`. @@ -1427,7 +1428,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): func: FunctionElement[Any], distilled_parameters: _CoreMultiExecuteParams, execution_options: CoreExecuteOptionsParameter, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """Execute a sql.FunctionElement object.""" return self._execute_clauseelement( @@ -1498,7 +1499,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): ddl: ExecutableDDLElement, distilled_parameters: _CoreMultiExecuteParams, execution_options: CoreExecuteOptionsParameter, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """Execute a schema.DDL object.""" execution_options = ddl._execution_options.merge_with( @@ -1594,7 +1595,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): elem: Executable, distilled_parameters: _CoreMultiExecuteParams, execution_options: CoreExecuteOptionsParameter, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """Execute a sql.ClauseElement object.""" execution_options = elem._execution_options.merge_with( @@ -1667,7 +1668,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): compiled: Compiled, distilled_parameters: _CoreMultiExecuteParams, execution_options: CoreExecuteOptionsParameter = _EMPTY_EXECUTION_OPTS, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """Execute a sql.Compiled object. TODO: why do we have this? likely deprecate or remove @@ -1717,7 +1718,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: str, parameters: Optional[_DBAPIAnyExecuteParams] = None, execution_options: Optional[CoreExecuteOptionsParameter] = None, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: r"""Executes a string SQL statement on the DBAPI cursor directly, without any SQL compilation steps. @@ -1799,7 +1800,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): execution_options: _ExecuteOptions, *args: Any, **kw: Any, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """Create an :class:`.ExecutionContext` and execute, returning a :class:`_engine.CursorResult`.""" @@ -1858,7 +1859,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): context: ExecutionContext, statement: Union[str, Compiled], parameters: Optional[_AnyMultiExecuteParams], - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """continue the _execute_context() method for a single DBAPI cursor.execute() or cursor.executemany() call. @@ -1998,7 +1999,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, dialect: Dialect, context: ExecutionContext, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: """continue the _execute_context() method for an "insertmanyvalues" operation, which will invoke DBAPI cursor.execute() one or more times with individual log and diff --git a/lib/sqlalchemy/engine/cursor.py b/lib/sqlalchemy/engine/cursor.py index dae898e628..9708d2a2a1 100644 --- a/lib/sqlalchemy/engine/cursor.py +++ b/lib/sqlalchemy/engine/cursor.py @@ -52,6 +52,7 @@ from ..sql.type_api import TypeEngine from ..util import compat from ..util.typing import Literal from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -345,7 +346,7 @@ class CursorResultMetaData(ResultMetaData): def __init__( self, - parent: CursorResult[Unpack[Tuple[Any, ...]]], + parent: CursorResult[Unpack[TupleAny]], cursor_description: _DBAPICursorDescription, ): context = parent.context @@ -930,21 +931,21 @@ class ResultFetchStrategy: def soft_close( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: Optional[DBAPICursor], ) -> None: raise NotImplementedError() def hard_close( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: Optional[DBAPICursor], ) -> None: raise NotImplementedError() def yield_per( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: Optional[DBAPICursor], num: int, ) -> None: @@ -952,7 +953,7 @@ class ResultFetchStrategy: def fetchone( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: DBAPICursor, hard_close: bool = False, ) -> Any: @@ -960,7 +961,7 @@ class ResultFetchStrategy: def fetchmany( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: DBAPICursor, size: Optional[int] = None, ) -> Any: @@ -968,14 +969,14 @@ class ResultFetchStrategy: def fetchall( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: DBAPICursor, ) -> Any: raise NotImplementedError() def handle_exception( self, - result: CursorResult[Unpack[Tuple[Any, ...]]], + result: CursorResult[Unpack[TupleAny]], dbapi_cursor: Optional[DBAPICursor], err: BaseException, ) -> NoReturn: @@ -2114,8 +2115,8 @@ class CursorResult(Result[Unpack[_Ts]]): return self._fetchiter_impl() def merge( - self, *others: Result[Unpack[Tuple[Any, ...]]] - ) -> MergedResult[Unpack[Tuple[Any, ...]]]: + self, *others: Result[Unpack[TupleAny]] + ) -> MergedResult[Unpack[TupleAny]]: merged_result = super().merge(*others) setup_rowcounts = self.context._has_rowcount if setup_rowcounts: diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index b1bc37c840..cb9a6f2dfd 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -66,6 +66,7 @@ from ..sql.compiler import SQLCompiler from ..sql.elements import quoted_name from ..util.typing import Final from ..util.typing import Literal +from ..util.typing import TupleAny from ..util.typing import Unpack @@ -1183,9 +1184,7 @@ class DefaultExecutionContext(ExecutionContext): result_column_struct: Optional[ Tuple[List[ResultColumnsEntry], bool, bool, bool, bool] ] = None - returned_default_rows: Optional[ - Sequence[Row[Unpack[Tuple[Any, ...]]]] - ] = None + returned_default_rows: Optional[Sequence[Row[Unpack[TupleAny]]]] = None execution_options: _ExecuteOptions = util.EMPTY_DICT diff --git a/lib/sqlalchemy/engine/events.py b/lib/sqlalchemy/engine/events.py index a5867d3e4d..cc93c6fb62 100644 --- a/lib/sqlalchemy/engine/events.py +++ b/lib/sqlalchemy/engine/events.py @@ -25,6 +25,7 @@ from .interfaces import Dialect from .. import event from .. import exc from ..util.typing import Literal +from ..util.typing import TupleAny from ..util.typing import Unpack if typing.TYPE_CHECKING: @@ -271,7 +272,7 @@ class ConnectionEvents(event.Events[ConnectionEventsTarget]): multiparams: _CoreMultiExecuteParams, params: _CoreSingleExecuteParams, execution_options: _ExecuteOptions, - result: Result[Unpack[Tuple[Any, ...]]], + result: Result[Unpack[TupleAny]], ) -> None: """Intercept high level execute() events after execute. diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 90c49a6705..b0ddbb0f05 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -46,6 +46,7 @@ from ..util import NONE_SET from ..util._has_cy import HAS_CYEXTENSION from ..util.typing import Literal from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -67,7 +68,7 @@ _KeyMapRecType = Any _KeyMapType = Mapping[_KeyType, _KeyMapRecType] -_RowData = Union[Row[Unpack[Tuple[Any, ...]]], RowMapping, Any] +_RowData = Union[Row[Unpack[TupleAny]], RowMapping, Any] """A generic form of "row" that accommodates for the different kinds of "rows" that different result objects return, including row, row mapping, and scalar values""" @@ -171,7 +172,7 @@ class ResultMetaData: def _getter( self, key: Any, raiseerr: bool = True - ) -> Optional[Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]]: + ) -> Optional[Callable[[Row[Unpack[TupleAny]]], Any]]: index = self._index_for_key(key, raiseerr) if index is not None: @@ -417,7 +418,7 @@ _NO_ROW = _NoRow._NO_ROW class ResultInternal(InPlaceGenerative, Generic[_R]): __slots__ = () - _real_result: Optional[Result[Unpack[Tuple[Any, ...]]]] = None + _real_result: Optional[Result[Unpack[TupleAny]]] = None _generate_rows: bool = True _row_logging_fn: Optional[Callable[[Any], Any]] @@ -431,22 +432,22 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): def _fetchiter_impl( self, - ) -> Iterator[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> Iterator[_InterimRowType[Row[Unpack[TupleAny]]]]: raise NotImplementedError() def _fetchone_impl( self, hard_close: bool = False - ) -> Optional[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> Optional[_InterimRowType[Row[Unpack[TupleAny]]]]: raise NotImplementedError() def _fetchmany_impl( self, size: Optional[int] = None - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: raise NotImplementedError() def _fetchall_impl( self, - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: raise NotImplementedError() def _soft_close(self, hard: bool = False) -> None: @@ -454,10 +455,10 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): @HasMemoized_ro_memoized_attribute def _row_getter(self) -> Optional[Callable[..., _R]]: - real_result: Result[Unpack[Tuple[Any, ...]]] = ( + real_result: Result[Unpack[TupleAny]] = ( self._real_result if self._real_result - else cast("Result[Unpack[Tuple[Any, ...]]]", self) + else cast("Result[Unpack[TupleAny]]", self) ) if real_result._source_supports_scalars: @@ -495,9 +496,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): fixed_tf = tf - def make_row( - row: _InterimRowType[Row[Unpack[Tuple[Any, ...]]]] - ) -> _R: + def make_row(row: _InterimRowType[Row[Unpack[TupleAny]]]) -> _R: return _make_row_orig(fixed_tf(row)) else: @@ -509,9 +508,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): _log_row = real_result._row_logging_fn _make_row = make_row - def make_row( - row: _InterimRowType[Row[Unpack[Tuple[Any, ...]]]] - ) -> _R: + def make_row(row: _InterimRowType[Row[Unpack[TupleAny]]]) -> _R: return _log_row(_make_row(row)) # type: ignore return make_row @@ -525,9 +522,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): if self._unique_filter_state: uniques, strategy = self._unique_strategy - def iterrows( - self: Result[Unpack[Tuple[Any, ...]]] - ) -> Iterator[_R]: + def iterrows(self: Result[Unpack[TupleAny]]) -> Iterator[_R]: for raw_row in self._fetchiter_impl(): obj: _InterimRowType[Any] = ( make_row(raw_row) if make_row else raw_row @@ -542,9 +537,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): else: - def iterrows( - self: Result[Unpack[Tuple[Any, ...]]] - ) -> Iterator[_R]: + def iterrows(self: Result[Unpack[TupleAny]]) -> Iterator[_R]: for raw_row in self._fetchiter_impl(): row: _InterimRowType[Any] = ( make_row(raw_row) if make_row else raw_row @@ -609,9 +602,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): if self._unique_filter_state: uniques, strategy = self._unique_strategy - def onerow( - self: Result[Unpack[Tuple[Any, ...]]] - ) -> Union[_NoRow, _R]: + def onerow(self: Result[Unpack[TupleAny]]) -> Union[_NoRow, _R]: _onerow = self._fetchone_impl while True: row = _onerow() @@ -632,9 +623,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): else: - def onerow( - self: Result[Unpack[Tuple[Any, ...]]] - ) -> Union[_NoRow, _R]: + def onerow(self: Result[Unpack[TupleAny]]) -> Union[_NoRow, _R]: row = self._fetchone_impl() if row is None: return _NO_ROW @@ -694,7 +683,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): real_result = ( self._real_result if self._real_result - else cast("Result[Unpack[Tuple[Any, ...]]]", self) + else cast("Result[Unpack[TupleAny]]", self) ) if real_result._yield_per: num_required = num = real_result._yield_per @@ -734,7 +723,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): real_result = ( self._real_result if self._real_result - else cast("Result[Unpack[Tuple[Any, ...]]]", self) + else cast("Result[Unpack[TupleAny]]", self) ) num = real_result._yield_per @@ -866,7 +855,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): real_result = ( self._real_result if self._real_result - else cast("Result[Unpack[Tuple[Any, ...]]]", self) + else cast("Result[Unpack[TupleAny]]", self) ) if not real_result._source_supports_scalars or len(indexes) != 1: @@ -884,7 +873,7 @@ class ResultInternal(InPlaceGenerative, Generic[_R]): real_result = ( self._real_result if self._real_result is not None - else cast("Result[Unpack[Tuple[Any, ...]]]", self) + else cast("Result[Unpack[TupleAny]]", self) ) if not strategy and self._metadata._unique_filters: @@ -957,7 +946,7 @@ class Result(_WithKeys, ResultInternal[Row[Unpack[_Ts]]]): __slots__ = ("_metadata", "__dict__") _row_logging_fn: Optional[ - Callable[[Row[Unpack[Tuple[Any, ...]]]], Row[Unpack[Tuple[Any, ...]]]] + Callable[[Row[Unpack[TupleAny]]], Row[Unpack[TupleAny]]] ] = None _source_supports_scalars: bool = False @@ -1193,7 +1182,7 @@ class Result(_WithKeys, ResultInternal[Row[Unpack[_Ts]]]): def _getter( self, key: _KeyIndexType, raiseerr: bool = True - ) -> Optional[Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]]: + ) -> Optional[Callable[[Row[Unpack[TupleAny]]], Any]]: """return a callable that will retrieve the given key from a :class:`_engine.Row`. @@ -1657,7 +1646,7 @@ class FilterResult(ResultInternal[_R]): _post_creational_filter: Optional[Callable[[Any], Any]] - _real_result: Result[Unpack[Tuple[Any, ...]]] + _real_result: Result[Unpack[TupleAny]] def __enter__(self) -> Self: return self @@ -1718,22 +1707,22 @@ class FilterResult(ResultInternal[_R]): def _fetchiter_impl( self, - ) -> Iterator[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> Iterator[_InterimRowType[Row[Unpack[TupleAny]]]]: return self._real_result._fetchiter_impl() def _fetchone_impl( self, hard_close: bool = False - ) -> Optional[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> Optional[_InterimRowType[Row[Unpack[TupleAny]]]]: return self._real_result._fetchone_impl(hard_close=hard_close) def _fetchall_impl( self, - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: return self._real_result._fetchall_impl() def _fetchmany_impl( self, size: Optional[int] = None - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: return self._real_result._fetchmany_impl(size=size) @@ -2316,7 +2305,7 @@ class IteratorResult(Result[Unpack[_Ts]]): def _fetchone_impl( self, hard_close: bool = False - ) -> Optional[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> Optional[_InterimRowType[Row[Unpack[TupleAny]]]]: if self._hard_closed: self._raise_hard_closed() @@ -2329,7 +2318,7 @@ class IteratorResult(Result[Unpack[_Ts]]): def _fetchall_impl( self, - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: if self._hard_closed: self._raise_hard_closed() try: @@ -2339,7 +2328,7 @@ class IteratorResult(Result[Unpack[_Ts]]): def _fetchmany_impl( self, size: Optional[int] = None - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: if self._hard_closed: self._raise_hard_closed() @@ -2401,7 +2390,7 @@ class ChunkedIteratorResult(IteratorResult[Unpack[_Ts]]): def _fetchmany_impl( self, size: Optional[int] = None - ) -> List[_InterimRowType[Row[Unpack[Tuple[Any, ...]]]]]: + ) -> List[_InterimRowType[Row[Unpack[TupleAny]]]]: if self.dynamic_yield_per: self.iterator = itertools.chain.from_iterable(self.chunks(size)) return super()._fetchmany_impl(size=size) diff --git a/lib/sqlalchemy/ext/asyncio/result.py b/lib/sqlalchemy/ext/asyncio/result.py index 5467ed4c8f..9cf5cb230b 100644 --- a/lib/sqlalchemy/ext/asyncio/result.py +++ b/lib/sqlalchemy/ext/asyncio/result.py @@ -32,6 +32,7 @@ from ...util import deprecated from ...util.concurrency import greenlet_spawn from ...util.typing import Literal from ...util.typing import Self +from ...util.typing import TupleAny from ...util.typing import TypeVarTuple from ...util.typing import Unpack @@ -47,7 +48,7 @@ _Ts = TypeVarTuple("_Ts") class AsyncCommon(FilterResult[_R]): __slots__ = () - _real_result: Result[Unpack[Tuple[Any, ...]]] + _real_result: Result[Unpack[TupleAny]] _metadata: ResultMetaData async def close(self) -> None: # type: ignore[override] @@ -465,13 +466,13 @@ class AsyncResult(_WithKeys, AsyncCommon[Row[Unpack[_Ts]]]): @overload def scalars( - self: AsyncResult[_T, Unpack[Tuple[Any, ...]]], index: Literal[0] + self: AsyncResult[_T, Unpack[TupleAny]], index: Literal[0] ) -> AsyncScalarResult[_T]: ... @overload def scalars( - self: AsyncResult[_T, Unpack[Tuple[Any, ...]]], + self: AsyncResult[_T, Unpack[TupleAny]], ) -> AsyncScalarResult[_T]: ... @@ -531,7 +532,7 @@ class AsyncScalarResult(AsyncCommon[_R]): def __init__( self, - real_result: Result[Unpack[Tuple[Any, ...]]], + real_result: Result[Unpack[TupleAny]], index: _KeyIndexType, ): self._real_result = real_result @@ -664,7 +665,7 @@ class AsyncMappingResult(_WithKeys, AsyncCommon[RowMapping]): _post_creational_filter = operator.attrgetter("_mapping") - def __init__(self, result: Result[Unpack[Tuple[Any, ...]]]): + def __init__(self, result: Result[Unpack[TupleAny]]): self._real_result = result self._unique_filter_state = result._unique_filter_state self._metadata = result._metadata @@ -964,7 +965,7 @@ class AsyncTupleResult(AsyncCommon[_R], util.TypingOnly): ... -_RT = TypeVar("_RT", bound="Result[Unpack[Tuple[Any, ...]]]") +_RT = TypeVar("_RT", bound="Result[Unpack[TupleAny]]") async def _ensure_sync_result(result: _RT, calling_method: Any) -> _RT: diff --git a/lib/sqlalchemy/ext/asyncio/scoping.py b/lib/sqlalchemy/ext/asyncio/scoping.py index 53112b545d..c24fec9c93 100644 --- a/lib/sqlalchemy/ext/asyncio/scoping.py +++ b/lib/sqlalchemy/ext/asyncio/scoping.py @@ -15,7 +15,6 @@ from typing import Iterator from typing import Optional from typing import overload from typing import Sequence -from typing import Tuple from typing import Type from typing import TYPE_CHECKING from typing import TypeVar @@ -31,6 +30,7 @@ from ...util import create_proxy_methods from ...util import ScopedRegistry from ...util import warn from ...util import warn_deprecated +from ...util.typing import TupleAny from ...util.typing import TypeVarTuple from ...util.typing import Unpack @@ -565,7 +565,7 @@ class async_scoped_session(Generic[_AS]): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: ... async def execute( @@ -576,7 +576,7 @@ class async_scoped_session(Generic[_AS]): execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, bind_arguments: Optional[_BindArguments] = None, **kw: Any, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: r"""Execute a statement and return a buffered :class:`_engine.Result` object. @@ -1593,10 +1593,10 @@ class async_scoped_session(Generic[_AS]): def identity_key( cls, class_: Optional[Type[Any]] = None, - ident: Union[Any, Tuple[Any, ...]] = None, + ident: Union[Any, TupleAny] = None, *, instance: Optional[Any] = None, - row: Optional[Union[Row[Unpack[Tuple[Any, ...]]], RowMapping]] = None, + row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]] = None, identity_token: Optional[Any] = None, ) -> _IdentityKeyType[Any]: r"""Return an identity key. diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py index f9b57926a3..f7374e78d0 100644 --- a/lib/sqlalchemy/orm/context.py +++ b/lib/sqlalchemy/orm/context.py @@ -67,6 +67,7 @@ from ..sql.selectable import SelectLabelStyle from ..sql.selectable import SelectState from ..sql.selectable import TypedReturnsRows from ..sql.visitors import InternalTraversal +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -151,8 +152,8 @@ class QueryContext: self, compile_state: CompileState, statement: Union[ - Select[Unpack[Tuple[Any, ...]]], - FromStatement[Unpack[Tuple[Any, ...]]], + Select[Unpack[TupleAny]], + FromStatement[Unpack[TupleAny]], ], params: _CoreSingleExecuteParams, session: Session, @@ -407,11 +408,9 @@ class ORMCompileState(AbstractORMCompileState): attributes: Dict[Any, Any] global_attributes: Dict[Any, Any] - statement: Union[ - Select[Unpack[Tuple[Any, ...]]], FromStatement[Unpack[Tuple[Any, ...]]] - ] + statement: Union[Select[Unpack[TupleAny]], FromStatement[Unpack[TupleAny]]] select_statement: Union[ - Select[Unpack[Tuple[Any, ...]]], FromStatement[Unpack[Tuple[Any, ...]]] + Select[Unpack[TupleAny]], FromStatement[Unpack[TupleAny]] ] _entities: List[_QueryEntity] _polymorphic_adapters: Dict[_InternalEntityType, ORMAdapter] @@ -426,7 +425,7 @@ class ORMCompileState(AbstractORMCompileState): dedupe_columns: Set[ColumnElement[Any]] create_eager_joins: List[ # TODO: this structure is set up by JoinedLoader - Tuple[Any, ...] + TupleAny ] current_path: PathRegistry = _path_registry _has_mapper_entities = False @@ -2444,9 +2443,7 @@ def _column_descriptions( def _legacy_filter_by_entity_zero( - query_or_augmented_select: Union[ - Query[Any], Select[Unpack[Tuple[Any, ...]]] - ] + query_or_augmented_select: Union[Query[Any], Select[Unpack[TupleAny]]] ) -> Optional[_InternalEntityType[Any]]: self = query_or_augmented_select if self._setup_joins: @@ -2461,9 +2458,7 @@ def _legacy_filter_by_entity_zero( def _entity_from_pre_ent_zero( - query_or_augmented_select: Union[ - Query[Any], Select[Unpack[Tuple[Any, ...]]] - ] + query_or_augmented_select: Union[Query[Any], Select[Unpack[TupleAny]]] ) -> Optional[_InternalEntityType[Any]]: self = query_or_augmented_select if not self._raw_columns: diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 7925f25b1c..555069ee9a 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -55,6 +55,7 @@ from ..sql import operators from ..sql.elements import BindParameter from ..util.typing import is_fwd_ref from ..util.typing import is_pep593 +from ..util.typing import TupleAny from ..util.typing import typing_get_args from ..util.typing import Unpack @@ -715,11 +716,11 @@ class CompositeProperty( def create_row_processor( self, - query: Select[Unpack[Tuple[Any, ...]]], - procs: Sequence[Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]], + query: Select[Unpack[TupleAny]], + procs: Sequence[Callable[[Row[Unpack[TupleAny]]], Any]], labels: Sequence[str], - ) -> Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]: - def proc(row: Row[Unpack[Tuple[Any, ...]]]) -> Any: + ) -> Callable[[Row[Unpack[TupleAny]]], Any]: + def proc(row: Row[Unpack[TupleAny]]) -> Any: return self.property.composite_class( *[proc(row) for proc in procs] ) diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 247ca03874..92676e1f73 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -71,6 +71,7 @@ from ..sql.schema import Column from ..sql.type_api import TypeEngine from ..util import warn_deprecated from ..util.typing import RODescriptorReference +from ..util.typing import TupleAny from ..util.typing import TypedDict from ..util.typing import Unpack @@ -488,7 +489,7 @@ class MapperProperty( query_entity: _MapperEntity, path: AbstractEntityRegistry, mapper: Mapper[Any], - result: Result[Unpack[Tuple[Any, ...]]], + result: Result[Unpack[TupleAny]], adapter: Optional[ORMAdapter], populators: _PopulatorDict, ) -> None: @@ -1058,7 +1059,7 @@ class StrategizedProperty(MapperProperty[_T]): query_entity: _MapperEntity, path: AbstractEntityRegistry, mapper: Mapper[Any], - result: Result[Unpack[Tuple[Any, ...]]], + result: Result[Unpack[TupleAny]], adapter: Optional[ORMAdapter], populators: _PopulatorDict, ) -> None: @@ -1449,7 +1450,7 @@ class LoaderStrategy: path: AbstractEntityRegistry, loadopt: Optional[_LoadElement], mapper: Mapper[Any], - result: Result[Unpack[Tuple[Any, ...]]], + result: Result[Unpack[TupleAny]], adapter: Optional[ORMAdapter], populators: _PopulatorDict, ) -> None: diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 9daca51e11..572eab668e 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -53,9 +53,9 @@ from ..sql.selectable import ForUpdateArg from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL from ..sql.selectable import SelectState from ..util import EMPTY_DICT +from ..util.typing import TupleAny from ..util.typing import Unpack - if TYPE_CHECKING: from ._typing import _IdentityKeyType from .base import LoaderCallableStatus @@ -78,8 +78,8 @@ _PopulatorDict = Dict[str, List[Tuple[str, Any]]] def instances( - cursor: CursorResult[Unpack[Tuple[Any, ...]]], context: QueryContext -) -> Result[Unpack[Tuple[Any, ...]]]: + cursor: CursorResult[Unpack[TupleAny]], context: QueryContext +) -> Result[Unpack[TupleAny]]: """Return a :class:`.Result` given an ORM query context. :param cursor: a :class:`.CursorResult`, generated by a statement diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 1228931a74..c0c62fcd0c 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -89,6 +89,7 @@ from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL from ..util import HasMemoized from ..util import HasMemoized_ro_memoized_attribute from ..util.typing import Literal +from ..util.typing import TupleAny from ..util.typing import Unpack if TYPE_CHECKING: @@ -3429,7 +3430,7 @@ class Mapper( def identity_key_from_row( self, - row: Optional[Union[Row[Unpack[Tuple[Any, ...]]], RowMapping]], + row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]], identity_token: Optional[Any] = None, adapter: Optional[ORMAdapter] = None, ) -> _IdentityKeyType[_O]: diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index b4a30128d1..d18f9ad5cd 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -93,6 +93,7 @@ from ..sql.selectable import SelectLabelStyle from ..util import deprecated from ..util.typing import Literal from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -543,7 +544,7 @@ class Query( def _final_statement( self, legacy_query_style: bool = True - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: """Return the 'final' SELECT statement for this :class:`.Query`. This is used by the testing suite only and is fairly inefficient. diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index 489d3af70a..519b1e7e11 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -32,6 +32,7 @@ from ..util import ThreadLocalRegistry from ..util import warn from ..util import warn_deprecated from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -699,7 +700,7 @@ class scoped_session(Generic[_S]): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: ... @overload @@ -712,7 +713,7 @@ class scoped_session(Generic[_S]): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: ... def execute( @@ -724,7 +725,7 @@ class scoped_session(Generic[_S]): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: r"""Execute a SQL expression construct. .. container:: class_bases @@ -2162,7 +2163,7 @@ class scoped_session(Generic[_S]): ident: Union[Any, Tuple[Any, ...]] = None, *, instance: Optional[Any] = None, - row: Optional[Union[Row[Unpack[Tuple[Any, ...]]], RowMapping]] = None, + row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]] = None, identity_token: Optional[Any] = None, ) -> _IdentityKeyType[Any]: r"""Return an identity key. diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 031022beb8..092bde7ecc 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -91,6 +91,7 @@ from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL from ..util import IdentitySet from ..util.typing import Literal from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -226,7 +227,7 @@ class _SessionClassMethods: ident: Union[Any, Tuple[Any, ...]] = None, *, instance: Optional[Any] = None, - row: Optional[Union[Row[Unpack[Tuple[Any, ...]]], RowMapping]] = None, + row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]] = None, identity_token: Optional[Any] = None, ) -> _IdentityKeyType[Any]: """Return an identity key. @@ -389,7 +390,7 @@ class ORMExecuteState(util.MemoizedSlots): params: Optional[_CoreAnyExecuteParams] = None, execution_options: Optional[OrmExecuteOptionsParameter] = None, bind_arguments: Optional[_BindArguments] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: """Execute the statement represented by this :class:`.ORMExecuteState`, without re-invoking events that have already proceeded. @@ -2075,7 +2076,7 @@ class Session(_SessionClassMethods, EventTarget): _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, _scalar_result: bool = ..., - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: ... def _execute_internal( @@ -2151,7 +2152,7 @@ class Session(_SessionClassMethods, EventTarget): ) for idx, fn in enumerate(events_todo): orm_exec_state._starting_event_idx = idx - fn_result: Optional[Result[Unpack[Tuple[Any, ...]]]] = fn( + fn_result: Optional[Result[Unpack[TupleAny]]] = fn( orm_exec_state ) if fn_result: @@ -2194,7 +2195,7 @@ class Session(_SessionClassMethods, EventTarget): if compile_state_cls: result: Result[ - Unpack[Tuple[Any, ...]] + Unpack[TupleAny] ] = compile_state_cls.orm_execute_statement( self, statement, @@ -2236,7 +2237,7 @@ class Session(_SessionClassMethods, EventTarget): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> CursorResult[Unpack[Tuple[Any, ...]]]: + ) -> CursorResult[Unpack[TupleAny]]: ... @overload @@ -2249,7 +2250,7 @@ class Session(_SessionClassMethods, EventTarget): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: ... def execute( @@ -2261,7 +2262,7 @@ class Session(_SessionClassMethods, EventTarget): bind_arguments: Optional[_BindArguments] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, - ) -> Result[Unpack[Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: r"""Execute a SQL expression construct. Returns a :class:`_engine.Result` object representing @@ -3132,9 +3133,7 @@ class Session(_SessionClassMethods, EventTarget): with_for_update = ForUpdateArg._from_argument(with_for_update) - stmt: Select[Unpack[Tuple[Any, ...]]] = sql.select( - object_mapper(instance) - ) + stmt: Select[Unpack[TupleAny]] = sql.select(object_mapper(instance)) if ( loading.load_on_ident( self, diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index d142f075c4..83f85cda27 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -46,6 +46,7 @@ from .. import inspection from .. import util from ..util.typing import Literal from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import Unpack if TYPE_CHECKING: @@ -97,7 +98,7 @@ class _InstallLoaderCallableProto(Protocol[_O]): self, state: InstanceState[_O], dict_: _InstanceDict, - row: Row[Unpack[Tuple[Any, ...]]], + row: Row[Unpack[TupleAny]], ) -> None: ... @@ -679,7 +680,7 @@ class InstanceState(interfaces.InspectionAttrInfo, Generic[_O]): def _set_callable( state: InstanceState[_O], dict_: _InstanceDict, - row: Row[Unpack[Tuple[Any, ...]]], + row: Row[Unpack[TupleAny]], ) -> None: if "callables" not in state.__dict__: state.callables = {} @@ -693,7 +694,7 @@ class InstanceState(interfaces.InspectionAttrInfo, Generic[_O]): def _set_callable( state: InstanceState[_O], dict_: _InstanceDict, - row: Row[Unpack[Tuple[Any, ...]]], + row: Row[Unpack[TupleAny]], ) -> None: if "callables" not in state.__dict__: state.callables = {} diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index a2f202aa4c..d834435c47 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -92,6 +92,7 @@ from ..util.typing import eval_name_only as _eval_name_only from ..util.typing import is_origin_of_cls from ..util.typing import Literal from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import typing_get_origin from ..util.typing import Unpack @@ -427,7 +428,7 @@ def identity_key( ident: Union[Any, Tuple[Any, ...]] = None, *, instance: Optional[_T] = None, - row: Optional[Union[Row[Unpack[Tuple[Any, ...]]], RowMapping]] = None, + row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]] = None, identity_token: Optional[Any] = None, ) -> _IdentityKeyType[_T]: r"""Generate "identity key" tuples, as are used as keys in the @@ -1722,10 +1723,10 @@ class Bundle( def create_row_processor( self, - query: Select[Unpack[Tuple[Any, ...]]], - procs: Sequence[Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]], + query: Select[Unpack[TupleAny]], + procs: Sequence[Callable[[Row[Unpack[TupleAny]]], Any]], labels: Sequence[str], - ) -> Callable[[Row[Unpack[Tuple[Any, ...]]]], Any]: + ) -> Callable[[Row[Unpack[TupleAny]]], Any]: """Produce the "row processing" function for this :class:`.Bundle`. May be overridden by subclasses to provide custom behaviors when @@ -1761,7 +1762,7 @@ class Bundle( """ keyed_tuple = result_tuple(labels, [() for l in labels]) - def proc(row: Row[Unpack[Tuple[Any, ...]]]) -> Any: + def proc(row: Row[Unpack[TupleAny]]) -> Any: return keyed_tuple([proc(row) for proc in procs]) return proc diff --git a/lib/sqlalchemy/sql/_selectable_constructors.py b/lib/sqlalchemy/sql/_selectable_constructors.py index 8f6bc74fad..2df2ef1cb6 100644 --- a/lib/sqlalchemy/sql/_selectable_constructors.py +++ b/lib/sqlalchemy/sql/_selectable_constructors.py @@ -10,7 +10,6 @@ from __future__ import annotations from typing import Any from typing import Optional from typing import overload -from typing import Tuple from typing import TYPE_CHECKING from typing import TypeVar from typing import Union @@ -32,6 +31,7 @@ from .selectable import Select from .selectable import TableClause from .selectable import TableSample from .selectable import Values +from ..util.typing import TupleAny from ..util.typing import Unpack if TYPE_CHECKING: @@ -452,13 +452,13 @@ def select( @overload def select( *entities: _ColumnsClauseArgument[Any], **__kw: Any -) -> Select[Unpack[Tuple[Any, ...]]]: +) -> Select[Unpack[TupleAny]]: ... def select( *entities: _ColumnsClauseArgument[Any], **__kw: Any -) -> Select[Unpack[Tuple[Any, ...]]]: +) -> Select[Unpack[TupleAny]]: r"""Construct a new :class:`_expression.Select`. diff --git a/lib/sqlalchemy/sql/_typing.py b/lib/sqlalchemy/sql/_typing.py index 2adc2d7f70..bb0ac7dbcf 100644 --- a/lib/sqlalchemy/sql/_typing.py +++ b/lib/sqlalchemy/sql/_typing.py @@ -17,7 +17,6 @@ from typing import NoReturn from typing import Optional from typing import overload from typing import Set -from typing import Tuple from typing import Type from typing import TYPE_CHECKING from typing import TypeVar @@ -29,6 +28,7 @@ from .. import util from ..inspection import Inspectable from ..util.typing import Literal from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import TypeAlias from ..util.typing import Unpack @@ -325,7 +325,7 @@ if TYPE_CHECKING: def is_select_statement( t: Union[Executable, ReturnsRows] - ) -> TypeGuard[Select[Unpack[Tuple[Any, ...]]]]: + ) -> TypeGuard[Select[Unpack[TupleAny]]]: ... def is_table(t: FromClause) -> TypeGuard[TableClause]: diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index f0a327cff6..49fb4eb231 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -87,6 +87,7 @@ from .. import util from ..util import FastIntFlag from ..util.typing import Literal from ..util.typing import Protocol +from ..util.typing import TupleAny from ..util.typing import TypedDict from ..util.typing import Unpack @@ -406,7 +407,7 @@ class _CompilerStackEntry(_BaseCompilerStackEntry, total=False): need_result_map_for_nested: bool need_result_map_for_compound: bool select_0: ReturnsRows - insert_from_select: Select[Unpack[Tuple[Any, ...]]] + insert_from_select: Select[Unpack[TupleAny]] class ExpandedState(NamedTuple): @@ -4787,7 +4788,7 @@ class SQLCompiler(Compiled): return text def _setup_select_hints( - self, select: Select[Unpack[Tuple[Any, ...]]] + self, select: Select[Unpack[TupleAny]] ) -> Tuple[str, _FromHintsType]: byfrom = { from_: hinttext diff --git a/lib/sqlalchemy/sql/dml.py b/lib/sqlalchemy/sql/dml.py index b743924ec0..cf605ae4c7 100644 --- a/lib/sqlalchemy/sql/dml.py +++ b/lib/sqlalchemy/sql/dml.py @@ -65,6 +65,7 @@ from .visitors import InternalTraversal from .. import exc from .. import util from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import TypeGuard from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -963,7 +964,7 @@ class ValuesBase(UpdateBase): _supports_multi_parameters = False - select: Optional[Select[Unpack[Tuple[Any, ...]]]] = None + select: Optional[Select[Unpack[TupleAny]]] = None """SELECT statement for INSERT .. FROM SELECT""" _post_values_clause: Optional[ClauseElement] = None @@ -1838,12 +1839,12 @@ class Delete(DMLWhereBase, UpdateBase): @overload def returning( self, *cols: _ColumnsClauseArgument[Any], **__kw: Any - ) -> ReturningDelete[Unpack[Tuple[Any, ...]]]: + ) -> ReturningDelete[Unpack[TupleAny]]: ... def returning( self, *cols: _ColumnsClauseArgument[Any], **__kw: Any - ) -> ReturningDelete[Unpack[Tuple[Any, ...]]]: + ) -> ReturningDelete[Unpack[TupleAny]]: ... diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index de11f339d0..685ae9c86e 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -78,6 +78,7 @@ from ..util import HasMemoized_ro_memoized_attribute from ..util import TypingOnly from ..util.typing import Literal from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import Unpack if typing.TYPE_CHECKING: @@ -511,7 +512,7 @@ class ClauseElement( connection: Connection, distilled_params: _CoreMultiExecuteParams, execution_options: CoreExecuteOptionsParameter, - ) -> Result[Unpack[typing_Tuple[Any, ...]]]: + ) -> Result[Unpack[TupleAny]]: if self.supports_execution: if TYPE_CHECKING: assert isinstance(self, Executable) @@ -2143,12 +2144,10 @@ class BindParameter(roles.InElementRole, KeyedColumnElement[_T]): else: check_value = value cast( - "BindParameter[typing_Tuple[Any, ...]]", self + "BindParameter[TupleAny]", self ).type = type_._resolve_values_to_types(check_value) else: - cast( - "BindParameter[typing_Tuple[Any, ...]]", self - ).type = type_ + cast("BindParameter[TupleAny]", self).type = type_ else: self.type = type_ @@ -3271,7 +3270,7 @@ and_ = BooleanClauseList.and_ or_ = BooleanClauseList.or_ -class Tuple(ClauseList, ColumnElement[typing_Tuple[Any, ...]]): +class Tuple(ClauseList, ColumnElement[TupleAny]): """Represent a SQL tuple.""" __visit_name__ = "tuple" diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index d841000548..3d070e968f 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -99,6 +99,7 @@ from ..util import HasMemoized_ro_memoized_attribute from ..util.typing import Literal from ..util.typing import Protocol from ..util.typing import Self +from ..util.typing import TupleAny from ..util.typing import TypeVarTuple from ..util.typing import Unpack @@ -614,7 +615,7 @@ class FromClause(roles.AnonymizedFromClauseRole, Selectable): _use_schema_map = False - def select(self) -> Select[Unpack[Tuple[Any, ...]]]: + def select(self) -> Select[Unpack[TupleAny]]: r"""Return a SELECT of this :class:`_expression.FromClause`. @@ -1500,7 +1501,7 @@ class Join(roles.DMLTableRole, FromClause): "join explicitly." % (a.description, b.description) ) - def select(self) -> Select[Unpack[Tuple[Any, ...]]]: + def select(self) -> Select[Unpack[TupleAny]]: r"""Create a :class:`_expression.Select` from this :class:`_expression.Join`. @@ -2056,7 +2057,7 @@ class CTE( def _init( self, - selectable: Select[Unpack[Tuple[Any, ...]]], + selectable: Select[Unpack[TupleAny]], *, name: Optional[str] = None, recursive: bool = False, @@ -4540,14 +4541,14 @@ class SelectState(util.MemoizedSlots, CompileState): @classmethod def from_statement( cls, - statement: Select[Unpack[Tuple[Any, ...]]], + statement: Select[Unpack[TupleAny]], from_statement: roles.ReturnsRowsRole, ) -> ExecutableReturnsRows: cls._plugin_not_implemented() @classmethod def get_columns_clause_froms( - cls, statement: Select[Unpack[Tuple[Any, ...]]] + cls, statement: Select[Unpack[TupleAny]] ) -> List[FromClause]: return cls._normalize_froms( itertools.chain.from_iterable( @@ -4603,7 +4604,7 @@ class SelectState(util.MemoizedSlots, CompileState): return go def _get_froms( - self, statement: Select[Unpack[Tuple[Any, ...]]] + self, statement: Select[Unpack[TupleAny]] ) -> List[FromClause]: ambiguous_table_name_map: _AmbiguousTableNameMap self._ambiguous_table_name_map = ambiguous_table_name_map = {} @@ -4632,7 +4633,7 @@ class SelectState(util.MemoizedSlots, CompileState): def _normalize_froms( cls, iterable_of_froms: Iterable[FromClause], - check_statement: Optional[Select[Unpack[Tuple[Any, ...]]]] = None, + check_statement: Optional[Select[Unpack[TupleAny]]] = None, ambiguous_table_name_map: Optional[_AmbiguousTableNameMap] = None, ) -> List[FromClause]: """given an iterable of things to select FROM, reduce them to what @@ -4777,7 +4778,7 @@ class SelectState(util.MemoizedSlots, CompileState): @classmethod def determine_last_joined_entity( - cls, stmt: Select[Unpack[Tuple[Any, ...]]] + cls, stmt: Select[Unpack[TupleAny]] ) -> Optional[_JoinTargetElement]: if stmt._setup_joins: return stmt._setup_joins[-1][0] @@ -4786,7 +4787,7 @@ class SelectState(util.MemoizedSlots, CompileState): @classmethod def all_selected_columns( - cls, statement: Select[Unpack[Tuple[Any, ...]]] + cls, statement: Select[Unpack[TupleAny]] ) -> _SelectIterable: return [c for c in _select_iterables(statement._raw_columns)] @@ -5034,7 +5035,7 @@ class _MemoizedSelectEntities( @classmethod def _generate_for_statement( - cls, select_stmt: Select[Unpack[Tuple[Any, ...]]] + cls, select_stmt: Select[Unpack[TupleAny]] ) -> None: if select_stmt._setup_joins or select_stmt._with_options: self = _MemoizedSelectEntities() @@ -5128,7 +5129,7 @@ class Select( _compile_state_factory: Type[SelectState] @classmethod - def _create_raw_select(cls, **kw: Any) -> Select[Unpack[Tuple[Any, ...]]]: + def _create_raw_select(cls, **kw: Any) -> Select[Unpack[TupleAny]]: """Create a :class:`.Select` using raw ``__new__`` with no coercions. Used internally to build up :class:`.Select` constructs with @@ -5678,7 +5679,7 @@ class Select( @_generative def add_columns( self, *entities: _ColumnsClauseArgument[Any] - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: r"""Return a new :func:`_expression.select` construct with the given entities appended to its columns clause. @@ -5730,7 +5731,7 @@ class Select( ) def column( self, column: _ColumnsClauseArgument[Any] - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: """Return a new :func:`_expression.select` construct with the given column expression added to its columns clause. @@ -5749,7 +5750,7 @@ class Select( @util.preload_module("sqlalchemy.sql.util") def reduce_columns( self, only_synonyms: bool = True - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: """Return a new :func:`_expression.select` construct with redundantly named, equivalently-valued columns removed from the columns clause. @@ -5772,7 +5773,7 @@ class Select( all columns that are equivalent to another are removed. """ - woc: Select[Unpack[Tuple[Any, ...]]] + woc: Select[Unpack[TupleAny]] woc = self.with_only_columns( *util.preloaded.sql_util.reduce_columns( self._all_selected_columns, @@ -5871,7 +5872,7 @@ class Select( *entities: _ColumnsClauseArgument[Any], maintain_column_froms: bool = False, **__kw: Any, - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: ... @_generative @@ -5880,7 +5881,7 @@ class Select( *entities: _ColumnsClauseArgument[Any], maintain_column_froms: bool = False, **__kw: Any, - ) -> Select[Unpack[Tuple[Any, ...]]]: + ) -> Select[Unpack[TupleAny]]: r"""Return a new :func:`_expression.select` construct with its columns clause replaced with the given entities. @@ -6273,7 +6274,7 @@ class Select( meth = SelectState.get_plugin_class(self).all_selected_columns return list(meth(self)) - def _ensure_disambiguated_names(self) -> Select[Unpack[Tuple[Any, ...]]]: + def _ensure_disambiguated_names(self) -> Select[Unpack[TupleAny]]: if self._label_style is LABEL_STYLE_NONE: self = self.set_label_style(LABEL_STYLE_DISAMBIGUATE_ONLY) return self @@ -6533,9 +6534,9 @@ class ScalarSelect( by this :class:`_expression.ScalarSelect`. """ - self.element = cast( - "Select[Unpack[Tuple[Any, ...]]]", self.element - ).where(crit) + self.element = cast("Select[Unpack[TupleAny]]", self.element).where( + crit + ) return self @overload @@ -6557,7 +6558,7 @@ class ScalarSelect( if TYPE_CHECKING: - def _ungroup(self) -> Select[Unpack[Tuple[Any, ...]]]: + def _ungroup(self) -> Select[Unpack[TupleAny]]: ... @_generative @@ -6592,7 +6593,7 @@ class ScalarSelect( """ self.element = cast( - "Select[Unpack[Tuple[Any, ...]]]", self.element + "Select[Unpack[TupleAny]]", self.element ).correlate(*fromclauses) return self @@ -6630,7 +6631,7 @@ class ScalarSelect( """ self.element = cast( - "Select[Unpack[Tuple[Any, ...]]]", self.element + "Select[Unpack[TupleAny]]", self.element ).correlate_except(*fromclauses) return self @@ -6647,7 +6648,7 @@ class Exists(UnaryExpression[bool]): inherit_cache = True element: Union[ - SelectStatementGrouping[Select[Unpack[Tuple[Any, ...]]]], + SelectStatementGrouping[Select[Unpack[TupleAny]]], ScalarSelect[Any], ] @@ -6685,10 +6686,8 @@ class Exists(UnaryExpression[bool]): def _regroup( self, - fn: Callable[ - [Select[Unpack[Tuple[Any, ...]]]], Select[Unpack[Tuple[Any, ...]]] - ], - ) -> SelectStatementGrouping[Select[Unpack[Tuple[Any, ...]]]]: + fn: Callable[[Select[Unpack[TupleAny]]], Select[Unpack[TupleAny]]], + ) -> SelectStatementGrouping[Select[Unpack[TupleAny]]]: element = self.element._ungroup() new_element = fn(element) @@ -6696,7 +6695,7 @@ class Exists(UnaryExpression[bool]): assert isinstance(return_value, SelectStatementGrouping) return return_value - def select(self) -> Select[Unpack[Tuple[Any, ...]]]: + def select(self) -> Select[Unpack[TupleAny]]: r"""Return a SELECT of this :class:`_expression.Exists`. e.g.:: diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 7e866cc032..55cfb3013d 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -61,6 +61,7 @@ from ..util import langhelpers from ..util import OrderedDict from ..util.typing import is_literal from ..util.typing import Literal +from ..util.typing import TupleAny from ..util.typing import typing_get_args if TYPE_CHECKING: @@ -3162,7 +3163,7 @@ class ARRAY( ) -class TupleType(TypeEngine[Tuple[Any, ...]]): +class TupleType(TypeEngine[TupleAny]): """represent the composite type of a Tuple.""" _is_tuple_type = True diff --git a/lib/sqlalchemy/util/typing.py b/lib/sqlalchemy/util/typing.py index 8f1f493c99..996c53eb13 100644 --- a/lib/sqlalchemy/util/typing.py +++ b/lib/sqlalchemy/util/typing.py @@ -63,6 +63,8 @@ _KT_contra = TypeVar("_KT_contra", contravariant=True) _VT = TypeVar("_VT") _VT_co = TypeVar("_VT_co", covariant=True) +TupleAny = Tuple[Any, ...] + if compat.py310: # why they took until py310 to put this in stdlib is beyond me, diff --git a/tools/normalize_file_headers.py b/tools/normalize_file_headers.py index 8d82f84955..ba4cd5734f 100644 --- a/tools/normalize_file_headers.py +++ b/tools/normalize_file_headers.py @@ -49,7 +49,7 @@ def run_file(cmd: code_writer_cmd, file: Path, update_year: bool): def run(cmd: code_writer_cmd, update_year: bool): i = 0 - for ext in ('py', 'pyx', 'pxd'): + for ext in ("py", "pyx", "pxd"): for file in sa_path.glob(f"**/*.{ext}"): run_file(cmd, file, update_year) i += 1 -- 2.47.3