]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix mypy error on scalar call with tuple[Any, ...] 13092/head
authorYurii Karabas <1998uriyyo@gmail.com>
Mon, 26 Jan 2026 23:46:40 +0000 (00:46 +0100)
committerYurii Karabas <1998uriyyo@gmail.com>
Tue, 27 Jan 2026 00:07:13 +0000 (01:07 +0100)
lib/sqlalchemy/engine/result.py [changed mode: 0644->0755]
test/typing/plain_files/sql/typed_results.py

old mode 100644 (file)
new mode 100755 (executable)
index 946f319..5c1cd85
@@ -47,6 +47,7 @@ from ..sql.base import _generative
 from ..sql.base import InPlaceGenerative
 from ..util import deprecated
 from ..util import NONE_SET
+from ..util.typing import Never
 from ..util.typing import Self
 from ..util.typing import TupleAny
 from ..util.typing import TypeVarTuple
@@ -1064,6 +1065,16 @@ class Result(_WithKeys, ResultInternal[Row[Unpack[_Ts]]]):
             raise_for_second_row=True, raise_for_none=True, scalar=False
         )
 
+    # special case to handle mypy issue:
+    # https://github.com/python/mypy/issues/20651
+    @overload
+    def scalar(self: Result[Never, Unpack[TupleAny]]) -> Optional[Any]:
+        pass
+
+    @overload
+    def scalar(self: Result[_T, Unpack[TupleAny]]) -> Optional[_T]:
+        pass
+
     def scalar(self: Result[_T, Unpack[TupleAny]]) -> Optional[_T]:
         """Fetch the first column of the first row, and close the result set.
 
index 98dde5ad9f7b98a77fb4de2f5a23d9961aadfbbd..8448bf9bb625f569f7009493f2e1da23ba75d86f 100644 (file)
@@ -6,11 +6,13 @@ from typing import assert_type
 from typing import cast
 from typing import Optional
 from typing import Sequence
+from typing import Tuple
 from typing import Type
 from typing import Unpack
 
 from sqlalchemy import Column
 from sqlalchemy import column
+from sqlalchemy import Connection
 from sqlalchemy import create_engine
 from sqlalchemy import func
 from sqlalchemy import insert
@@ -623,3 +625,36 @@ def test_outerjoin_10173() -> None:
         print(stmt4)
 
     print(stmt, stmt2, stmt3)
+
+
+def test_13091() -> None:
+    with e.connect() as conn:
+        stmt = select(t_user.c.id)
+        assert_type(stmt, Select[Unpack[Tuple[Any, ...]]])
+        result = conn.execute(stmt)
+
+        assert_type(result, CursorResult[Unpack[Tuple[Any, ...]]])
+        data = result.scalar()
+        assert_type(data, Any | None)
+
+
+def test_13091_2(
+    conn: Connection, table: Table, c: Column[int], c2: Column[str]
+) -> None:
+    assert_type(table.select(), Select[Unpack[Tuple[Any, ...]]])
+    r1 = conn.execute(table.select())
+    assert_type(r1, CursorResult[Unpack[Tuple[Any, ...]]])
+    d1 = r1.scalar()
+    assert_type(d1, Any | None)
+    r2 = conn.execute(select(table))
+    assert_type(r2, CursorResult[Unpack[Tuple[Any, ...]]])
+    d2 = r2.scalar()
+    assert_type(d2, Any | None)
+    r3 = conn.execute(select(c))
+    assert_type(r3, CursorResult[int])
+    d3 = r3.scalar()
+    assert_type(d3, int | None)
+    r4 = conn.execute(select(c, c2))
+    assert_type(r4, CursorResult[int, str])
+    d4 = r3.scalar()
+    assert_type(d4, int | None)