]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add mypy ignore comments for Python 3.14 module imports
authorShamil Abdulaev <ashm.tech@proton.me>
Thu, 16 Apr 2026 18:56:23 +0000 (14:56 -0400)
committersqla-tester <sqla-tester@sqlalchemy.org>
Thu, 16 Apr 2026 18:56:23 +0000 (14:56 -0400)
Fixes #13240

Use `sys.version_info >= (3, 14)` instead of the `py314` variable for
the py314-only imports block (`annotationlib`, `string.templatelib`).

mypy has built-in support for `sys.version_info` guards and only
type-checks the reachable branch, while a plain variable like `py314`
causes mypy to check both branches — leading to `import-not-found` on
<3.14 and `unused-ignore` on 3.14 if `type: ignore` comments are added.

Closes: #13239
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13239
Pull-request-sha: f58bfc11694c71020b98ed69d8400a0173be096b

Change-Id: Ib5e2361e849a3f14f90d0da34800c1d31f8bf201

lib/sqlalchemy/sql/_elements_constructors.py
lib/sqlalchemy/util/compat.py

index 756789697962791f049376a080f270a9838d8841..5d596525d11f68950ba4663924bf104e57ffd2ab 100644 (file)
@@ -53,8 +53,6 @@ from .elements import WithinGroup
 from .functions import FunctionElement
 
 if typing.TYPE_CHECKING:
-    from string.templatelib import Template
-
     from ._typing import _ByArgument
     from ._typing import _ColumnExpressionArgument
     from ._typing import _ColumnExpressionOrLiteralArgument
@@ -66,6 +64,7 @@ if typing.TYPE_CHECKING:
     from .elements import FrameClause
     from .selectable import FromClause
     from .type_api import TypeEngine
+    from ..util.compat import Template
 
 _T = TypeVar("_T")
 
index ddf042a4742dbf72adb7129fedf083d50c03084b..38ff365628201f94479b1360ca8024640a287348 100644 (file)
@@ -31,7 +31,6 @@ from typing import Sequence
 from typing import Set
 from typing import Tuple
 from typing import Type
-from typing import TYPE_CHECKING
 
 py314b1 = sys.version_info >= (3, 14, 0, "beta", 1)
 py314 = sys.version_info >= (3, 14)
@@ -51,11 +50,24 @@ has_refcount_gc = bool(cpython)
 
 dottedgetter = operator.attrgetter
 
-if py314 or TYPE_CHECKING:
+
+# use sys.version_info to enable mypy version narrowing
+if sys.version_info >= (3, 14):
+
+    import annotationlib
     from string.templatelib import Template as Template
+
+    def get_annotations(obj: Any) -> Mapping[str, Any]:
+        return annotationlib.get_annotations(
+            obj, format=annotationlib.Format.FORWARDREF
+        )
+
 else:
 
-    class Template:  # type: ignore[no-redef]
+    def get_annotations(obj: Any) -> Mapping[str, Any]:
+        return inspect.get_annotations(obj)
+
+    class Template:
         """Minimal Template for Python < 3.14 (test usage only)."""
 
         def __init__(self, *parts: Any):
@@ -73,21 +85,6 @@ else:
             return iter(self._parts)
 
 
-if py314:
-
-    import annotationlib
-
-    def get_annotations(obj: Any) -> Mapping[str, Any]:
-        return annotationlib.get_annotations(
-            obj, format=annotationlib.Format.FORWARDREF
-        )
-
-else:
-
-    def get_annotations(obj: Any) -> Mapping[str, Any]:
-        return inspect.get_annotations(obj)
-
-
 class FullArgSpec(typing.NamedTuple):
     args: List[str]
     varargs: Optional[str]