]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix inferred type of async_sessionmaker
authorSam Bull <aa6bs0@sambull.org>
Sun, 20 Nov 2022 00:38:04 +0000 (19:38 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 21 Nov 2022 17:01:56 +0000 (12:01 -0500)
Improved the typing for :class:`.sessionmaker` and
:class:`.asyncsessionmaker`, so that the default type of their return value
will be :class:`.Session` or :class:`.AsyncSession`, without the need to
type this explicitly. Previously, Mypy would not automaticaly infer these
return types from its generic base.

As part of this change, arguments for :class:`.Session`,
:class:`.AsyncSession`, :class:`.sessionmaker` and
:class:`.asyncsessionmaker` beyond the initial "bind" argument have been
made keyword-only, which includes parameters that have always been
documented as keyword arguments, such as :paramref:`.Session.autoflush`,
:paramref:`.Session.class_`, etc.

Pull request courtesy Sam Bull.

Closes: #8842
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8842
Pull-request-sha: fa6d1a8468e98b40e12f82ed7ddaddc1fde060ac

Change-Id: Iaaabc4572a87489d61617d970f62b9b50db4fac7

doc/build/changelog/unreleased_20/8842.rst [new file with mode: 0644]
lib/sqlalchemy/ext/asyncio/session.py
lib/sqlalchemy/orm/session.py
test/ext/mypy/plain_files/sessionmakers.py

diff --git a/doc/build/changelog/unreleased_20/8842.rst b/doc/build/changelog/unreleased_20/8842.rst
new file mode 100644 (file)
index 0000000..f7e5cb7
--- /dev/null
@@ -0,0 +1,19 @@
+.. change::
+    :tags: bug, typing
+    :tickets: 8842
+
+    Improved the typing for :class:`.sessionmaker` and
+    :class:`.asyncsessionmaker`, so that the default type of their return value
+    will be :class:`.Session` or :class:`.AsyncSession`, without the need to
+    type this explicitly. Previously, Mypy would not automaticaly infer these
+    return types from its generic base.
+
+    As part of this change, arguments for :class:`.Session`,
+    :class:`.AsyncSession`, :class:`.sessionmaker` and
+    :class:`.asyncsessionmaker` beyond the initial "bind" argument have been
+    made keyword-only, which includes parameters that have always been
+    documented as keyword arguments, such as :paramref:`.Session.autoflush`,
+    :paramref:`.Session.class_`, etc.
+
+    Pull request courtesy Sam Bull.
+
index 1956ea588ade60ff42c405b6b81adc65faa253e0..a74e877695d5dc6bb20a26dd711230b441ebcd04 100644 (file)
@@ -124,6 +124,7 @@ class AsyncSession(ReversibleProxy[Session]):
     def __init__(
         self,
         bind: Optional[_AsyncSessionBind] = None,
+        *,
         binds: Optional[Dict[_SessionBindKey, _AsyncSessionBind]] = None,
         sync_session_class: Optional[Type[Session]] = None,
         **kw: Any,
@@ -1436,9 +1437,35 @@ class async_sessionmaker(Generic[_AS]):
 
     class_: Type[_AS]
 
+    @overload
+    def __init__(
+        self,
+        bind: Optional[_AsyncSessionBind] = ...,
+        *,
+        class_: Type[_AS],
+        autoflush: bool = ...,
+        expire_on_commit: bool = ...,
+        info: Optional[_InfoType] = ...,
+        **kw: Any,
+    ):
+        ...
+
+    @overload
+    def __init__(
+        self: "async_sessionmaker[AsyncSession]",
+        bind: Optional[_AsyncSessionBind] = ...,
+        *,
+        autoflush: bool = ...,
+        expire_on_commit: bool = ...,
+        info: Optional[_InfoType] = ...,
+        **kw: Any,
+    ):
+        ...
+
     def __init__(
         self,
         bind: Optional[_AsyncSessionBind] = None,
+        *,
         class_: Type[_AS] = AsyncSession,  # type: ignore
         autoflush: bool = True,
         expire_on_commit: bool = True,
index 849d37ab227375e73627396bd48c108f932f2b17..15cd587926a7121a8f0ae209e80b856127733ce9 100644 (file)
@@ -1362,6 +1362,7 @@ class Session(_SessionClassMethods, EventTarget):
     def __init__(
         self,
         bind: Optional[_SessionBind] = None,
+        *,
         autoflush: bool = True,
         future: Literal[True] = True,
         expire_on_commit: bool = True,
@@ -4621,9 +4622,35 @@ class sessionmaker(_SessionClassMethods, Generic[_S]):
 
     class_: Type[_S]
 
+    @overload
+    def __init__(
+        self,
+        bind: Optional[_SessionBind] = ...,
+        *,
+        class_: Type[_S],
+        autoflush: bool = ...,
+        expire_on_commit: bool = ...,
+        info: Optional[_InfoType] = ...,
+        **kw: Any,
+    ):
+        ...
+
+    @overload
+    def __init__(
+        self: "sessionmaker[Session]",
+        bind: Optional[_SessionBind] = ...,
+        *,
+        autoflush: bool = ...,
+        expire_on_commit: bool = ...,
+        info: Optional[_InfoType] = ...,
+        **kw: Any,
+    ):
+        ...
+
     def __init__(
         self,
         bind: Optional[_SessionBind] = None,
+        *,
         class_: Type[_S] = Session,  # type: ignore
         autoflush: bool = True,
         expire_on_commit: bool = True,
index ce9b766385bcae266633a9444b7ea09aacc0cea3..2d02f2a3f43f27ab8757a47acf16dd39a2b16ac7 100644 (file)
@@ -86,3 +86,27 @@ def main() -> None:
     sess = scoped_fac()
     # EXPECTED_TYPE: MySession
     reveal_type(sess)
+
+
+def test_8837_sync() -> None:
+    sm = sessionmaker()
+
+    # EXPECTED_TYPE: sessionmaker[Session]
+    reveal_type(sm)
+
+    session = sm()
+
+    # EXPECTED_TYPE: Session
+    reveal_type(session)
+
+
+def test_8837_async() -> None:
+    as_ = async_sessionmaker()
+
+    # EXPECTED_TYPE: async_sessionmaker[AsyncSession]
+    reveal_type(as_)
+
+    async_session = as_()
+
+    # EXPECTED_TYPE: AsyncSession
+    reveal_type(async_session)