]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
remove python 3.9 support since it's close to eol
authorFederico Caselli <cfederico87@gmail.com>
Thu, 21 Aug 2025 20:53:15 +0000 (22:53 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Sat, 23 Aug 2025 12:22:57 +0000 (14:22 +0200)
Fixes: #12819
Change-Id: I60f848226c1fef2a769845938d6afa3d3c5d0509

93 files changed:
.github/workflows/create-wheels.yaml
.github/workflows/run-on-pr.yaml
.github/workflows/run-test.yaml
.github/workflows/scripts/can_install.py [deleted file]
doc/build/changelog/unreleased_21/10357.rst [deleted file]
doc/build/changelog/unreleased_21/python_version.rst [new file with mode: 0644]
doc/build/intro.rst
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/dialects/postgresql/asyncpg.py
lib/sqlalchemy/dialects/postgresql/psycopg.py
lib/sqlalchemy/dialects/postgresql/ranges.py
lib/sqlalchemy/engine/create.py
lib/sqlalchemy/engine/cursor.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/engine/events.py
lib/sqlalchemy/engine/interfaces.py
lib/sqlalchemy/engine/result.py
lib/sqlalchemy/event/base.py
lib/sqlalchemy/ext/associationproxy.py
lib/sqlalchemy/ext/asyncio/base.py
lib/sqlalchemy/ext/asyncio/engine.py
lib/sqlalchemy/ext/asyncio/result.py
lib/sqlalchemy/ext/asyncio/session.py
lib/sqlalchemy/ext/hybrid.py
lib/sqlalchemy/inspection.py
lib/sqlalchemy/log.py
lib/sqlalchemy/orm/_orm_constructors.py
lib/sqlalchemy/orm/_typing.py
lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/base.py
lib/sqlalchemy/orm/bulk_persistence.py
lib/sqlalchemy/orm/decl_api.py
lib/sqlalchemy/orm/decl_base.py
lib/sqlalchemy/orm/descriptor_props.py
lib/sqlalchemy/orm/instrumentation.py
lib/sqlalchemy/orm/mapped_collection.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/path_registry.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/orm/relationships.py
lib/sqlalchemy/orm/session.py
lib/sqlalchemy/orm/state.py
lib/sqlalchemy/orm/state_changes.py
lib/sqlalchemy/orm/strategies.py
lib/sqlalchemy/orm/strategy_options.py
lib/sqlalchemy/orm/util.py
lib/sqlalchemy/orm/writeonly.py
lib/sqlalchemy/pool/base.py
lib/sqlalchemy/pool/impl.py
lib/sqlalchemy/sql/_elements_constructors.py
lib/sqlalchemy/sql/_orm_types.py
lib/sqlalchemy/sql/_typing.py
lib/sqlalchemy/sql/_util_cy.py
lib/sqlalchemy/sql/annotation.py
lib/sqlalchemy/sql/base.py
lib/sqlalchemy/sql/cache_key.py
lib/sqlalchemy/sql/coercions.py
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/crud.py
lib/sqlalchemy/sql/dml.py
lib/sqlalchemy/sql/elements.py
lib/sqlalchemy/sql/lambdas.py
lib/sqlalchemy/sql/operators.py
lib/sqlalchemy/sql/roles.py
lib/sqlalchemy/sql/schema.py
lib/sqlalchemy/sql/selectable.py
lib/sqlalchemy/sql/sqltypes.py
lib/sqlalchemy/sql/type_api.py
lib/sqlalchemy/sql/util.py
lib/sqlalchemy/sql/visitors.py
lib/sqlalchemy/testing/engines.py
lib/sqlalchemy/testing/fixtures/mypy.py
lib/sqlalchemy/testing/requirements.py
lib/sqlalchemy/util/__init__.py
lib/sqlalchemy/util/_collections.py
lib/sqlalchemy/util/compat.py
lib/sqlalchemy/util/concurrency.py
lib/sqlalchemy/util/langhelpers.py
lib/sqlalchemy/util/typing.py
pyproject.toml
test/base/test_tutorials.py
test/base/test_typing_utils.py
test/ext/asyncio/test_engine_py3k.py
test/ext/asyncio/test_session_py3k.py
test/ext/test_associationproxy.py
test/orm/declarative/test_dc_transforms.py
test/orm/declarative/test_dc_transforms_future_anno_sync.py
test/orm/declarative/test_mixin.py
test/orm/declarative/test_tm_future_annotations_sync.py
test/orm/declarative/test_typed_mapping.py
test/orm/test_cache_key.py
test/orm/test_deprecations.py

index 6c4d7dd42b5c49ce5a53a07bdcd28c3243a0a89f..ce81123d7c8cf915ca937ada0f30284167b0d95d 100644 (file)
@@ -20,7 +20,6 @@ jobs:
       matrix:
         # emulated wheels on linux take too much time, split wheels into multiple runs
         python:
-          - "cp39-*"
           - "cp310-* cp311-*"
           - "cp312-* cp313-*"
         wheel_mode:
@@ -41,7 +40,7 @@ jobs:
           # create pure python build
           - os: ubuntu-22.04
             wheel_mode: pure-python
-            python: "cp-312*"
+            python: "cp-313*"
 
         exclude:
           - os: "windows-2022"
@@ -93,7 +92,7 @@ jobs:
       - name: Set up Python for twine and pure-python wheel
         uses: actions/setup-python@v5
         with:
-          python-version: "3.12"
+          python-version: "3.13"
 
       - name: Build pure-python wheel
         if: ${{ matrix.wheel_mode == 'pure-python' && runner.os == 'Linux' }}
index 889da8499f3e9f686f9e7204248f8fce01aba146..00cacf48d68774b424aa62b68fdd7afb8373b4d4 100644 (file)
@@ -62,7 +62,7 @@ jobs:
         os:
           - "ubuntu-22.04"
         python-version:
-          - "3.12"
+          - "3.13"
         tox-env:
           - mypy
           - lint
index cd214febd12acd6635ace6984f7b60c66df01c57..9818625603c18d8719326d969cdf1efe2e0f8562 100644 (file)
@@ -33,11 +33,11 @@ jobs:
           - "macos-latest"
           - "macos-13"
         python-version:
-          - "3.9"
           - "3.10"
           - "3.11"
           - "3.12"
           - "3.13"
+          - "3.14.0-alpha - 3.14"
           - "pypy-3.10"
         build-type:
           - "cext"
@@ -71,13 +71,11 @@ jobs:
           # windows des not have arm64 python
           - os: "windows-latest"
             architecture: arm64
-          # macos: latests uses arm macs. only 3.10+; no x86/x64
+          # macos: latests uses arm macs. no x86/x64
           - os: "macos-latest"
             architecture: x86
           - os: "macos-latest"
             architecture: x64
-          - os: "macos-latest"
-            python-version: "3.9"
           # macos 13: uses intel macs. no arm64, x86
           - os: "macos-13"
             architecture: arm64
@@ -96,8 +94,6 @@ jobs:
             python-version: "pypy-3.10"
           - os: "windows-11-arm"
             python-version: "3.10"
-          - os: "windows-11-arm"
-            python-version: "3.9"
           - os: "windows-11-arm"
             architecture: x86
           - os: "windows-11-arm"
@@ -150,9 +146,9 @@ jobs:
           - pep484
 
         include:
-          # run lint only on 3.12
+          # run lint only on 3.13
           - tox-env: lint
-            python-version: "3.12"
+            python-version: "3.13"
             os: "ubuntu-22.04"
 
       fail-fast: false
diff --git a/.github/workflows/scripts/can_install.py b/.github/workflows/scripts/can_install.py
deleted file mode 100644 (file)
index ecb24b5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-import sys
-
-from packaging import tags
-
-to_check = "--"
-found = False
-if len(sys.argv) > 1:
-    to_check = sys.argv[1]
-    for t in tags.sys_tags():
-        start = "-".join(str(t).split("-")[:2])
-        if to_check.lower() == start:
-            print(
-                "Wheel tag {0} matches installed version {1}.".format(
-                    to_check, t
-                )
-            )
-            found = True
-            break
-if not found:
-    print(
-        "Wheel tag {0} not found in installed version tags {1}.".format(
-            to_check, [str(t) for t in tags.sys_tags()]
-        )
-    )
-    exit(1)
diff --git a/doc/build/changelog/unreleased_21/10357.rst b/doc/build/changelog/unreleased_21/10357.rst
deleted file mode 100644 (file)
index 2277267..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.. change::
-    :tags: change, installation
-    :tickets: 10357, 12029
-
-    Python 3.9 or above is now required; support for Python 3.8 and 3.7 is
-    dropped as these versions are EOL.
diff --git a/doc/build/changelog/unreleased_21/python_version.rst b/doc/build/changelog/unreleased_21/python_version.rst
new file mode 100644 (file)
index 0000000..e936563
--- /dev/null
@@ -0,0 +1,6 @@
+.. change::
+    :tags: change, installation
+    :tickets: 10357, 12029, 12819
+
+    Python 3.10 or above is now required; support for Python 3.9, 3.8 and 3.7
+    is dropped as these versions are EOL.
index cba95ab69e78f33764a864ec2e107b4a89b56c62..2c68b5489a957eac5e46b6b737664c3c6fc4e84f 100644 (file)
@@ -96,11 +96,11 @@ Supported Platforms
 
 SQLAlchemy 2.1 supports the following platforms:
 
-* cPython 3.9 and higher
+* cPython 3.10 and higher
 * Python-3 compatible versions of `PyPy <http://pypy.org/>`_
 
 .. versionchanged:: 2.1
-   SQLAlchemy now targets Python 3.9 and above.
+   SQLAlchemy now targets Python 3.10 and above.
 
 
 Supported Installation Methods
index c0bf43304af4fa94ff9cb9fded0a67d2d9f293a3..b655c214dad676e4522c76df118e4cbeaca5123b 100644 (file)
@@ -963,6 +963,7 @@ import codecs
 import datetime
 import operator
 import re
+from typing import Literal
 from typing import overload
 from typing import TYPE_CHECKING
 from uuid import UUID as _python_UUID
@@ -1010,7 +1011,6 @@ from ...types import SMALLINT
 from ...types import TEXT
 from ...types import VARCHAR
 from ...util import update_wrapper
-from ...util.typing import Literal
 
 if TYPE_CHECKING:
     from ...sql.dml import DMLState
index 09ff9f48c087a55c7f60b71566acd91cc753b16c..1f11984eaf419f21a324e60346ce5906ee789c43 100644 (file)
@@ -184,6 +184,7 @@ import decimal
 import json as _py_json
 import re
 import time
+from types import NoneType
 from typing import Any
 from typing import Awaitable
 from typing import Callable
@@ -435,8 +436,6 @@ class _AsyncpgMultiRange(ranges.AbstractMultiRangeImpl):
     def bind_processor(self, dialect):
         asyncpg_Range = dialect.dbapi.asyncpg.Range
 
-        NoneType = type(None)
-
         def to_range(value):
             if isinstance(value, (str, NoneType)):
                 return value
index 7ad63a2fd3c96936cc17f0c0455cb7ef7898dac5..966195752d0e9b213388d966d5e1e17904676b1e 100644 (file)
@@ -97,6 +97,7 @@ from __future__ import annotations
 import collections
 import logging
 import re
+from types import NoneType
 from typing import cast
 from typing import TYPE_CHECKING
 
@@ -236,8 +237,6 @@ class _PsycopgMultiRange(ranges.AbstractMultiRangeImpl):
             PGDialect_psycopg, dialect
         )._psycopg_Multirange
 
-        NoneType = type(None)
-
         def to_range(value):
             if isinstance(value, (str, NoneType, psycopg_Multirange)):
                 return value
index 0ce4ea29137ed2b93f21008428e08dde035b2f7f..ea25ed5caf86e2ce4281a4649c976b9cc630b396 100644 (file)
@@ -16,6 +16,7 @@ from typing import Any
 from typing import cast
 from typing import Generic
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Sequence
@@ -36,8 +37,6 @@ from .operators import STRICTLY_RIGHT_OF
 from ... import types as sqltypes
 from ...sql import operators
 from ...sql.type_api import TypeEngine
-from ...util import py310
-from ...util.typing import Literal
 
 if TYPE_CHECKING:
     from ...sql.elements import ColumnElement
@@ -48,15 +47,8 @@ _T = TypeVar("_T", bound=Any)
 
 _BoundsType = Literal["()", "[)", "(]", "[]"]
 
-if py310:
-    dc_slots = {"slots": True}
-    dc_kwonly = {"kw_only": True}
-else:
-    dc_slots = {}
-    dc_kwonly = {}
 
-
-@dataclasses.dataclass(frozen=True, **dc_slots)
+@dataclasses.dataclass(frozen=True, slots=True)
 class Range(Generic[_T]):
     """Represent a PostgreSQL range.
 
@@ -85,32 +77,8 @@ class Range(Generic[_T]):
     upper: Optional[_T] = None
     """the upper bound"""
 
-    if TYPE_CHECKING:
-        bounds: _BoundsType = dataclasses.field(default="[)")
-        empty: bool = dataclasses.field(default=False)
-    else:
-        bounds: _BoundsType = dataclasses.field(default="[)", **dc_kwonly)
-        empty: bool = dataclasses.field(default=False, **dc_kwonly)
-
-    if not py310:
-
-        def __init__(
-            self,
-            lower: Optional[_T] = None,
-            upper: Optional[_T] = None,
-            *,
-            bounds: _BoundsType = "[)",
-            empty: bool = False,
-        ):
-            # no __slots__ either so we can update dict
-            self.__dict__.update(
-                {
-                    "lower": lower,
-                    "upper": upper,
-                    "bounds": bounds,
-                    "empty": empty,
-                }
-            )
+    bounds: _BoundsType = dataclasses.field(default="[)", kw_only=True)
+    empty: bool = dataclasses.field(default=False, kw_only=True)
 
     def __bool__(self) -> bool:
         return not self.empty
index d2bf7702c705c41c2a4511916e1d0945888c9fae..948a3d72b3b053ebe02907c72547d91a91dd6fac 100644 (file)
@@ -32,6 +32,8 @@ from ..sql import compiler
 from ..util import immutabledict
 
 if typing.TYPE_CHECKING:
+    from typing import Literal
+
     from .base import Engine
     from .interfaces import _ExecuteOptions
     from .interfaces import _ParamStyle
@@ -42,7 +44,6 @@ if typing.TYPE_CHECKING:
     from ..pool import _CreatorWRecFnType
     from ..pool import _ResetStyleArgType
     from ..pool import Pool
-    from ..util.typing import Literal
 
 
 @overload
index 165ae2feaa2e79c2ac430035ab0dbf0db780345a..35d8180ac049a5325208a2c1cb45387179f9c2d9 100644 (file)
@@ -23,6 +23,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -50,7 +51,6 @@ from ..sql.compiler import RM_OBJECTS
 from ..sql.compiler import RM_RENDERED_NAME
 from ..sql.compiler import RM_TYPE
 from ..sql.type_api import TypeEngine
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import TypeVarTuple
index c624cece19dd44abaa2dbdc17bd6adf983b3937e..fcdb68093a44480c616d7e7a1e6b9d76dbf32bf6 100644 (file)
@@ -28,6 +28,7 @@ from typing import cast
 from typing import Dict
 from typing import Final
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import MutableMapping
 from typing import MutableSequence
@@ -66,7 +67,6 @@ from ..sql.compiler import DDLCompiler
 from ..sql.compiler import InsertmanyvaluesSentinelOpts
 from ..sql.compiler import SQLCompiler
 from ..sql.elements import quoted_name
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
 
index fab3cb3040cbff504743d031c0fe6c3d4f0f2e8e..d5c809439cfaf1749ba4d8d07e709c1d673279a4 100644 (file)
@@ -11,6 +11,7 @@ from __future__ import annotations
 import typing
 from typing import Any
 from typing import Dict
+from typing import Literal
 from typing import Optional
 from typing import Tuple
 from typing import Type
@@ -24,7 +25,6 @@ from .interfaces import DBAPICursor
 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
 
index 5d7f5c97859fa43294bae449bd2c97340b63ecaa..0c998996a16cc9efed62eed95d961be493c80a03 100644 (file)
@@ -19,6 +19,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import MutableMapping
 from typing import Optional
@@ -42,7 +43,6 @@ from ..sql.compiler import TypeCompiler as TypeCompiler
 from ..sql.compiler import TypeCompiler  # noqa
 from ..util import immutabledict
 from ..util.concurrency import await_
-from ..util.typing import Literal
 from ..util.typing import NotRequired
 
 if TYPE_CHECKING:
index 7c72f288f6b517f407775c768442d7de6bb12165..844db160f6a5c4700019cdcc958afa50023f2ddc 100644 (file)
@@ -22,6 +22,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -44,7 +45,6 @@ from ..sql.base import InPlaceGenerative
 from ..util import deprecated
 from ..util import HasMemoized_ro_memoized_attribute
 from ..util import NONE_SET
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import TypeVarTuple
index 66dc12996bc04e36fec189c783ddde18cdd3b959..e1251cb45c2cc0e8cd3b176571523f3fd8c14f8a 100644 (file)
@@ -24,6 +24,7 @@ from typing import Dict
 from typing import Generic
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import MutableMapping
 from typing import Optional
@@ -40,7 +41,6 @@ from .attr import _JoinedListener
 from .registry import _ET
 from .registry import _EventKey
 from .. import util
-from ..util.typing import Literal
 
 _registrars: MutableMapping[str, List[Type[_HasEventsDispatch[Any]]]] = (
     util.defaultdict(list)
index 22d2bb570d76d72e9e511588a92d09fcb481a891..f7bb0f994c31c4840eb9d9deb64ee789e593354c 100644 (file)
@@ -29,6 +29,7 @@ from typing import Iterable
 from typing import Iterator
 from typing import KeysView
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import MutableMapping
 from typing import MutableSequence
@@ -61,7 +62,6 @@ from ..orm.interfaces import _DEFAULT_ATTRIBUTE_OPTIONS
 from ..sql import operators
 from ..sql import or_
 from ..sql.base import _NoArg
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import SupportsKeysAndGetItem
 
index 72a617f4e227784884609eb0b03e7e9657a6714f..cc22950a5764e9a569b1b6005dd867e4b16bf89b 100644 (file)
@@ -18,6 +18,7 @@ from typing import ClassVar
 from typing import Dict
 from typing import Generator
 from typing import Generic
+from typing import Literal
 from typing import NoReturn
 from typing import Optional
 from typing import overload
@@ -27,7 +28,6 @@ import weakref
 
 from . import exc as async_exc
 from ... import util
-from ...util.typing import Literal
 from ...util.typing import Self
 
 _T = TypeVar("_T", bound=Any)
@@ -148,7 +148,7 @@ class GeneratorStartableContext(StartableContext[_T_co]):
 
     async def start(self, is_ctxmanager: bool = False) -> _T_co:
         try:
-            start_value = await util.anext_(self.gen)
+            start_value = await anext(self.gen)
         except StopAsyncIteration:
             raise RuntimeError("generator didn't yield") from None
 
@@ -167,7 +167,7 @@ class GeneratorStartableContext(StartableContext[_T_co]):
         # vendored from contextlib.py
         if typ is None:
             try:
-                await util.anext_(self.gen)
+                await anext(self.gen)
             except StopAsyncIteration:
                 return False
             else:
index a33911321003dd53e083e66f1b77110f8e6ef76b..5f5ec6cf350531b6dc6ff137cca8e34e36a9d401 100644 (file)
@@ -11,11 +11,13 @@ import contextlib
 from typing import Any
 from typing import AsyncIterator
 from typing import Callable
+from typing import Concatenate
 from typing import Dict
 from typing import Generator
 from typing import NoReturn
 from typing import Optional
 from typing import overload
+from typing import ParamSpec
 from typing import Type
 from typing import TYPE_CHECKING
 from typing import TypeVar
@@ -40,8 +42,6 @@ from ...engine.base import NestedTransaction
 from ...engine.base import Transaction
 from ...exc import ArgumentError
 from ...util.concurrency import greenlet_spawn
-from ...util.typing import Concatenate
-from ...util.typing import ParamSpec
 from ...util.typing import TupleAny
 from ...util.typing import TypeVarTuple
 from ...util.typing import Unpack
index 970bb791bca93f2d5f3515fa67459d61902576c1..2e2efebb5ab0a890077f193a886e394bcbd01230 100644 (file)
@@ -9,6 +9,7 @@ from __future__ import annotations
 import operator
 from typing import Any
 from typing import AsyncIterator
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Sequence
@@ -30,7 +31,6 @@ from ...engine.row import RowMapping
 from ...sql.base import _generative
 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
index 77c7b6edae647cbe98786866e91e964c47123733..58958b7f105407ed31937a79af36620ac292350c 100644 (file)
@@ -11,6 +11,7 @@ from typing import Any
 from typing import Awaitable
 from typing import Callable
 from typing import cast
+from typing import Concatenate
 from typing import Dict
 from typing import Generic
 from typing import Iterable
@@ -18,6 +19,7 @@ from typing import Iterator
 from typing import NoReturn
 from typing import Optional
 from typing import overload
+from typing import ParamSpec
 from typing import Sequence
 from typing import Tuple
 from typing import Type
@@ -38,8 +40,6 @@ from ...orm import Session
 from ...orm import SessionTransaction
 from ...orm import state as _instance_state
 from ...util.concurrency import greenlet_spawn
-from ...util.typing import Concatenate
-from ...util.typing import ParamSpec
 from ...util.typing import TupleAny
 from ...util.typing import TypeVarTuple
 from ...util.typing import Unpack
index 840a3f06503e2e43efcfa2b33b3be641c75384c1..58b5a80bb610ed2a0d8421f8ce42c2c40d96f098 100644 (file)
@@ -1146,11 +1146,14 @@ from __future__ import annotations
 from typing import Any
 from typing import Callable
 from typing import cast
+from typing import Concatenate
 from typing import Generic
 from typing import List
+from typing import Literal
 from typing import MutableMapping
 from typing import Optional
 from typing import overload
+from typing import ParamSpec
 from typing import Protocol
 from typing import Sequence
 from typing import Tuple
@@ -1170,9 +1173,6 @@ from ..sql import roles
 from ..sql._typing import is_has_clause_element
 from ..sql.elements import ColumnElement
 from ..sql.elements import SQLCoreOperations
-from ..util.typing import Concatenate
-from ..util.typing import Literal
-from ..util.typing import ParamSpec
 from ..util.typing import Self
 
 if TYPE_CHECKING:
index 71911671660f9a3eb8908ad8730e933c2e46f909..04adc826936b745686213aa50eee7bd9b3354bf9 100644 (file)
@@ -34,6 +34,7 @@ from typing import Any
 from typing import Callable
 from typing import Dict
 from typing import Generic
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Protocol
@@ -42,7 +43,6 @@ from typing import TypeVar
 from typing import Union
 
 from . import exc
-from .util.typing import Literal
 
 _T = TypeVar("_T", bound=Any)
 _TCov = TypeVar("_TCov", bound=Any, covariant=True)
index b9627d879c0cabc8da7bfdc5aebcc0310af13949..4e676239b74452adf375edc99dacaed0046e4943 100644 (file)
@@ -22,6 +22,7 @@ from __future__ import annotations
 import logging
 import sys
 from typing import Any
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Set
@@ -30,7 +31,6 @@ from typing import TypeVar
 from typing import Union
 
 from .util import py311
-from .util.typing import Literal
 
 
 STACKLEVEL = True
index bcd21fc964951ca010a50a8061d6fc95ecd67f28..1bc9f17035178b5dfe69ac04a96f562d1a3dcec9 100644 (file)
@@ -8,10 +8,12 @@
 from __future__ import annotations
 
 import typing
+from typing import Annotated
 from typing import Any
 from typing import Callable
 from typing import Collection
 from typing import Iterable
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -47,8 +49,6 @@ from ..sql.base import SchemaEventTarget
 from ..sql.schema import _InsertSentinelColumnDefault
 from ..sql.schema import SchemaConst
 from ..sql.selectable import FromClause
-from ..util.typing import Annotated
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from ._typing import _EntityType
index 8cf5335d67dad18af6daef5d4f60f0727681a7c3..80f4cb1448c4d4e2493011fde4808a9ea4aed9d8 100644 (file)
@@ -16,6 +16,7 @@ from typing import Protocol
 from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -27,7 +28,6 @@ from ..sql._orm_types import (
 )
 from ..sql._typing import _HasClauseElement
 from ..sql.elements import ColumnElement
-from ..util.typing import TypeGuard
 
 if TYPE_CHECKING:
     from .attributes import _AttributeImpl
index 46462049ccd98f48ad7a00d5f8222ee84f50b0b7..4cff73851e16635f6cf611a1e0149184bad19d47 100644 (file)
@@ -26,6 +26,7 @@ from typing import ClassVar
 from typing import Dict
 from typing import Iterable
 from typing import List
+from typing import Literal
 from typing import NamedTuple
 from typing import Optional
 from typing import overload
@@ -33,6 +34,7 @@ from typing import Sequence
 from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -90,9 +92,7 @@ from ..sql import visitors
 from ..sql.cache_key import HasCacheKey
 from ..sql.visitors import _TraverseInternalsType
 from ..sql.visitors import InternalTraversal
-from ..util.typing import Literal
 from ..util.typing import Self
-from ..util.typing import TypeGuard
 
 if TYPE_CHECKING:
     from ._typing import _EntityType
index c53ba4434582565b9e1d2e0412037a18e144ab9b..32307222f7665a79c45f2e73646a290d1ce8b234 100644 (file)
@@ -16,6 +16,7 @@ from typing import Any
 from typing import Callable
 from typing import Dict
 from typing import Generic
+from typing import Literal
 from typing import no_type_check
 from typing import Optional
 from typing import overload
@@ -35,7 +36,6 @@ from ..sql.elements import SQLColumnExpression
 from ..sql.elements import SQLCoreOperations
 from ..util import FastIntFlag
 from ..util.langhelpers import TypingOnly
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     from ._typing import _EntityType
index 8e813d667a3ee2188de02ce9e69157fb89aca1f2..99b97ccf4ca3c1e977f34198d35f06dc6d75385f 100644 (file)
@@ -18,6 +18,7 @@ from typing import Any
 from typing import cast
 from typing import Dict
 from typing import Iterable
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import TYPE_CHECKING
@@ -53,7 +54,6 @@ from ..sql.dml import DeleteDMLState
 from ..sql.dml import InsertDMLState
 from ..sql.dml import UpdateDMLState
 from ..util import EMPTY_DICT
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
 
index 6239263bd39b5840c3ceab765234295aa8222868..b99906ed61bd5d1e2d98b3dc36198687666e560a 100644 (file)
@@ -19,6 +19,7 @@ from typing import FrozenSet
 from typing import Generic
 from typing import Iterable
 from typing import Iterator
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -74,7 +75,6 @@ from ..util.typing import CallableReference
 from ..util.typing import de_optionalize_union_types
 from ..util.typing import is_generic
 from ..util.typing import is_literal
-from ..util.typing import Literal
 from ..util.typing import LITERAL_TYPES
 from ..util.typing import Self
 
index 9d9538bdf07cd902ac56f0e0394435e1fdd6278f..5d110e969b779b83e44ba600b87c921b25f7557d 100644 (file)
@@ -16,6 +16,7 @@ from typing import Any
 from typing import Callable
 from typing import cast
 from typing import Dict
+from typing import get_args
 from typing import Iterable
 from typing import List
 from typing import Mapping
@@ -67,7 +68,6 @@ from ..sql.schema import Column
 from ..sql.schema import Table
 from ..util import topological
 from ..util.typing import _AnnotationScanType
-from ..util.typing import get_args
 from ..util.typing import is_fwd_ref
 from ..util.typing import is_literal
 
index 62cb5afc7c0eb0831db423521b6e8e852bf375b1..99e9b4ddb1695b1324968c8957d05ad4f866b7de 100644 (file)
@@ -20,6 +20,7 @@ import typing
 from typing import Any
 from typing import Callable
 from typing import Dict
+from typing import get_args
 from typing import List
 from typing import NoReturn
 from typing import Optional
@@ -55,7 +56,6 @@ from ..sql import expression
 from ..sql import operators
 from ..sql.base import _NoArg
 from ..sql.elements import BindParameter
-from ..util.typing import get_args
 from ..util.typing import is_fwd_ref
 from ..util.typing import is_pep593
 from ..util.typing import TupleAny
index c95d0a06737e101f6b1b8ff9d921cd7ac7a3e3f9..6e3a218cfd298185ccb2e708aa145ea1ea85ed42 100644 (file)
@@ -34,6 +34,7 @@ from typing import Dict
 from typing import Generic
 from typing import Iterable
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import Protocol
 from typing import Set
@@ -54,7 +55,6 @@ from .attributes import _is_collection_attribute_impl
 from .. import util
 from ..event import EventTarget
 from ..util import HasMemoized
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from ._typing import _RegistryType
index ca085c4037675e445b30725c2192c5c49cc29b13..a5885fc9d03caa9c370543b224beeecb08585a5c 100644 (file)
@@ -13,6 +13,7 @@ from typing import Callable
 from typing import Dict
 from typing import Generic
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import Sequence
 from typing import Tuple
@@ -31,7 +32,6 @@ from ..sql import expression
 from ..sql import roles
 from ..util.langhelpers import Missing
 from ..util.langhelpers import MissingOr
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from . import AttributeEventToken
index 9bc5cc055d2a333010c8ecf9a8ed0e1aa1903000..33d6646b35a91a24b00a788d5fd6727560466fd2 100644 (file)
@@ -33,6 +33,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import Sequence
@@ -88,7 +89,6 @@ from ..sql.schema import Table
 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
 
index d9e02268632633b46c426d4f831273de20fb69eb..ff6a2dff2149c756d83a5991992490a935d7c998 100644 (file)
@@ -32,6 +32,8 @@ from ..sql import visitors
 from ..sql.cache_key import HasCacheKey
 
 if TYPE_CHECKING:
+    from typing import TypeGuard
+
     from ._typing import _InternalEntityType
     from .interfaces import StrategizedProperty
     from .mapper import Mapper
@@ -41,7 +43,6 @@ if TYPE_CHECKING:
     from ..sql.elements import BindParameter
     from ..sql.visitors import anon_map
     from ..util.typing import _LiteralStar
-    from ..util.typing import TypeGuard
 
     def is_root(path: PathRegistry) -> TypeGuard[RootRegistry]: ...
 
index bc0c8fdda3238ab114d4c01db5c8ede21ba6eb17..5c5cac7ff41f5744d952753d643b1ee3c098a7c8 100644 (file)
@@ -17,6 +17,7 @@ from __future__ import annotations
 from typing import Any
 from typing import cast
 from typing import Dict
+from typing import get_args
 from typing import List
 from typing import Optional
 from typing import Sequence
@@ -56,7 +57,6 @@ from ..sql.schema import Column
 from ..sql.schema import SchemaConst
 from ..sql.type_api import TypeEngine
 from ..util.typing import de_optionalize_union_types
-from ..util.typing import get_args
 from ..util.typing import includes_none
 from ..util.typing import is_a_type
 from ..util.typing import is_fwd_ref
index c5a9fe9ddc4d6827c7381e2f0ef784831b524934..2eb2c5e008f23520219145bb928d3e5e370370f5 100644 (file)
@@ -30,6 +30,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -92,7 +93,6 @@ from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
 from ..sql.selectable import SelectLabelStyle
 from ..util import deprecated
 from ..util import warn_deprecated
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import TypeVarTuple
index eba022685c872a8c8a84bf6dc779860cb5ca09de..b608c520160868bb6853bef5cdeb708a6cff8f69 100644 (file)
@@ -32,6 +32,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import NamedTuple
 from typing import NoReturn
 from typing import Optional
@@ -94,7 +95,6 @@ from ..sql.util import join_condition
 from ..sql.util import selectables_overlap
 from ..sql.util import visit_binary_product
 from ..util.typing import de_optionalize_union_types
-from ..util.typing import Literal
 from ..util.typing import resolve_name_to_real_class_name
 
 if typing.TYPE_CHECKING:
index e4383c21cfbaea2bb3bf6301d5b38a139d04a77c..8c9a0daee8dcb66dbe7b0746b030491b8f66a9b6 100644 (file)
@@ -22,6 +22,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import NoReturn
 from typing import Optional
 from typing import overload
@@ -91,7 +92,6 @@ from ..sql.selectable import ForUpdateArg
 from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
 from ..util import deprecated_params
 from ..util import IdentitySet
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 from ..util.typing import TypeVarTuple
 from ..util.typing import Unpack
index 0f879f3d1e38d0049e2451b19093600c784cbb1c..34575c56b849bb11db5fc17309e3802682bcbb53 100644 (file)
@@ -19,6 +19,7 @@ from typing import Callable
 from typing import Dict
 from typing import Generic
 from typing import Iterable
+from typing import Literal
 from typing import Optional
 from typing import Protocol
 from typing import Set
@@ -45,7 +46,6 @@ from .path_registry import PathRegistry
 from .. import exc as sa_exc
 from .. import inspection
 from .. import util
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
 
index a79874e1c7a0341c21340fb6eb5e5fbb0cf2dbf2..c39fbaf90a28d30f8acb3a4f3458d5a09bc4e78e 100644 (file)
@@ -15,6 +15,7 @@ from typing import Any
 from typing import Callable
 from typing import cast
 from typing import Iterator
+from typing import Literal
 from typing import NoReturn
 from typing import Optional
 from typing import Tuple
@@ -23,7 +24,6 @@ from typing import Union
 
 from .. import exc as sa_exc
 from .. import util
-from ..util.typing import Literal
 
 _F = TypeVar("_F", bound=Callable[..., Any])
 
index 8e67973e4baec966102c168d0c93b8dabbd4ce24..392ba671e95774285ca54273bb2f895a7c0625a7 100644 (file)
@@ -16,6 +16,7 @@ import collections
 import itertools
 from typing import Any
 from typing import Dict
+from typing import Literal
 from typing import Optional
 from typing import Tuple
 from typing import TYPE_CHECKING
@@ -59,7 +60,6 @@ from ..sql import util as sql_util
 from ..sql import visitors
 from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
 from ..sql.selectable import Select
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from .mapper import Mapper
index d41eaec0b2b9c0aff23898c9e001f28360a3ffb8..96d2024e52ca8b9507a6eee8e9a22d60f7bf68da 100644 (file)
@@ -17,6 +17,7 @@ from typing import cast
 from typing import Dict
 from typing import Final
 from typing import Iterable
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Sequence
@@ -52,7 +53,6 @@ from ..sql import roles
 from ..sql import traversals
 from ..sql import visitors
 from ..sql.base import _generative
-from ..util.typing import Literal
 from ..util.typing import Self
 
 _RELATIONSHIP_TOKEN: Final[Literal["relationship"]] = "relationship"
index eb8472993addd71c26e65e62fe077dca4d9b3b88..29f77bca8fbdb55e7d3028999fbd03aca1833ae7 100644 (file)
@@ -20,9 +20,11 @@ from typing import cast
 from typing import Dict
 from typing import FrozenSet
 from typing import Generic
+from typing import get_origin
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Match
 from typing import Optional
 from typing import Protocol
@@ -90,9 +92,7 @@ from ..util.langhelpers import MemoizedSlots
 from ..util.typing import de_stringify_annotation as _de_stringify_annotation
 from ..util.typing import eval_name_only as _eval_name_only
 from ..util.typing import fixup_container_fwd_refs
-from ..util.typing import get_origin
 from ..util.typing import is_origin_of_cls
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
 
index 347d0d92da9f6dbcaeefc0d701694c0086a4ef9d..1343a74bfe15a3fc5e157ad75e16848053b0c816 100644 (file)
@@ -25,6 +25,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import NoReturn
 from typing import Optional
 from typing import overload
@@ -55,7 +56,6 @@ from ..sql import update
 from ..sql.dml import Delete
 from ..sql.dml import Insert
 from ..sql.dml import Update
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from . import QueryableAttribute
index e25e000f01f9306be91b66d348d4515b0e282b1f..5e73ccd9c9e72544d6c5dbb9e6f1eff1201cb44f 100644 (file)
@@ -22,6 +22,7 @@ from typing import cast
 from typing import Deque
 from typing import Dict
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import Protocol
 from typing import Tuple
@@ -33,7 +34,6 @@ from .. import event
 from .. import exc
 from .. import log
 from .. import util
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from ..engine.interfaces import DBAPIConnection
index d57a2dee46738683f5c07047fa0b4addbe998aaa..af39bba1700555d05391b0f7969fb692c41db94f 100644 (file)
@@ -15,6 +15,7 @@ import typing
 from typing import Any
 from typing import cast
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import Set
 from typing import Type
@@ -34,7 +35,6 @@ from .. import exc
 from .. import util
 from ..util import chop_traceback
 from ..util import queue as sqla_queue
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     from ..engine.interfaces import DBAPIConnection
index 7fe4abb5456ce96addcbfc4b4d1df276f5fed6d6..8e3a718221b375e7fee5a552d384b89fbcf898e4 100644 (file)
@@ -10,6 +10,7 @@ from __future__ import annotations
 import typing
 from typing import Any
 from typing import Callable
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -46,7 +47,6 @@ from .elements import TypeCoerce
 from .elements import UnaryExpression
 from .elements import WithinGroup
 from .functions import FunctionElement
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     from ._typing import _ByArgument
index c37d805ef3fb52ec2735d5431e9613eb30c94220..142e9f501a249964f5880328ae9662446ef0f311 100644 (file)
@@ -14,7 +14,7 @@ are meaningful to the ORM.
 
 from __future__ import annotations
 
-from ..util.typing import Literal
+from typing import Literal
 
 SynchronizeSessionArgument = Literal[False, "auto", "evaluate", "fetch"]
 DMLStrategyArgument = Literal["bulk", "raw", "orm", "auto"]
index 71f54a63f1c4182cccda5395d2f7630e8bf0dec0..b4af798dbd92e06722a6a59db6fa5b8a2cf20fac 100644 (file)
@@ -13,6 +13,7 @@ from typing import Callable
 from typing import Dict
 from typing import Generic
 from typing import Iterable
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -21,6 +22,7 @@ from typing import Protocol
 from typing import Set
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeAlias
 from typing import TypeVar
 from typing import Union
 
@@ -28,9 +30,7 @@ from . import roles
 from .. import exc
 from .. import util
 from ..inspection import Inspectable
-from ..util.typing import Literal
 from ..util.typing import TupleAny
-from ..util.typing import TypeAlias
 from ..util.typing import TypeVarTuple
 from ..util.typing import Unpack
 
@@ -40,6 +40,7 @@ if TYPE_CHECKING:
     from datetime import time
     from datetime import timedelta
     from decimal import Decimal
+    from typing import TypeGuard
     from uuid import UUID
 
     from .base import Executable
@@ -76,7 +77,6 @@ if TYPE_CHECKING:
     from ..engine import Dialect
     from ..engine import Engine
     from ..engine.mock import MockConnection
-    from ..util.typing import TypeGuard
 
 _T = TypeVar("_T", bound=Any)
 _T_co = TypeVar("_T_co", bound=Any, covariant=True)
index c8d303d3591a75afb10ce00ac924bdbc4f3a5eb1..8d4ef542b97c04647eb7d558ae387583040e3b39 100644 (file)
@@ -8,12 +8,11 @@
 from __future__ import annotations
 
 from typing import Dict
+from typing import Literal
 from typing import Tuple
 from typing import TYPE_CHECKING
 from typing import Union
 
-from ..util.typing import Literal
-
 if TYPE_CHECKING:
     from .cache_key import CacheConst
 
index 0fb2390c11ee77118fd09f2999eba791399d1081..74b0467ebdd5aad1fc477112c6c15c825c90bafb 100644 (file)
@@ -24,6 +24,7 @@ from typing import Callable
 from typing import cast
 from typing import Dict
 from typing import FrozenSet
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -39,7 +40,6 @@ from .visitors import anon_map
 from .visitors import ExternallyTraversible
 from .visitors import InternalTraversal
 from .. import util
-from ..util.typing import Literal
 from ..util.typing import Self
 
 if TYPE_CHECKING:
index b016c291b0794ae10860ed288046f42049a0cc34..7a5a40d846d26330e3eed09470c6f1f312c881b4 100644 (file)
@@ -40,6 +40,7 @@ from typing import Set
 from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -58,7 +59,6 @@ from .. import util
 from ..util import HasMemoized as HasMemoized
 from ..util import hybridmethod
 from ..util.typing import Self
-from ..util.typing import TypeGuard
 from ..util.typing import TypeVarTuple
 from ..util.typing import Unpack
 
index c8fa20569175a7dd897e32a62fc5bbfcbb846628..f44ca268863e5df2cb609fe75fd7bcc90240ecd6 100644 (file)
@@ -16,6 +16,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import MutableMapping
 from typing import NamedTuple
 from typing import Optional
@@ -32,7 +33,6 @@ from .visitors import prefix_anon_map
 from .. import util
 from ..inspection import inspect
 from ..util import HasMemoized
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     from .elements import BindParameter
index 5cb74948bd4155d8f8de6ff9e59a872eecbf1b7a..c967ab0c9873c56347a63ab9831334ae8c46c729 100644 (file)
@@ -19,6 +19,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import NoReturn
 from typing import Optional
 from typing import overload
@@ -39,7 +40,6 @@ from .visitors import Visitable
 from .. import exc
 from .. import inspection
 from .. import util
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     # elements lambdas schema selectable are set by __init__
index eb457dd410b1d03a3fa27f2d989f334fbc86ed7f..bf1112536932122f78cae365ac5ad73f4dfac4eb 100644 (file)
@@ -44,6 +44,7 @@ from typing import FrozenSet
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import MutableMapping
 from typing import NamedTuple
@@ -83,7 +84,6 @@ from .visitors import prefix_anon_map
 from .. import exc
 from .. import util
 from ..util import FastIntFlag
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
index 51bede81fd0e91efb603379bc6e5dce08545c135..bb63a41e728f78d74567412aacd9d0735f15f131 100644 (file)
@@ -21,6 +21,7 @@ from typing import cast
 from typing import Dict
 from typing import Iterable
 from typing import List
+from typing import Literal
 from typing import MutableMapping
 from typing import NamedTuple
 from typing import Optional
@@ -44,7 +45,6 @@ from .selectable import Select
 from .selectable import TableClause
 from .. import exc
 from .. import util
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from .compiler import _BindNameForColProtocol
index 73e61de65d9a27a91dc3263e278b9d05de4e46e3..99d983b88ae536f29035b0fe69b011a92b08ed22 100644 (file)
@@ -28,6 +28,7 @@ from typing import Set
 from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -71,7 +72,6 @@ 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
 
index 88e4f68999f931f61fca15629b3ad3efd617c55e..6d24d15da22d6d55dd946d494e2cf81e2508dd85 100644 (file)
@@ -29,9 +29,11 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
+from typing import ParamSpec
 from typing import Sequence
 from typing import Set
 from typing import Tuple as typing_Tuple
@@ -76,8 +78,6 @@ from .. import inspection
 from .. import util
 from ..util import HasMemoized_ro_memoized_attribute
 from ..util import TypingOnly
-from ..util.typing import Literal
-from ..util.typing import ParamSpec
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
index 21c69fed5af1743141eee921513eff253081f4ba..731f7e5932069d278a6b78b8ec86d2f3319be4a4 100644 (file)
@@ -19,6 +19,7 @@ from typing import Any
 from typing import Callable
 from typing import cast
 from typing import List
+from typing import Literal
 from typing import MutableMapping
 from typing import Optional
 from typing import Tuple
@@ -42,7 +43,6 @@ from .operators import ColumnOperators
 from .. import exc
 from .. import inspection
 from .. import util
-from ..util.typing import Literal
 
 
 if TYPE_CHECKING:
index 7e751e13d08d5aa7f41292867ce15af6ad81b986..00f885a084542486b4f6e445a31943571746ac0f 100644 (file)
@@ -41,6 +41,7 @@ from typing import Callable
 from typing import cast
 from typing import Dict
 from typing import Generic
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Protocol
@@ -53,7 +54,6 @@ from typing import Union
 
 from .. import exc
 from .. import util
-from ..util.typing import Literal
 
 if typing.TYPE_CHECKING:
     from ._typing import ColumnExpressionArgument
index 99f9fc231c44c126eda774c094bdd3d21dfb3af0..5a23d0d4d9d9acf64dbab1a55cb0a5f504a4e772 100644 (file)
@@ -8,12 +8,12 @@ from __future__ import annotations
 
 from typing import Any
 from typing import Generic
+from typing import Literal
 from typing import Optional
 from typing import TYPE_CHECKING
 from typing import TypeVar
 
 from .. import util
-from ..util.typing import Literal
 
 if TYPE_CHECKING:
     from ._typing import _PropagateAttrsType
index 92ecadb7927ecab9cfed3774a267486e02045716..4e640e2af40cd6ef20a4711cb74b378e435d2a70 100644 (file)
@@ -44,6 +44,7 @@ from typing import Final
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -54,6 +55,7 @@ from typing import Set
 from typing import Tuple
 from typing import TYPE_CHECKING
 from typing import TypedDict
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -86,9 +88,7 @@ from .. import exc
 from .. import inspection
 from .. import util
 from ..util import HasMemoized
-from ..util.typing import Literal
 from ..util.typing import Self
-from ..util.typing import TypeGuard
 
 if typing.TYPE_CHECKING:
     from ._typing import _AutoIncrementType
index c19d989fbdaf0ec81c98351e11fe8d4a97017a41..1ec6307c9697f8a94c20f28ee2d42ef6f50022d9 100644 (file)
@@ -26,6 +26,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import NamedTuple
 from typing import NoReturn
 from typing import Optional
@@ -103,7 +104,6 @@ from .. import exc
 from .. import util
 from ..util import HasMemoized_ro_memoized_attribute
 from ..util import warn_deprecated
-from ..util.typing import Literal
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
index 3053dd857b3e5579b10353a516ee1e82e22c18d0..81a2bbf67dd593f7c5b160d9fce4b021d4048677 100644 (file)
@@ -21,8 +21,10 @@ from typing import Callable
 from typing import cast
 from typing import Dict
 from typing import Generic
+from typing import get_args
 from typing import Iterable
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -62,10 +64,8 @@ from .. import util
 from ..engine import processors
 from ..util import langhelpers
 from ..util import OrderedDict
-from ..util.typing import get_args
 from ..util.typing import is_literal
 from ..util.typing import is_pep695
-from ..util.typing import Literal
 from ..util.typing import TupleAny
 
 if TYPE_CHECKING:
index abfbcb61673da0429ec8b3439e9e55221155f578..8cfc72c88bf8414c24b8921433603e7ddc884a0b 100644 (file)
@@ -26,6 +26,7 @@ from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
 from typing import TypedDict
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -38,7 +39,6 @@ from .. import exc
 from .. import util
 from ..util.typing import Self
 from ..util.typing import TypeAliasType
-from ..util.typing import TypeGuard
 
 # these are back-assigned by sqltypes.
 if typing.TYPE_CHECKING:
index 128fc6d345efeb687edfd79e6f6d4fb64beabed7..868927a3e7e42d55cc67692fe883f4801800f791 100644 (file)
@@ -22,6 +22,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Optional
 from typing import overload
 from typing import Protocol
@@ -67,7 +68,6 @@ from .selectable import TableClause
 from .visitors import _ET
 from .. import exc
 from .. import util
-from ..util.typing import Literal
 from ..util.typing import Unpack
 
 if typing.TYPE_CHECKING:
index a5cf585ba42db585fbd21cf45ce5ff04a7ce6c36..1cd7097f2d2a306337c034c6a006a4c78d12d6ac 100644 (file)
@@ -22,6 +22,7 @@ from typing import Dict
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import Optional
 from typing import overload
@@ -37,7 +38,6 @@ from ._util_cy import prefix_anon_map as prefix_anon_map  # noqa: F401
 from .. import exc
 from .. import util
 from ..util import langhelpers
-from ..util.typing import Literal
 from ..util.typing import Self
 
 if TYPE_CHECKING:
index fc51e7d873159d6fd53e67a5ec5ea029388d8eb0..fdb6d18b13cd9510a05db737e624c34d7a68dd07 100644 (file)
@@ -14,6 +14,7 @@ import re
 import typing
 from typing import Any
 from typing import Dict
+from typing import Literal
 from typing import Optional
 import warnings
 import weakref
@@ -24,7 +25,6 @@ from .util import gc_collect
 from .. import event
 from .. import pool
 from ..util import await_
-from ..util.typing import Literal
 
 
 if typing.TYPE_CHECKING:
index 4b43225789cddbea07f7ec8aa6aaa40822179f8c..b1d2ee0e81642a6158d31f84e00744b005132440 100644 (file)
@@ -19,7 +19,6 @@ import tempfile
 from .base import TestBase
 from .. import config
 from ..assertions import eq_
-from ... import util
 
 try:
     from mypy import version
@@ -206,8 +205,8 @@ class MypyTest(TestBase):
                         is_mypy = is_re = True
                         expected_msg = f'Revealed type is "{expected_msg}"'
 
-                    if mypy_14 and util.py310:
-                        # use_or_syntax, py310 and above
+                    if mypy_14:
+                        # use_or_syntax
                         # https://github.com/python/mypy/blob/304997bfb85200fb521ac727ee0ce3e6085e5278/mypy/options.py#L368  # noqa: E501
                         expected_msg = re.sub(
                             r"Optional\[(.*?)\]",
index 3d109be3084bc66cdd5ac3a99083cef69e9c255c..6c1d3918a2e385a3b0730465bcd3b402c592f2d2 100644 (file)
@@ -1590,12 +1590,6 @@ class SuiteRequirements(Requirements):
 
         return exclusions.only_if(check)
 
-    @property
-    def python310(self):
-        return exclusions.only_if(
-            lambda: util.py310, "Python 3.10 or above required"
-        )
-
     @property
     def python311(self):
         return exclusions.only_if(
index a2110c4ec52dbc6a755d61c6acb3d23255af1f7f..167d135adbf06c5d1e06b80e01e090e09a01f385 100644 (file)
@@ -46,7 +46,6 @@ from ._collections import UniqueAppender as UniqueAppender
 from ._collections import update_copy as update_copy
 from ._collections import WeakPopulateDict as WeakPopulateDict
 from ._collections import WeakSequence as WeakSequence
-from .compat import anext_ as anext_
 from .compat import arm as arm
 from .compat import b as b
 from .compat import b64decode as b64decode
@@ -61,7 +60,6 @@ from .compat import inspect_getfullargspec as inspect_getfullargspec
 from .compat import is64bit as is64bit
 from .compat import local_dataclass_fields as local_dataclass_fields
 from .compat import osx as osx
-from .compat import py310 as py310
 from .compat import py311 as py311
 from .compat import py312 as py312
 from .compat import py313 as py313
@@ -130,7 +128,6 @@ from .langhelpers import (
     monkeypatch_proxied_specials as monkeypatch_proxied_specials,
 )
 from .langhelpers import non_memoized_property as non_memoized_property
-from .langhelpers import NoneType as NoneType
 from .langhelpers import only_once as only_once
 from .langhelpers import (
     parse_user_argument_for_enum as parse_user_argument_for_enum,
index 36ca6a56a92844fe19c69453c87e863f5ea1ff93..8940f38163b6acb12f286231ccf895bc1fa1637e 100644 (file)
@@ -23,6 +23,7 @@ from typing import Generic
 from typing import Iterable
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -43,7 +44,6 @@ from ._immutabledict_cy import immutabledict as immutabledict
 from ._immutabledict_cy import ImmutableDictBase as ImmutableDictBase
 from ._immutabledict_cy import ReadOnlyContainer as ReadOnlyContainer
 from .typing import is_non_string_iterable
-from .typing import Literal
 
 
 _T = TypeVar("_T", bound=Any)
index 7dd777546894e42de84b9597969357ff49adb738..a62bb6a25743c5aea680de1c4f3da864ee7eff40 100644 (file)
@@ -36,7 +36,6 @@ py314 = sys.version_info >= (3, 14)
 py313 = sys.version_info >= (3, 13)
 py312 = sys.version_info >= (3, 12)
 py311 = sys.version_info >= (3, 11)
-py310 = sys.version_info >= (3, 10)
 pypy = platform.python_implementation() == "PyPy"
 cpython = platform.python_implementation() == "CPython"
 
@@ -104,28 +103,6 @@ def md5_not_for_security() -> Any:
     return hashlib.md5(usedforsecurity=False)
 
 
-if py310:
-    anext_ = anext
-else:
-    _NOT_PROVIDED = object()
-    from collections.abc import AsyncIterator
-
-    async def anext_(async_iterator, default=_NOT_PROVIDED):
-        """vendored from https://github.com/python/cpython/pull/8895"""
-
-        if not isinstance(async_iterator, AsyncIterator):
-            raise TypeError(
-                f"anext expected an AsyncIterator, got {type(async_iterator)}"
-            )
-        anxt = type(async_iterator).__anext__
-        try:
-            return await anxt(async_iterator)
-        except StopAsyncIteration:
-            if default is _NOT_PROVIDED:
-                raise
-            return default
-
-
 def importlib_metadata_get(group):
     ep = importlib_metadata.entry_points()
     if typing.TYPE_CHECKING or hasattr(ep, "select"):
index da758e5dce65954d20f8d065a01fbfad93c52a44..d5250f7bbbfc65dba6cf2598bbb6c960a043acc2 100644 (file)
@@ -14,16 +14,16 @@ from typing import Any
 from typing import Awaitable
 from typing import Callable
 from typing import Coroutine
+from typing import Literal
 from typing import NoReturn
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
 from .compat import py311
 from .langhelpers import memoized_property
-from .typing import Literal
 from .typing import Self
-from .typing import TypeGuard
 from .. import exc
 
 _T = TypeVar("_T")
index f82ab5cde868f739bb2827d459a5d9919d3a1b8e..528723494c6cd3124496a19cd29b3c88f6fdfabe 100644 (file)
@@ -34,6 +34,7 @@ from typing import FrozenSet
 from typing import Generic
 from typing import Iterator
 from typing import List
+from typing import Literal
 from typing import Mapping
 from typing import NoReturn
 from typing import Optional
@@ -49,7 +50,6 @@ import warnings
 
 from . import _collections
 from . import compat
-from .typing import Literal
 from .. import exc
 
 _T = TypeVar("_T")
@@ -136,24 +136,10 @@ if compat.py314:
         # away in future python as a separate mode
         return _vendored_get_annotations(obj, format=Format.FORWARDREF)
 
-elif compat.py310:
-
-    def get_annotations(obj: Any) -> Mapping[str, Any]:
-        return inspect.get_annotations(obj)
-
 else:
 
     def get_annotations(obj: Any) -> Mapping[str, Any]:
-        # https://docs.python.org/3/howto/annotations.html#annotations-howto
-        if isinstance(obj, type):
-            ann = obj.__dict__.get("__annotations__", None)
-        else:
-            ann = obj.__annotations__
-
-        if ann is None:
-            return _collections.EMPTY_DICT
-        else:
-            return cast("Mapping[str, Any]", ann)
+        return inspect.get_annotations(obj)
 
 
 def md5_hex(x: Any) -> str:
@@ -2003,9 +1989,6 @@ def chop_traceback(
     return tb[start : end + 1]
 
 
-NoneType = type(None)
-
-
 def attrsetter(attrname):
     code = "def set(obj, value):    obj.%s = value" % attrname
     env = locals().copy()
index 7a59dd536ee1d650d64d8b99b38f4081cb02f8ea..439bbb85e78dbaec09343080b330dae663402770 100644 (file)
@@ -13,13 +13,17 @@ from collections import deque
 import collections.abc as collections_abc
 import re
 import sys
+from types import NoneType
 import typing
 from typing import Any
 from typing import Callable
 from typing import Dict
 from typing import ForwardRef
 from typing import Generic
+from typing import get_args
+from typing import get_origin
 from typing import Iterable
+from typing import Literal
 from typing import Mapping
 from typing import NewType
 from typing import NoReturn
@@ -30,6 +34,7 @@ from typing import Set
 from typing import Tuple
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeGuard
 from typing import TypeVar
 from typing import Union
 
@@ -38,20 +43,10 @@ import typing_extensions
 from . import compat
 
 if True:  # zimports removes the tailing comments
-    from typing_extensions import Annotated as Annotated  # 3.9
-    from typing_extensions import Concatenate as Concatenate  # 3.10
     from typing_extensions import (
         dataclass_transform as dataclass_transform,  # 3.11,
     )
-    from typing_extensions import get_args as get_args  # 3.10
-    from typing_extensions import get_origin as get_origin  # 3.10
-    from typing_extensions import (
-        Literal as Literal,
-    )  # 3.8 but has bugs before 3.10
     from typing_extensions import NotRequired as NotRequired  # 3.11
-    from typing_extensions import ParamSpec as ParamSpec  # 3.10
-    from typing_extensions import TypeAlias as TypeAlias  # 3.10
-    from typing_extensions import TypeGuard as TypeGuard  # 3.10
     from typing_extensions import TypeVarTuple as TypeVarTuple  # 3.11
     from typing_extensions import Self as Self  # 3.11
     from typing_extensions import TypeAliasType as TypeAliasType  # 3.12
@@ -70,14 +65,6 @@ _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,
-    # I've been wanting it since py27
-    from types import NoneType as NoneType
-else:
-    NoneType = type(None)  # type: ignore
-
-
 def is_fwd_none(typ: Any) -> bool:
     return isinstance(typ, ForwardRef) and typ.__forward_arg__ == "None"
 
@@ -344,10 +331,7 @@ def is_literal(type_: Any) -> bool:
 
 
 def is_newtype(type_: Optional[_AnnotationScanType]) -> TypeGuard[NewType]:
-    return hasattr(type_, "__supertype__")
-    # doesn't work in 3.9, 3.8, 3.7 as it passes a closure, not an
-    # object instance
-    # isinstance(type, type_instances.NewType)
+    return isinstance(type_, _type_tuples.NewType)
 
 
 def is_generic(type_: _AnnotationScanType) -> TypeGuard[GenericProtocol[Any]]:
@@ -598,22 +582,11 @@ def is_origin_of(
     if origin is None:
         return False
 
-    return _get_type_name(origin) in names and (
+    return origin.__name__ in names and (
         module is None or origin.__module__.startswith(module)
     )
 
 
-def _get_type_name(type_: Type[Any]) -> str:
-    if compat.py310:
-        return type_.__name__
-    else:
-        typ_name = getattr(type_, "__name__", None)
-        if typ_name is None:
-            typ_name = getattr(type_, "_name", None)
-
-        return typ_name  # type: ignore
-
-
 class DescriptorProto(Protocol):
     def __get__(self, instance: object, owner: Any) -> Any: ...
 
index 9010569134801ec472eacca204efd942946569a2..2bd90fa25dc1444e68020ee3db41a06cf4c90d94 100644 (file)
@@ -19,7 +19,6 @@ classifiers = [
     "Operating System :: OS Independent",
     "Programming Language :: Python",
     "Programming Language :: Python :: 3",
-    "Programming Language :: Python :: 3.9",
     "Programming Language :: Python :: 3.10",
     "Programming Language :: Python :: 3.11",
     "Programming Language :: Python :: 3.12",
@@ -29,7 +28,7 @@ classifiers = [
     "Programming Language :: Python :: Implementation :: PyPy",
     "Topic :: Database :: Front-Ends",
 ]
-requires-python = ">=3.9"
+requires-python = ">=3.10"
 dependencies = [
     "typing-extensions >= 4.6.0",
 ]
@@ -118,7 +117,7 @@ tag-build = "dev"
 
 [tool.black]
 line-length = 79
-target-version = ['py39']
+target-version = ['py310']
 
 
 [tool.zimports]
index d86322e12ee32e7bacf416e50f33bf892f40cede..672606dfeac79f19622112219501a06a8fe8623c 100644 (file)
@@ -14,7 +14,7 @@ from sqlalchemy.testing import skip_test
 
 
 class DocTest(fixtures.TestBase):
-    __requires__ = ("python310", "insert_returning", "insertmanyvalues")
+    __requires__ = ("insert_returning", "insertmanyvalues")
     __only_on__ = "sqlite+pysqlite"
 
     def _setup_logger(self):
index b1ba3cdee105eb7df25c4b261f976e0ca5eb1945..c5c5015adbbd06cd5ccb71990edbc19da4046532 100644 (file)
@@ -9,7 +9,6 @@ from sqlalchemy.testing import fixtures
 from sqlalchemy.testing import requires
 from sqlalchemy.testing.assertions import eq_
 from sqlalchemy.testing.assertions import is_
-from sqlalchemy.util import py310
 from sqlalchemy.util import py312
 from sqlalchemy.util import py314
 from sqlalchemy.util import typing as sa_typing
@@ -18,9 +17,7 @@ TV = typing.TypeVar("TV")
 
 
 def union_types():
-    res = [typing.Union[int, str]]
-    if py310:
-        res.append(int | str)
+    res = [typing.Union[int, str], int | str]
     return res
 
 
@@ -29,18 +26,17 @@ def null_union_types():
         typing.Optional[typing.Union[int, str]],
         typing.Union[int, str, None],
         typing.Union[int, str, "None"],
+        int | str | None,
+        typing.Optional[int | str],
+        typing.Union[int, str] | None,
+        typing.Optional[int] | str,
     ]
-    if py310:
-        res.append(int | str | None)
-        res.append(typing.Optional[int | str])
-        res.append(typing.Union[int, str] | None)
-        res.append(typing.Optional[int] | str)
     return res
 
 
 def generic_unions():
     res = union_types() + null_union_types()
-    if py310 and not py314:
+    if not py314:
         # for py310 through py313, remove new-style unions `int | str` that
         # are not generic
         new_ut = type(int | str)
@@ -190,12 +186,10 @@ def new_types():
     return [NT_str, NT_null, NT_union]
 
 
-A_str = typing_extensions.Annotated[str, "meta"]
-A_null_str = typing_extensions.Annotated[
-    typing.Union[str, None], "other_meta", "null"
-]
-A_union = typing_extensions.Annotated[typing.Union[str, int], "other_meta"]
-A_null_union = typing_extensions.Annotated[
+A_str = typing.Annotated[str, "meta"]
+A_null_str = typing.Annotated[typing.Union[str, None], "other_meta", "null"]
+A_union = typing.Annotated[typing.Union[str, int], "other_meta"]
+A_null_union = typing.Annotated[
     typing.Union[str, int, None], "other_meta", "null"
 ]
 
@@ -283,8 +277,7 @@ class TestTyping(fixtures.TestBase):
         eq_(sa_typing.is_pep593(str), False)
         eq_(sa_typing.is_pep593(None), False)
         eq_(sa_typing.is_pep593(typing_extensions.Annotated[int, "a"]), True)
-        if py310:
-            eq_(sa_typing.is_pep593(typing.Annotated[int, "a"]), True)
+        eq_(sa_typing.is_pep593(typing.Annotated[int, "a"]), True)
 
         for t in annotated_l():
             eq_(sa_typing.is_pep593(t), True)
index 901b47f42ffd7d2f78cf5f1bcc6923f28ec829b4..a8d2e2ce3cbd819ae5b0584ce59c77496946c74f 100644 (file)
@@ -754,7 +754,6 @@ class AsyncEngineTest(EngineFixture):
             with expect_raises(exc.TimeoutError):
                 await engine.connect()
 
-    @testing.requires.python310
     @async_test
     async def test_engine_aclose(self, async_engine):
         users = self.tables.users
index 5f9bf2e089e87b87544e10a7296d1b64dea6d15f..3ad10337b97629a2d1db64ab9f4eabe42aff1e75 100644 (file)
@@ -197,7 +197,6 @@ class AsyncSessionQueryTest(AsyncFixture):
         result = await async_session.scalar(stmt)
         eq_(result, 7)
 
-    @testing.requires.python310
     @async_test
     async def test_session_aclose(self, async_session):
         User = self.classes.User
index 1aca0c97e259ad9109abbae84f8369fb7ce41f3e..2c38fbc31cf5a773d8b1ce80b866d9f7cffa4d93 100644 (file)
@@ -3912,7 +3912,7 @@ class DeclOrmForms(fixtures.TestBase):
         {},
         {"repr": False},
         {"repr": True},
-        ({"kw_only": True}, testing.requires.python310),
+        {"kw_only": True},
         {"init": False},
         {"default_factory": True},
         argnames="field_kw",
index 3bc260077ca3f3307b96af0e294f4cae8d82c3e4..6d26c58f02ce122402e8bbe249d19e1e149b46ac 100644 (file)
@@ -4,6 +4,7 @@ from dataclasses import InitVar
 import functools
 import inspect as pyinspect
 from itertools import product
+from typing import Annotated
 from typing import Any
 from typing import ClassVar
 from typing import Dict
@@ -15,8 +16,6 @@ from typing import Type
 from typing import TypeVar
 from unittest import mock
 
-from typing_extensions import Annotated
-
 from sqlalchemy import BigInteger
 from sqlalchemy import Column
 from sqlalchemy import exc
@@ -60,7 +59,6 @@ from sqlalchemy.testing import is_false
 from sqlalchemy.testing import is_true
 from sqlalchemy.testing import ne_
 from sqlalchemy.testing import Variation
-from sqlalchemy.util import compat
 
 
 def _dataclass_mixin_warning(clsname, attrnames):
@@ -721,7 +719,6 @@ class DCTransformsTest(AssertsCompiledSQL, fixtures.TestBase):
         a2 = A(id=1, data="foo")
         eq_(a1, a2)
 
-    @testing.requires.python310
     def test_kw_only_attribute(self, dc_decl_base: Type[MappedAsDataclass]):
         class A(dc_decl_base):
             __tablename__ = "a"
@@ -754,7 +751,6 @@ class DCTransformsTest(AssertsCompiledSQL, fixtures.TestBase):
             a.data = "y"
             ne_(hash(a), a_hash1)
 
-    @testing.requires.python310
     def test_kw_only_dataclass_constant(
         self, dc_decl_base: Type[MappedAsDataclass]
     ):
@@ -1470,9 +1466,15 @@ class DataclassesForNonMappedClassesTest(fixtures.TestBase):
 
 
 class DataclassArgsTest(fixtures.TestBase):
-    dc_arg_names = ("init", "repr", "eq", "order", "unsafe_hash")
-    if compat.py310:
-        dc_arg_names += ("match_args", "kw_only")
+    dc_arg_names = (
+        "init",
+        "repr",
+        "eq",
+        "order",
+        "unsafe_hash",
+        "match_args",
+        "kw_only",
+    )
 
     @testing.fixture(params=product(dc_arg_names, (True, False)))
     def dc_argument_fixture(self, request: Any, registry: _RegistryType):
@@ -1488,9 +1490,9 @@ class DataclassArgsTest(fixtures.TestBase):
                 "eq": True,
                 "order": False,
                 "unsafe_hash": False,
+                "match_args": True,
+                "kw_only": False,
             }
-            if compat.py310:
-                default |= {"match_args": True, "kw_only": False}
             to_apply = {k: v for k, v in args.items() if v}
             effective = {**default, **to_apply}
             return to_apply, effective
@@ -1779,9 +1781,9 @@ class DataclassArgsTest(fixtures.TestBase):
             "eq": True,
             "order": True,
             "unsafe_hash": False,
+            "match_args": True,
+            "kw_only": False,
         }
-        if compat.py310:
-            effective |= {"match_args": True, "kw_only": False}
         self._assert_cls(A, effective)
 
     def test_dc_base_unsupported_argument(self, registry: _RegistryType):
index 035abc19c124b8b87783beb403323d7499672bf3..a5e2c53c456897554b976a0bb223b5fe7be0ed33 100644 (file)
@@ -13,6 +13,7 @@ from dataclasses import InitVar
 import functools
 import inspect as pyinspect
 from itertools import product
+from typing import Annotated
 from typing import Any
 from typing import ClassVar
 from typing import Dict
@@ -24,8 +25,6 @@ from typing import Type
 from typing import TypeVar
 from unittest import mock
 
-from typing_extensions import Annotated
-
 from sqlalchemy import BigInteger
 from sqlalchemy import Column
 from sqlalchemy import exc
@@ -69,7 +68,6 @@ from sqlalchemy.testing import is_false
 from sqlalchemy.testing import is_true
 from sqlalchemy.testing import ne_
 from sqlalchemy.testing import Variation
-from sqlalchemy.util import compat
 
 
 def _dataclass_mixin_warning(clsname, attrnames):
@@ -734,7 +732,6 @@ class DCTransformsTest(AssertsCompiledSQL, fixtures.TestBase):
         a2 = A(id=1, data="foo")
         eq_(a1, a2)
 
-    @testing.requires.python310
     def test_kw_only_attribute(self, dc_decl_base: Type[MappedAsDataclass]):
         class A(dc_decl_base):
             __tablename__ = "a"
@@ -767,7 +764,6 @@ class DCTransformsTest(AssertsCompiledSQL, fixtures.TestBase):
             a.data = "y"
             ne_(hash(a), a_hash1)
 
-    @testing.requires.python310
     def test_kw_only_dataclass_constant(
         self, dc_decl_base: Type[MappedAsDataclass]
     ):
@@ -1489,9 +1485,15 @@ class DataclassesForNonMappedClassesTest(fixtures.TestBase):
 
 
 class DataclassArgsTest(fixtures.TestBase):
-    dc_arg_names = ("init", "repr", "eq", "order", "unsafe_hash")
-    if compat.py310:
-        dc_arg_names += ("match_args", "kw_only")
+    dc_arg_names = (
+        "init",
+        "repr",
+        "eq",
+        "order",
+        "unsafe_hash",
+        "match_args",
+        "kw_only",
+    )
 
     @testing.fixture(params=product(dc_arg_names, (True, False)))
     def dc_argument_fixture(self, request: Any, registry: _RegistryType):
@@ -1507,9 +1509,9 @@ class DataclassArgsTest(fixtures.TestBase):
                 "eq": True,
                 "order": False,
                 "unsafe_hash": False,
+                "match_args": True,
+                "kw_only": False,
             }
-            if compat.py310:
-                default |= {"match_args": True, "kw_only": False}
             to_apply = {k: v for k, v in args.items() if v}
             effective = {**default, **to_apply}
             return to_apply, effective
@@ -1798,9 +1800,9 @@ class DataclassArgsTest(fixtures.TestBase):
             "eq": True,
             "order": True,
             "unsafe_hash": False,
+            "match_args": True,
+            "kw_only": False,
         }
-        if compat.py310:
-            effective |= {"match_args": True, "kw_only": False}
         self._assert_cls(A, effective)
 
     def test_dc_base_unsupported_argument(self, registry: _RegistryType):
index 42745e46690bd01eba34b421bc87e09b92596655..0ec0cdbe622c1cdb12519f5882144e382d73e769 100644 (file)
@@ -1,6 +1,5 @@
 from operator import is_not
-
-from typing_extensions import Annotated
+from typing import Annotated
 
 import sqlalchemy as sa
 from sqlalchemy import ForeignKey
index ac343c2315c4efcf26f7d480a20dac2d56876220..0ab310277a12379b351591797f215900b416e91b 100644 (file)
@@ -15,26 +15,27 @@ import enum
 import inspect as _py_inspect
 import re
 import typing
+from typing import Annotated
 from typing import Any
 from typing import cast
 from typing import ClassVar
 from typing import Dict
 from typing import Generic
+from typing import get_args as get_args
 from typing import List
+from typing import Literal as Literal
 from typing import NewType
 from typing import Optional
 from typing import Set
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeAlias as TypeAlias
 from typing import TypedDict
 from typing import TypeVar
 from typing import Union
 import uuid
 
 import typing_extensions
-from typing_extensions import get_args as get_args
-from typing_extensions import Literal as Literal
-from typing_extensions import TypeAlias as TypeAlias
 from typing_extensions import TypeAliasType
 
 from sqlalchemy import BIGINT
@@ -102,8 +103,6 @@ from sqlalchemy.testing import requires
 from sqlalchemy.testing import Variation
 from sqlalchemy.testing.assertions import ne_
 from sqlalchemy.testing.fixtures import fixture_session
-from sqlalchemy.util import compat
-from sqlalchemy.util.typing import Annotated
 
 TV = typing.TypeVar("TV")
 
@@ -128,15 +127,14 @@ _JsonPrimitive: TypeAlias = Union[str, int, float, bool, None]
 _JsonObject: TypeAlias = Dict[str, "_Json"]
 _JsonArray: TypeAlias = List["_Json"]
 _Json: TypeAlias = Union[_JsonObject, _JsonArray, _JsonPrimitive]
+_JsonPrimitivePep604: TypeAlias = str | int | float | bool | None
+_JsonObjectPep604: TypeAlias = dict[str, "_JsonPep604"]
+_JsonArrayPep604: TypeAlias = list["_JsonPep604"]
+_JsonPep604: TypeAlias = (
+    _JsonObjectPep604 | _JsonArrayPep604 | _JsonPrimitivePep604
+)
+_JsonPep695 = TypeAliasType("_JsonPep695", _JsonPep604)
 
-if compat.py310:
-    _JsonPrimitivePep604: TypeAlias = str | int | float | bool | None
-    _JsonObjectPep604: TypeAlias = dict[str, "_JsonPep604"]
-    _JsonArrayPep604: TypeAlias = list["_JsonPep604"]
-    _JsonPep604: TypeAlias = (
-        _JsonObjectPep604 | _JsonArrayPep604 | _JsonPrimitivePep604
-    )
-    _JsonPep695 = TypeAliasType("_JsonPep695", _JsonPep604)
 
 TypingTypeAliasType = getattr(typing, "TypeAliasType", TypeAliasType)
 
@@ -152,11 +150,10 @@ _UnionPep695 = TypeAliasType("_UnionPep695", Union[_SomeDict1, _SomeDict2])
 strtypalias_keyword = TypeAliasType(
     "strtypalias_keyword", Annotated[str, mapped_column(info={"hi": "there"})]
 )
-if compat.py310:
-    strtypalias_keyword_nested = TypeAliasType(
-        "strtypalias_keyword_nested",
-        int | Annotated[str, mapped_column(info={"hi": "there"})],
-    )
+strtypalias_keyword_nested = TypeAliasType(
+    "strtypalias_keyword_nested",
+    int | Annotated[str, mapped_column(info={"hi": "there"})],
+)
 strtypalias_ta: TypeAlias = Annotated[str, mapped_column(info={"hi": "there"})]
 strtypalias_plain = Annotated[str, mapped_column(info={"hi": "there"})]
 _Literal695 = TypeAliasType(
@@ -633,11 +630,11 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "argtype",
         [
             "type",
-            ("column", testing.requires.python310),
-            ("mapped_column", testing.requires.python310),
+            "column",
+            "mapped_column",
             "column_class",
             "ref_to_type",
-            ("ref_to_column", testing.requires.python310),
+            "ref_to_column",
         ],
     )
     def test_construct_lhs_sqlalchemy_type(self, decl_base, argtype):
@@ -1308,7 +1305,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             eq_(col.type.enums, ["a", "b"])
             is_(col.type.native_enum, False)
 
-    @testing.requires.python310
     def test_we_got_all_attrs_test_annotated(self):
         argnames = _py_inspect.getfullargspec(mapped_column)
         assert _annotated_names_tested.issuperset(argnames.kwonlyargs), (
@@ -1419,7 +1415,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             exc.SADeprecationWarning(
                 "Argument 'kw_only' is a dataclass argument "
             ),
-            testing.requires.python310,
         ),
         (
             "compare",
@@ -1427,7 +1422,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             exc.SADeprecationWarning(
                 "Argument 'compare' is a dataclass argument "
             ),
-            testing.requires.python310,
         ),
         (
             "default_factory",
@@ -1620,17 +1614,10 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
         str50 = NewType("str50", str)
 
-        if compat.py310:
-            text = ".*str50"
-        else:
-            # NewTypes before 3.10 had a very bad repr
-            # <function NewType.<locals>.new_type at 0x...>
-            text = ".*NewType.*"
-
         with expect_raises_message(
             orm_exc.MappedAnnotationError,
             "Could not locate SQLAlchemy Core type for Python type "
-            f"{text} inside the 'data_one' attribute Mapped annotation",
+            ".*str50 inside the 'data_one' attribute Mapped annotation",
         ):
 
             class MyClass(decl_base):
@@ -1848,38 +1835,22 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             to_assert.fail()
 
     @testing.combinations(
-        (collections.abc.Sequence, (str,), testing.requires.python310),
-        (collections.abc.MutableSequence, (str,), testing.requires.python310),
-        (collections.abc.Mapping, (str, str), testing.requires.python310),
-        (
-            collections.abc.MutableMapping,
-            (str, str),
-            testing.requires.python310,
-        ),
-        (typing.Mapping, (str, str), testing.requires.python310),
-        (typing.MutableMapping, (str, str), testing.requires.python310),
+        (collections.abc.Sequence, (str,)),
+        (collections.abc.MutableSequence, (str,)),
+        (collections.abc.Mapping, (str, str)),
+        (collections.abc.MutableMapping, (str, str)),
+        (typing.Mapping, (str, str)),
+        (typing.MutableMapping, (str, str)),
         (typing.Sequence, (str,)),
         (typing.MutableSequence, (str,)),
-        (list, (str,), testing.requires.python310),
-        (
-            List,
-            (str,),
-        ),
-        (dict, (str, str), testing.requires.python310),
-        (
-            Dict,
-            (str, str),
-        ),
-        (list, None, testing.requires.python310),
-        (
-            List,
-            None,
-        ),
-        (dict, None, testing.requires.python310),
-        (
-            Dict,
-            None,
-        ),
+        (list, (str,)),
+        (List, (str,)),
+        (dict, (str, str)),
+        (Dict, (str, str)),
+        (list, None),
+        (List, None),
+        (dict, None),
+        (Dict, None),
         id_="sa",
         argnames="container_typ,args",
     )
@@ -2166,12 +2137,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
     @testing.variation(
         "union",
-        [
-            "union",
-            ("pep604", requires.python310),
-            "union_null",
-            ("pep604_null", requires.python310),
-        ],
+        ["union", "pep604", "union_null", "pep604_null"],
     )
     def test_unions(self, union):
         global UnionType
@@ -2227,17 +2193,14 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             float_data: Mapped[float] = mapped_column()
             decimal_data: Mapped[Decimal] = mapped_column()
 
-            if compat.py310:
-                pep604_data: Mapped[float | Decimal] = mapped_column()
-                pep604_reverse: Mapped[Decimal | float] = mapped_column()
-                pep604_optional: Mapped[Decimal | float | None] = (
-                    mapped_column()
-                )
-                pep604_data_fwd: Mapped["float | Decimal"] = mapped_column()
-                pep604_reverse_fwd: Mapped["Decimal | float"] = mapped_column()
-                pep604_optional_fwd: Mapped["Decimal | float | None"] = (
-                    mapped_column()
-                )
+            pep604_data: Mapped[float | Decimal] = mapped_column()
+            pep604_reverse: Mapped[Decimal | float] = mapped_column()
+            pep604_optional: Mapped[Decimal | float | None] = mapped_column()
+            pep604_data_fwd: Mapped["float | Decimal"] = mapped_column()
+            pep604_reverse_fwd: Mapped["Decimal | float"] = mapped_column()
+            pep604_optional_fwd: Mapped["Decimal | float | None"] = (
+                mapped_column()
+            )
 
         info = [
             ("data", False),
@@ -2248,16 +2211,13 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             ("refer_union", "null" in union.name),
             ("refer_union_optional", True),
             ("unflat_union_optional_data", True),
+            ("pep604_data", False),
+            ("pep604_reverse", False),
+            ("pep604_optional", True),
+            ("pep604_data_fwd", False),
+            ("pep604_reverse_fwd", False),
+            ("pep604_optional_fwd", True),
         ]
-        if compat.py310:
-            info += [
-                ("pep604_data", False),
-                ("pep604_reverse", False),
-                ("pep604_optional", True),
-                ("pep604_data_fwd", False),
-                ("pep604_reverse_fwd", False),
-                ("pep604_optional_fwd", True),
-            ]
 
         for name, nullable in info:
             col = User.__table__.c[name]
@@ -2274,7 +2234,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "union",
         [
             "union",
-            ("pep604", requires.python310),
+            "pep604",
             ("pep695", requires.python312),
         ],
     )
@@ -2321,8 +2281,8 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             "optional",
             "optional_fwd_ref",
             "union_none",
-            ("pep604", testing.requires.python310),
-            ("pep604_fwd_ref", testing.requires.python310),
+            "pep604",
+            "pep604_fwd_ref",
         ],
     )
     @testing.variation("brackets", ["oneset", "twosets"])
@@ -2336,18 +2296,12 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         #12207"""
 
         class Base(DeclarativeBase):
-            if testing.requires.python310.enabled:
-                type_annotation_map = {
-                    Dict[str, Decimal]: JSON,
-                    dict[str, Decimal]: JSON,
-                    Union[List[int], List[str]]: JSON,
-                    list[int] | list[str]: JSON,
-                }
-            else:
-                type_annotation_map = {
-                    Dict[str, Decimal]: JSON,
-                    Union[List[int], List[str]]: JSON,
-                }
+            type_annotation_map = {
+                Dict[str, Decimal]: JSON,
+                dict[str, Decimal]: JSON,
+                Union[List[int], List[str]]: JSON,
+                list[int] | list[str]: JSON,
+            }
 
         if include_mc_type == "include_mc_type":
             mc = mapped_column(JSON)
@@ -2365,46 +2319,36 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             if brackets.oneset:
                 if option.not_optional:
                     json: Mapped[Dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
+                    json2: Mapped[dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
                 elif option.optional:
                     json: Mapped[Optional[Dict[str, Decimal]]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[Optional[dict[str, Decimal]]] = mc2
+                    json2: Mapped[Optional[dict[str, Decimal]]] = mc2
                 elif option.optional_fwd_ref:
                     json: Mapped["Optional[Dict[str, Decimal]]"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped["Optional[dict[str, Decimal]]"] = mc2
+                    json2: Mapped["Optional[dict[str, Decimal]]"] = mc2
                 elif option.union_none:
                     json: Mapped[Union[Dict[str, Decimal], None]] = mc
                     json2: Mapped[Union[None, Dict[str, Decimal]]] = mc2
                 elif option.pep604:
                     json: Mapped[dict[str, Decimal] | None] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[None | dict[str, Decimal]] = mc2
+                    json2: Mapped[None | dict[str, Decimal]] = mc2
                 elif option.pep604_fwd_ref:
                     json: Mapped["dict[str, Decimal] | None"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped["None | dict[str, Decimal]"] = mc2
+                    json2: Mapped["None | dict[str, Decimal]"] = mc2
             elif brackets.twosets:
                 if option.not_optional:
                     json: Mapped[Union[List[int], List[str]]] = mapped_column()  # type: ignore  # noqa: E501
                 elif option.optional:
                     json: Mapped[Optional[Union[List[int], List[str]]]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[
-                            Optional[Union[list[int], list[str]]]
-                        ] = mc2
+                    json2: Mapped[Optional[Union[list[int], list[str]]]] = mc2
                 elif option.optional_fwd_ref:
                     json: Mapped["Optional[Union[List[int], List[str]]]"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[
-                            "Optional[Union[list[int], list[str]]]"
-                        ] = mc2
+                    json2: Mapped["Optional[Union[list[int], list[str]]]"] = (
+                        mc2
+                    )
                 elif option.union_none:
                     json: Mapped[Union[List[int], List[str], None]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[Union[None, list[int], list[str]]] = mc2
+                    json2: Mapped[Union[None, list[int], list[str]]] = mc2
                 elif option.pep604:
                     json: Mapped[list[int] | list[str] | None] = mc
                     json2: Mapped[None | list[int] | list[str]] = mc2
@@ -2643,9 +2587,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
                 id: Mapped[int] = mapped_column(primary_key=True)
                 data: Mapped[int_sub]
 
-    @testing.variation(
-        "dict_key", ["typing", ("plain", testing.requires.python310)]
-    )
+    @testing.variation("dict_key", ["typing", "plain"])
     def test_type_dont_mis_resolve_on_non_generic(self, dict_key):
         """test for #8859.
 
@@ -3302,9 +3244,9 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "datatype",
         [
             "typing_sequence",
-            ("collections_sequence", testing.requires.python310),
+            "collections_sequence",
             "typing_mutable_sequence",
-            ("collections_mutable_sequence", testing.requires.python310),
+            "collections_mutable_sequence",
         ],
     )
     @testing.variation("include_explicit", [True, False])
@@ -3388,12 +3330,7 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
     @testing.variation(
         "collection_type",
-        [
-            ("list", testing.requires.python310),
-            "List",
-            ("set", testing.requires.python310),
-            "Set",
-        ],
+        ["list", "List", "set", "Set"],
     )
     def test_14_style_anno_accepted_w_allow_unmapped(self, collection_type):
         """test for #8692 and #10385"""
@@ -3453,7 +3390,7 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         ("optional",),
         ("optional_fwd_ref",),
         ("union_none",),
-        ("pep604", testing.requires.python310),
+        ("pep604",),
         argnames="optional_on_m2o",
     )
     def test_basic_bidirectional(self, decl_base, optional_on_m2o):
index 72ba534f3593174254c0f7994e6717fcdb71c6da..cabe5ecae293fe0063e9aaf6b4baa647ba8f86ef 100644 (file)
@@ -6,26 +6,27 @@ import enum
 import inspect as _py_inspect
 import re
 import typing
+from typing import Annotated
 from typing import Any
 from typing import cast
 from typing import ClassVar
 from typing import Dict
 from typing import Generic
+from typing import get_args as get_args
 from typing import List
+from typing import Literal as Literal
 from typing import NewType
 from typing import Optional
 from typing import Set
 from typing import Type
 from typing import TYPE_CHECKING
+from typing import TypeAlias as TypeAlias
 from typing import TypedDict
 from typing import TypeVar
 from typing import Union
 import uuid
 
 import typing_extensions
-from typing_extensions import get_args as get_args
-from typing_extensions import Literal as Literal
-from typing_extensions import TypeAlias as TypeAlias
 from typing_extensions import TypeAliasType
 
 from sqlalchemy import BIGINT
@@ -93,8 +94,6 @@ from sqlalchemy.testing import requires
 from sqlalchemy.testing import Variation
 from sqlalchemy.testing.assertions import ne_
 from sqlalchemy.testing.fixtures import fixture_session
-from sqlalchemy.util import compat
-from sqlalchemy.util.typing import Annotated
 
 TV = typing.TypeVar("TV")
 
@@ -119,15 +118,14 @@ _JsonPrimitive: TypeAlias = Union[str, int, float, bool, None]
 _JsonObject: TypeAlias = Dict[str, "_Json"]
 _JsonArray: TypeAlias = List["_Json"]
 _Json: TypeAlias = Union[_JsonObject, _JsonArray, _JsonPrimitive]
+_JsonPrimitivePep604: TypeAlias = str | int | float | bool | None
+_JsonObjectPep604: TypeAlias = dict[str, "_JsonPep604"]
+_JsonArrayPep604: TypeAlias = list["_JsonPep604"]
+_JsonPep604: TypeAlias = (
+    _JsonObjectPep604 | _JsonArrayPep604 | _JsonPrimitivePep604
+)
+_JsonPep695 = TypeAliasType("_JsonPep695", _JsonPep604)
 
-if compat.py310:
-    _JsonPrimitivePep604: TypeAlias = str | int | float | bool | None
-    _JsonObjectPep604: TypeAlias = dict[str, "_JsonPep604"]
-    _JsonArrayPep604: TypeAlias = list["_JsonPep604"]
-    _JsonPep604: TypeAlias = (
-        _JsonObjectPep604 | _JsonArrayPep604 | _JsonPrimitivePep604
-    )
-    _JsonPep695 = TypeAliasType("_JsonPep695", _JsonPep604)
 
 TypingTypeAliasType = getattr(typing, "TypeAliasType", TypeAliasType)
 
@@ -143,11 +141,10 @@ _UnionPep695 = TypeAliasType("_UnionPep695", Union[_SomeDict1, _SomeDict2])
 strtypalias_keyword = TypeAliasType(
     "strtypalias_keyword", Annotated[str, mapped_column(info={"hi": "there"})]
 )
-if compat.py310:
-    strtypalias_keyword_nested = TypeAliasType(
-        "strtypalias_keyword_nested",
-        int | Annotated[str, mapped_column(info={"hi": "there"})],
-    )
+strtypalias_keyword_nested = TypeAliasType(
+    "strtypalias_keyword_nested",
+    int | Annotated[str, mapped_column(info={"hi": "there"})],
+)
 strtypalias_ta: TypeAlias = Annotated[str, mapped_column(info={"hi": "there"})]
 strtypalias_plain = Annotated[str, mapped_column(info={"hi": "there"})]
 _Literal695 = TypeAliasType(
@@ -624,11 +621,11 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "argtype",
         [
             "type",
-            ("column", testing.requires.python310),
-            ("mapped_column", testing.requires.python310),
+            "column",
+            "mapped_column",
             "column_class",
             "ref_to_type",
-            ("ref_to_column", testing.requires.python310),
+            "ref_to_column",
         ],
     )
     def test_construct_lhs_sqlalchemy_type(self, decl_base, argtype):
@@ -1299,7 +1296,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             eq_(col.type.enums, ["a", "b"])
             is_(col.type.native_enum, False)
 
-    @testing.requires.python310
     def test_we_got_all_attrs_test_annotated(self):
         argnames = _py_inspect.getfullargspec(mapped_column)
         assert _annotated_names_tested.issuperset(argnames.kwonlyargs), (
@@ -1410,7 +1406,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             exc.SADeprecationWarning(
                 "Argument 'kw_only' is a dataclass argument "
             ),
-            testing.requires.python310,
         ),
         (
             "compare",
@@ -1418,7 +1413,6 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             exc.SADeprecationWarning(
                 "Argument 'compare' is a dataclass argument "
             ),
-            testing.requires.python310,
         ),
         (
             "default_factory",
@@ -1611,17 +1605,10 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
         str50 = NewType("str50", str)
 
-        if compat.py310:
-            text = ".*str50"
-        else:
-            # NewTypes before 3.10 had a very bad repr
-            # <function NewType.<locals>.new_type at 0x...>
-            text = ".*NewType.*"
-
         with expect_raises_message(
             orm_exc.MappedAnnotationError,
             "Could not locate SQLAlchemy Core type for Python type "
-            f"{text} inside the 'data_one' attribute Mapped annotation",
+            ".*str50 inside the 'data_one' attribute Mapped annotation",
         ):
 
             class MyClass(decl_base):
@@ -1839,38 +1826,22 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             to_assert.fail()
 
     @testing.combinations(
-        (collections.abc.Sequence, (str,), testing.requires.python310),
-        (collections.abc.MutableSequence, (str,), testing.requires.python310),
-        (collections.abc.Mapping, (str, str), testing.requires.python310),
-        (
-            collections.abc.MutableMapping,
-            (str, str),
-            testing.requires.python310,
-        ),
-        (typing.Mapping, (str, str), testing.requires.python310),
-        (typing.MutableMapping, (str, str), testing.requires.python310),
+        (collections.abc.Sequence, (str,)),
+        (collections.abc.MutableSequence, (str,)),
+        (collections.abc.Mapping, (str, str)),
+        (collections.abc.MutableMapping, (str, str)),
+        (typing.Mapping, (str, str)),
+        (typing.MutableMapping, (str, str)),
         (typing.Sequence, (str,)),
         (typing.MutableSequence, (str,)),
-        (list, (str,), testing.requires.python310),
-        (
-            List,
-            (str,),
-        ),
-        (dict, (str, str), testing.requires.python310),
-        (
-            Dict,
-            (str, str),
-        ),
-        (list, None, testing.requires.python310),
-        (
-            List,
-            None,
-        ),
-        (dict, None, testing.requires.python310),
-        (
-            Dict,
-            None,
-        ),
+        (list, (str,)),
+        (List, (str,)),
+        (dict, (str, str)),
+        (Dict, (str, str)),
+        (list, None),
+        (List, None),
+        (dict, None),
+        (Dict, None),
         id_="sa",
         argnames="container_typ,args",
     )
@@ -2157,12 +2128,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
     @testing.variation(
         "union",
-        [
-            "union",
-            ("pep604", requires.python310),
-            "union_null",
-            ("pep604_null", requires.python310),
-        ],
+        ["union", "pep604", "union_null", "pep604_null"],
     )
     def test_unions(self, union):
         # anno only: global UnionType
@@ -2218,17 +2184,14 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             float_data: Mapped[float] = mapped_column()
             decimal_data: Mapped[Decimal] = mapped_column()
 
-            if compat.py310:
-                pep604_data: Mapped[float | Decimal] = mapped_column()
-                pep604_reverse: Mapped[Decimal | float] = mapped_column()
-                pep604_optional: Mapped[Decimal | float | None] = (
-                    mapped_column()
-                )
-                pep604_data_fwd: Mapped["float | Decimal"] = mapped_column()
-                pep604_reverse_fwd: Mapped["Decimal | float"] = mapped_column()
-                pep604_optional_fwd: Mapped["Decimal | float | None"] = (
-                    mapped_column()
-                )
+            pep604_data: Mapped[float | Decimal] = mapped_column()
+            pep604_reverse: Mapped[Decimal | float] = mapped_column()
+            pep604_optional: Mapped[Decimal | float | None] = mapped_column()
+            pep604_data_fwd: Mapped["float | Decimal"] = mapped_column()
+            pep604_reverse_fwd: Mapped["Decimal | float"] = mapped_column()
+            pep604_optional_fwd: Mapped["Decimal | float | None"] = (
+                mapped_column()
+            )
 
         info = [
             ("data", False),
@@ -2239,16 +2202,13 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             ("refer_union", "null" in union.name),
             ("refer_union_optional", True),
             ("unflat_union_optional_data", True),
+            ("pep604_data", False),
+            ("pep604_reverse", False),
+            ("pep604_optional", True),
+            ("pep604_data_fwd", False),
+            ("pep604_reverse_fwd", False),
+            ("pep604_optional_fwd", True),
         ]
-        if compat.py310:
-            info += [
-                ("pep604_data", False),
-                ("pep604_reverse", False),
-                ("pep604_optional", True),
-                ("pep604_data_fwd", False),
-                ("pep604_reverse_fwd", False),
-                ("pep604_optional_fwd", True),
-            ]
 
         for name, nullable in info:
             col = User.__table__.c[name]
@@ -2265,7 +2225,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "union",
         [
             "union",
-            ("pep604", requires.python310),
+            "pep604",
             ("pep695", requires.python312),
         ],
     )
@@ -2312,8 +2272,8 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             "optional",
             "optional_fwd_ref",
             "union_none",
-            ("pep604", testing.requires.python310),
-            ("pep604_fwd_ref", testing.requires.python310),
+            "pep604",
+            "pep604_fwd_ref",
         ],
     )
     @testing.variation("brackets", ["oneset", "twosets"])
@@ -2327,18 +2287,12 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         #12207"""
 
         class Base(DeclarativeBase):
-            if testing.requires.python310.enabled:
-                type_annotation_map = {
-                    Dict[str, Decimal]: JSON,
-                    dict[str, Decimal]: JSON,
-                    Union[List[int], List[str]]: JSON,
-                    list[int] | list[str]: JSON,
-                }
-            else:
-                type_annotation_map = {
-                    Dict[str, Decimal]: JSON,
-                    Union[List[int], List[str]]: JSON,
-                }
+            type_annotation_map = {
+                Dict[str, Decimal]: JSON,
+                dict[str, Decimal]: JSON,
+                Union[List[int], List[str]]: JSON,
+                list[int] | list[str]: JSON,
+            }
 
         if include_mc_type == "include_mc_type":
             mc = mapped_column(JSON)
@@ -2356,46 +2310,36 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
             if brackets.oneset:
                 if option.not_optional:
                     json: Mapped[Dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
+                    json2: Mapped[dict[str, Decimal]] = mapped_column()  # type: ignore  # noqa: E501
                 elif option.optional:
                     json: Mapped[Optional[Dict[str, Decimal]]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[Optional[dict[str, Decimal]]] = mc2
+                    json2: Mapped[Optional[dict[str, Decimal]]] = mc2
                 elif option.optional_fwd_ref:
                     json: Mapped["Optional[Dict[str, Decimal]]"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped["Optional[dict[str, Decimal]]"] = mc2
+                    json2: Mapped["Optional[dict[str, Decimal]]"] = mc2
                 elif option.union_none:
                     json: Mapped[Union[Dict[str, Decimal], None]] = mc
                     json2: Mapped[Union[None, Dict[str, Decimal]]] = mc2
                 elif option.pep604:
                     json: Mapped[dict[str, Decimal] | None] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[None | dict[str, Decimal]] = mc2
+                    json2: Mapped[None | dict[str, Decimal]] = mc2
                 elif option.pep604_fwd_ref:
                     json: Mapped["dict[str, Decimal] | None"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped["None | dict[str, Decimal]"] = mc2
+                    json2: Mapped["None | dict[str, Decimal]"] = mc2
             elif brackets.twosets:
                 if option.not_optional:
                     json: Mapped[Union[List[int], List[str]]] = mapped_column()  # type: ignore  # noqa: E501
                 elif option.optional:
                     json: Mapped[Optional[Union[List[int], List[str]]]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[
-                            Optional[Union[list[int], list[str]]]
-                        ] = mc2
+                    json2: Mapped[Optional[Union[list[int], list[str]]]] = mc2
                 elif option.optional_fwd_ref:
                     json: Mapped["Optional[Union[List[int], List[str]]]"] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[
-                            "Optional[Union[list[int], list[str]]]"
-                        ] = mc2
+                    json2: Mapped["Optional[Union[list[int], list[str]]]"] = (
+                        mc2
+                    )
                 elif option.union_none:
                     json: Mapped[Union[List[int], List[str], None]] = mc
-                    if testing.requires.python310.enabled:
-                        json2: Mapped[Union[None, list[int], list[str]]] = mc2
+                    json2: Mapped[Union[None, list[int], list[str]]] = mc2
                 elif option.pep604:
                     json: Mapped[list[int] | list[str] | None] = mc
                     json2: Mapped[None | list[int] | list[str]] = mc2
@@ -2634,9 +2578,7 @@ class MappedColumnTest(fixtures.TestBase, testing.AssertsCompiledSQL):
                 id: Mapped[int] = mapped_column(primary_key=True)
                 data: Mapped[int_sub]
 
-    @testing.variation(
-        "dict_key", ["typing", ("plain", testing.requires.python310)]
-    )
+    @testing.variation("dict_key", ["typing", "plain"])
     def test_type_dont_mis_resolve_on_non_generic(self, dict_key):
         """test for #8859.
 
@@ -3293,9 +3235,9 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         "datatype",
         [
             "typing_sequence",
-            ("collections_sequence", testing.requires.python310),
+            "collections_sequence",
             "typing_mutable_sequence",
-            ("collections_mutable_sequence", testing.requires.python310),
+            "collections_mutable_sequence",
         ],
     )
     @testing.variation("include_explicit", [True, False])
@@ -3379,12 +3321,7 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
 
     @testing.variation(
         "collection_type",
-        [
-            ("list", testing.requires.python310),
-            "List",
-            ("set", testing.requires.python310),
-            "Set",
-        ],
+        ["list", "List", "set", "Set"],
     )
     def test_14_style_anno_accepted_w_allow_unmapped(self, collection_type):
         """test for #8692 and #10385"""
@@ -3444,7 +3381,7 @@ class RelationshipLHSTest(fixtures.TestBase, testing.AssertsCompiledSQL):
         ("optional",),
         ("optional_fwd_ref",),
         ("union_none",),
-        ("pep604", testing.requires.python310),
+        ("pep604",),
         argnames="optional_on_m2o",
     )
     def test_basic_bidirectional(self, decl_base, optional_on_m2o):
index 4bd353b84fd139e64f54870abd89875ec51ee1cb..8f595bcaeb8eae983a39a0ba335175850d4c0726 100644 (file)
@@ -1164,10 +1164,8 @@ class EmbeddedSubqTest(
                 testing.skip_test("python platform not available")
             elif util.py311:
                 int_within_variance(39996, total_size(ck), 0.05)
-            elif util.py310:
-                int_within_variance(29796, total_size(ck), 0.05)
             else:
-                testing.skip_test("python platform not available")
+                int_within_variance(29796, total_size(ck), 0.05)
 
 
 class WithExpresionLoaderOptTest(DeclarativeMappedTest):
index a52a5ddacde370ea3f3cadd3d359f8dc3047211d..d70364c4d57487f7aaa451e51744ff69114a98e8 100644 (file)
@@ -424,7 +424,7 @@ class MiscDeprecationsTest(fixtures.TestBase):
 
     @testing.combinations(
         ("init", True),
-        ("kw_only", True, testing.requires.python310),
+        ("kw_only", True),
         ("default", 5),
         ("default_factory", lambda: 10),
         argnames="paramname, value",
@@ -436,7 +436,6 @@ class MiscDeprecationsTest(fixtures.TestBase):
         ):
             column_property(column("q"), **{paramname: value})
 
-    @testing.requires.python310
     def test_column_property_dc_attributes_still_function(self, dc_decl_base):
         with expect_deprecated(
             r"The column_property.init parameter is deprecated "