]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
add Mapped to _ORMColCollectionElement
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 26 Jan 2023 14:23:07 +0000 (09:23 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 26 Jan 2023 14:25:35 +0000 (09:25 -0500)
Fixed issue where using the :paramref:`_orm.relationship.remote_side`
and similar parameters, passing an annotated declarative object typed as
:class:`_orm.Mapped`, would not be accepted by the type checker.

Fixes: #9150
Change-Id: I5770c17ee4ad8c54661354da9582ec3c4706ffcc

doc/build/changelog/unreleased_20/more_typing.rst
lib/sqlalchemy/orm/relationships.py
test/ext/mypy/plain_files/experimental_relationship.py

index 62cd04e8b4d506377105955fc8681046a44fad4f..f7b1ba258da49b22fd9c4e11d0196007c1ad6b00 100644 (file)
     as a context manager were not preserved, indicating :class:`_engine.Result`
     in all cases rather than the specific :class:`_engine.Result` sub-type.
     Pull request courtesy Martin Baláž.
+
+.. change::
+    :tags: typing, bug
+    :tickets: 9150
+
+    Fixed issue where using the :paramref:`_orm.relationship.remote_side`
+    and similar parameters, passing an annotated declarative object typed as
+    :class:`_orm.Mapped`, would not be accepted by the type checker.
index 66d3a60355bf366e4c720533bdc1b1f1528c7764..05fa17a968263e8bf6b6b2744e5196a95c51576d 100644 (file)
@@ -175,7 +175,7 @@ _ORMOrderByArgument = Union[
 ORMBackrefArgument = Union[str, Tuple[str, Dict[str, Any]]]
 
 _ORMColCollectionElement = Union[
-    ColumnClause[Any], _HasClauseElement, roles.DMLColumnRole
+    ColumnClause[Any], _HasClauseElement, roles.DMLColumnRole, "Mapped[Any]"
 ]
 _ORMColCollectionArgument = Union[
     str,
index a8d81426e7d6714952a52928581d240d2e49999e..7acec89e1875e7959745c427f297fd9da0e38e8c 100644 (file)
@@ -1,6 +1,8 @@
 """this suite experiments with other kinds of relationship syntaxes.
 
 """
+from __future__ import annotations
+
 import typing
 from typing import List
 from typing import Optional
@@ -48,6 +50,28 @@ class Address(Base):
     user_style_two: Mapped["User"] = relationship()
 
 
+class SelfReferential(Base):
+    """test for #9150"""
+
+    __tablename__ = "MyTable"
+
+    idx: Mapped[int] = mapped_column(Integer, primary_key=True)
+    mytable_id: Mapped[int] = mapped_column(ForeignKey("MyTable.idx"))
+
+    not_anno = mapped_column(Integer)
+
+    selfref_1: Mapped[Optional[SelfReferential]] = relationship(
+        remote_side=idx
+    )
+    selfref_2: Mapped[Optional[SelfReferential]] = relationship(
+        foreign_keys=mytable_id
+    )
+
+    selfref_3: Mapped[Optional[SelfReferential]] = relationship(
+        remote_side=not_anno
+    )
+
+
 if typing.TYPE_CHECKING:
     # EXPECTED_RE_TYPE: sqlalchemy.*.InstrumentedAttribute\[Union\[builtins.str, None\]\]
     reveal_type(User.extra)