]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
add correct descriptor methods to dynamic/writeonly
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 20 Jun 2023 14:11:14 +0000 (10:11 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 21 Jun 2023 17:07:31 +0000 (13:07 -0400)
Fixed typing issue which prevented :class:`_orm.WriteOnlyMapped` and
:class:`_orm.DynamicMapped` attributes from being used fully within ORM
queries.

Fixes: #9985
Change-Id: I33eef4d06fc84e85f2ea1a997a017ffce47df7d6

doc/build/changelog/unreleased_20/9985.rst [new file with mode: 0644]
lib/sqlalchemy/orm/base.py
test/ext/mypy/plain_files/dynamic_rel.py
test/ext/mypy/plain_files/write_only.py

diff --git a/doc/build/changelog/unreleased_20/9985.rst b/doc/build/changelog/unreleased_20/9985.rst
new file mode 100644 (file)
index 0000000..243fb6f
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, typing
+    :tickets: 9985
+
+    Fixed typing issue which prevented :class:`_orm.WriteOnlyMapped` and
+    :class:`_orm.DynamicMapped` attributes from being used fully within ORM
+    queries.
index 5d19cf20ad6ae69599f59188c99360bd1f244809..5079dfc7c53840f88bca490a6ba4d289403c3fec 100644 (file)
@@ -912,9 +912,19 @@ class DynamicMapped(_MappedAnnotationBase[_T]):
 
     if TYPE_CHECKING:
 
+        @overload
+        def __get__(
+            self, instance: None, owner: Any
+        ) -> InstrumentedAttribute[_T]:
+            ...
+
+        @overload
+        def __get__(self, instance: object, owner: Any) -> AppenderQuery[_T]:
+            ...
+
         def __get__(
             self, instance: Optional[object], owner: Any
-        ) -> AppenderQuery[_T]:
+        ) -> Union[InstrumentedAttribute[_T], AppenderQuery[_T]]:
             ...
 
         def __set__(self, instance: Any, value: typing.Collection[_T]) -> None:
@@ -954,10 +964,22 @@ class WriteOnlyMapped(_MappedAnnotationBase[_T]):
 
     if TYPE_CHECKING:
 
+        @overload
         def __get__(
-            self, instance: Optional[object], owner: Any
+            self, instance: None, owner: Any
+        ) -> InstrumentedAttribute[_T]:
+            ...
+
+        @overload
+        def __get__(
+            self, instance: object, owner: Any
         ) -> WriteOnlyCollection[_T]:
             ...
 
+        def __get__(
+            self, instance: Optional[object], owner: Any
+        ) -> Union[InstrumentedAttribute[_T], WriteOnlyCollection[_T]]:
+            ...
+
         def __set__(self, instance: Any, value: typing.Collection[_T]) -> None:
             ...
index 3aee8f320424bf160e872562bcddb03922880e88..8b406bb171e09f680f2dc177a9a02c90c20e11e7 100644 (file)
@@ -3,6 +3,7 @@ from __future__ import annotations
 import typing
 
 from sqlalchemy import ForeignKey
+from sqlalchemy import select
 from sqlalchemy.orm import DeclarativeBase
 from sqlalchemy.orm import DynamicMapped
 from sqlalchemy.orm import Mapped
@@ -80,3 +81,6 @@ with Session() as session:
     u.addresses.append(Address())
 
     session.commit()
+
+    # test #9985
+    stmt = select(User).join(User.addresses)
index 5d322a606bf1208e2cd125d88ecb287c597e8188..619cde74e8cadcf0439c8aa076cd800bdd473ab9 100644 (file)
@@ -3,6 +3,7 @@ from __future__ import annotations
 import typing
 
 from sqlalchemy import ForeignKey
+from sqlalchemy import select
 from sqlalchemy.orm import DeclarativeBase
 from sqlalchemy.orm import Mapped
 from sqlalchemy.orm import mapped_column
@@ -55,3 +56,6 @@ with Session() as session:
     u.addresses.add(Address())
 
     session.commit()
+
+    # test #9985
+    stmt = select(User).join(User.addresses)