]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Unify doc typing
authorHarry Lees <harry.lees@gmail.com>
Tue, 31 Jan 2023 13:38:34 +0000 (08:38 -0500)
committermike bayer <mike_mp@zzzcomputing.com>
Tue, 31 Jan 2023 19:45:48 +0000 (19:45 +0000)
### Description
<!-- Describe your changes in detail -->

Fixes #9168

This PR replaces common occurrences of [PEP 585](https://peps.python.org/pep-0585/) style type annotations with annotations compatible with older versions of Python.

I searched for instances of the following supported types from the PEP and replaced with their legacy typing couterparts.

* tuple # typing.Tuple
* list # typing.List
* dict # typing.Dict
* set # typing.Set
* frozenset # typing.FrozenSet
* type # typing.Type

```
grep -r "list\[.*\]" ./build --exclude-dir="./build/venv/*" --exclude-dir="./build/output/*" --exclude="changelog_[0-9]*\.rst"
```

I excluded changelog files from being altered, I think some of these could be changed if necessary but others are likely to require manual checking as the change may target the new typing style specifically.

For any examples that included imports, I tried to ensure that the correct typing imports were included and properly ordered.

### Checklist
<!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once)

-->

This pull request is:

- [x] A documentation / typographical error fix
- Good to go, no issue or tests are needed
- [ ] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.
- [ ] A new feature implementation
- please include the issue number, and create an issue if none exists, which must
  include a complete example of how the feature would look.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.

Closes: #9198
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9198
Pull-request-sha: 05ad4651b57c6275b29433e5e76e166344ba6c4c

Change-Id: I41b93b3dee85f9fe00cfbb3d3eb011212795de29

19 files changed:
doc/build/changelog/changelog_20.rst
doc/build/changelog/migration_20.rst
doc/build/orm/basic_relationships.rst
doc/build/orm/collection_api.rst
doc/build/orm/declarative_styles.rst
doc/build/orm/extensions/associationproxy.rst
doc/build/orm/extensions/asyncio.rst
doc/build/orm/inheritance.rst
doc/build/orm/large_collections.rst
doc/build/orm/queryguide/_inheritance_setup.rst
doc/build/orm/queryguide/relationships.rst
doc/build/orm/quickstart.rst
doc/build/tutorial/orm_related_objects.rst
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/ext/associationproxy.py
lib/sqlalchemy/ext/asyncio/base.py
lib/sqlalchemy/ext/automap.py
lib/sqlalchemy/ext/mutable.py
lib/sqlalchemy/orm/decl_api.py

index a91a137981990c5da3d058272b88cd0a2cc43090..ae3b9eb342bb12966c8d09d6029ef5264a00b2ea 100644 (file)
         :tickets: 8777
 
         Fixed a suite of issues involving :class:`.Mapped` use with dictionary
-        types, such as ``Mapped[dict[str, str] | None]``, would not be correctly
+        types, such as ``Mapped[Dict[str, str] | None]``, would not be correctly
         interpreted in Declarative ORM mappings. Support to correctly
         "de-optionalize" this type including for lookup in ``type_annotation_map``
         has been fixed.
index 51e34955ee46328656eda5a41ad9c516121b172e..604d59e083beaa8f60d2182d02f403700e0d062b 100644 (file)
@@ -471,7 +471,7 @@ are subject to these errors, as would occur in the example below::
         id: int = Column(Integer, primary_key=True)
 
         # will raise
-        bars: list["Bar"] = relationship("Bar", back_populates="foo")
+        bars: List["Bar"] = relationship("Bar", back_populates="foo")
 
 
     class Bar(Base):
@@ -519,7 +519,7 @@ that descend from ``Base``::
 
         id: int = Column(Integer, primary_key=True)
 
-        bars: list["Bar"] = relationship("Bar", back_populates="foo")
+        bars: List["Bar"] = relationship("Bar", back_populates="foo")
 
 
     class Bar(Base):
index 28c1c65bfd9dc681e85191aee512e3be8b8daa76..eb4704f7e7b2a63066d3d2758a3fa05ae7da980d 100644 (file)
@@ -10,6 +10,7 @@ based on the use of the :class:`_orm.Mapped` annotation type.
 The setup for each of the following sections is as follows::
 
     from __future__ import annotations
+    from typing import List
 
     from sqlalchemy import ForeignKey
     from sqlalchemy import Integer
@@ -40,7 +41,7 @@ which is the most modern form of SQLAlchemy Declarative mapping::
         __tablename__ = "parent_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship(back_populates="parent")
+        children: Mapped[List["Child"]] = relationship(back_populates="parent")
 
 
     class Child(Base):
@@ -114,7 +115,7 @@ a collection of items represented by the child::
         __tablename__ = "parent_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship()
+        children: Mapped[List["Child"]] = relationship()
 
 
     class Child(Base):
@@ -134,7 +135,7 @@ as the value for :paramref:`_orm.relationship.back_populates` on the other::
         __tablename__ = "parent_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship(back_populates="parent")
+        children: Mapped[List["Child"]] = relationship(back_populates="parent")
 
 
     class Child(Base):
@@ -155,13 +156,13 @@ Using annotated Declarative mappings, the type of collection used for the
 :func:`_orm.relationship` is derived from the collection type passed to the
 :class:`_orm.Mapped` container type.  The example from the previous section
 may be written to use a ``set`` rather than a ``list`` for the
-``Parent.children`` collection using ``Mapped[set["Child"]]``::
+``Parent.children`` collection using ``Mapped[Set["Child"]]``::
 
     class Parent(Base):
         __tablename__ = "parent_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[set["Child"]] = relationship(back_populates="parent")
+        children: Mapped[Set["Child"]] = relationship(back_populates="parent")
 
 When using non-annotated forms including imperative mappings, the Python
 class to use as a collection may be passed using the
@@ -236,7 +237,7 @@ as the value for :paramref:`_orm.relationship.back_populates` on the other::
         __tablename__ = "child_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        parents: Mapped[list["Parent"]] = relationship(back_populates="child")
+        parents: Mapped[List["Parent"]] = relationship(back_populates="child")
 
 .. _relationship_patterns_nullable_m2o:
 
@@ -265,7 +266,7 @@ case the configuration would look like::
         __tablename__ = "child_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        parents: Mapped[list["Parent"]] = relationship(back_populates="child")
+        parents: Mapped[List["Parent"]] = relationship(back_populates="child")
 
 Above, the column for ``Parent.child_id`` will be created in DDL to allow
 ``NULL`` values. When using :func:`_orm.mapped_column` with explicit typing
@@ -297,7 +298,7 @@ for background on this behavior.
           __tablename__ = "child_table"
 
           id: Mapped[int] = mapped_column(primary_key=True)
-          parents: Mapped[list[Parent]] = relationship(back_populates="child")
+          parents: Mapped[List[Parent]] = relationship(back_populates="child")
 
 .. _relationships_one_to_one:
 
@@ -423,7 +424,7 @@ with which to link::
         __tablename__ = "left_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list[Child]] = relationship(secondary=association_table)
+        children: Mapped[List[Child]] = relationship(secondary=association_table)
 
 
     class Child(Base):
@@ -485,7 +486,7 @@ for each :func:`_orm.relationship` specify the common association table::
         __tablename__ = "left_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list[Child]] = relationship(
+        children: Mapped[List[Child]] = relationship(
             secondary=association_table, back_populates="parents"
         )
 
@@ -494,7 +495,7 @@ for each :func:`_orm.relationship` specify the common association table::
         __tablename__ = "right_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        parents: Mapped[list[Parent]] = relationship(
+        parents: Mapped[List[Parent]] = relationship(
             secondary=association_table, back_populates="children"
         )
 
@@ -522,7 +523,7 @@ such as ``set``::
         __tablename__ = "left_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[set["Child"]] = relationship(secondary=association_table)
+        children: Mapped[Set["Child"]] = relationship(secondary=association_table)
 
 When using non-annotated forms including imperative mappings, as is
 the case with one-to-many, the Python
@@ -650,7 +651,7 @@ from ``Parent`` to ``Child`` makes explicit use of ``Association``::
     class Parent(Base):
         __tablename__ = "left_table"
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Association"]] = relationship()
+        children: Mapped[List["Association"]] = relationship()
 
 
     class Child(Base):
@@ -688,13 +689,13 @@ constructs, linked to the existing ones using :paramref:`_orm.relationship.back_
     class Parent(Base):
         __tablename__ = "left_table"
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Association"]] = relationship(back_populates="parent")
+        children: Mapped[List["Association"]] = relationship(back_populates="parent")
 
 
     class Child(Base):
         __tablename__ = "right_table"
         id: Mapped[int] = mapped_column(primary_key=True)
-        parents: Mapped[list["Association"]] = relationship(back_populates="child")
+        parents: Mapped[List["Association"]] = relationship(back_populates="child")
 
 Working with the association pattern in its direct form requires that child
 objects are associated with an association instance before being appended to
@@ -789,12 +790,12 @@ and ``Child.parent_associations -> Association.parent``::
         id: Mapped[int] = mapped_column(primary_key=True)
 
         # many-to-many relationship to Child, bypassing the `Association` class
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             secondary="association_table", back_populates="parents"
         )
 
         # association between Parent -> Association -> Child
-        child_associations: Mapped[list["Association"]] = relationship(
+        child_associations: Mapped[List["Association"]] = relationship(
             back_populates="parent"
         )
 
@@ -805,12 +806,12 @@ and ``Child.parent_associations -> Association.parent``::
         id: Mapped[int] = mapped_column(primary_key=True)
 
         # many-to-many relationship to Parent, bypassing the `Association` class
-        parents: Mapped[list["Parent"]] = relationship(
+        parents: Mapped[List["Parent"]] = relationship(
             secondary="association_table", back_populates="children"
         )
 
         # association between Child -> Association -> Parent
-        parent_associations: Mapped[list["Association"]] = relationship(
+        parent_associations: Mapped[List["Association"]] = relationship(
             back_populates="child"
         )
 
@@ -858,12 +859,12 @@ additional association columns, as below::
         id: Mapped[int] = mapped_column(primary_key=True)
 
         # many-to-many relationship to Child, bypassing the `Association` class
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             secondary="association_table", back_populates="parents", viewonly=True
         )
 
         # association between Parent -> Association -> Child
-        child_associations: Mapped[list["Association"]] = relationship(
+        child_associations: Mapped[List["Association"]] = relationship(
             back_populates="parent"
         )
 
@@ -874,12 +875,12 @@ additional association columns, as below::
         id: Mapped[int] = mapped_column(primary_key=True)
 
         # many-to-many relationship to Parent, bypassing the `Association` class
-        parents: Mapped[list["Parent"]] = relationship(
+        parents: Mapped[List["Parent"]] = relationship(
             secondary="association_table", back_populates="children", viewonly=True
         )
 
         # association between Child -> Association -> Parent
-        parent_associations: Mapped[list["Association"]] = relationship(
+        parent_associations: Mapped[List["Association"]] = relationship(
             back_populates="child"
         )
 
@@ -919,7 +920,7 @@ at runtime only as a string::
     class Parent(Base):
         # ...
 
-        children: Mapped[list["Child"]] = relationship(back_populates="parent")
+        children: Mapped[List["Child"]] = relationship(back_populates="parent")
 
 
     class Child(Base):
@@ -971,7 +972,7 @@ package, including expression functions like :func:`_sql.desc` and
     class Parent(Base):
         # ...
 
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             order_by="desc(Child.email_address)",
             primaryjoin="Parent.id == Child.parent_id",
         )
@@ -983,7 +984,7 @@ within any of these string expressions::
     class Parent(Base):
         # ...
 
-        children: Mapped[list["myapp.mymodel.Child"]] = relationship(
+        children: Mapped[List["myapp.mymodel.Child"]] = relationship(
             order_by="desc(myapp.mymodel.Child.email_address)",
             primaryjoin="myapp.mymodel.Parent.id == myapp.mymodel.Child.parent_id",
         )
@@ -1004,7 +1005,7 @@ name within the :class:`_orm.registry`::
     class Parent(Base):
         # ...
 
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             "myapp.mymodel.Child",
             order_by="desc(myapp.mymodel.Child.email_address)",
             primaryjoin="myapp.mymodel.Parent.id == myapp.mymodel.Child.parent_id",
@@ -1018,7 +1019,7 @@ we can specify ``model1.Child`` or ``model2.Child``::
     class Parent(Base):
         # ...
 
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             "model1.Child",
             order_by="desc(mymodel1.Child.email_address)",
             primaryjoin="Parent.id == model1.Child.parent_id",
@@ -1045,7 +1046,7 @@ like the following::
     class Parent(Base):
         # ...
 
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             _resolve_child_model(),
             order_by=lambda: desc(_resolve_child_model().email_address),
             primaryjoin=lambda: Parent.id == _resolve_child_model().parent_id,
@@ -1151,7 +1152,7 @@ using a lambda as::
         __tablename__ = "left_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship(
+        children: Mapped[List["Child"]] = relationship(
             "Child", secondary=lambda: association_table
         )
 
@@ -1165,7 +1166,7 @@ the :class:`.MetaData` collection::
         __tablename__ = "left_table"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship(secondary="association_table")
+        children: Mapped[List["Child"]] = relationship(secondary="association_table")
 
 .. warning:: When passed as a string,
     :paramref:`_orm.relationship.secondary` argument is interpreted using Python's
index aba0ca104c8c42871ed79ae41e244f8afa4af29e..2d56bb9b2b083d775e076c6d4bcc2d426c2d47f1 100644 (file)
@@ -47,7 +47,7 @@ below where ``list`` is used::
         parent_id: Mapped[int] = mapped_column(primary_key=True)
 
         # use a list
-        children: Mapped[list["Child"]] = relationship()
+        children: Mapped[List["Child"]] = relationship()
 
 
     class Child(Base):
@@ -59,6 +59,7 @@ below where ``list`` is used::
 Or for a ``set``, illustrated in the same
 ``Parent.children`` collection::
 
+    from typing import Set
     from sqlalchemy import ForeignKey
 
     from sqlalchemy.orm import DeclarativeBase
@@ -77,7 +78,7 @@ Or for a ``set``, illustrated in the same
         parent_id: Mapped[int] = mapped_column(primary_key=True)
 
         # use a set
-        children: Mapped[set["Child"]] = relationship()
+        children: Mapped[Set["Child"]] = relationship()
 
 
     class Child(Base):
@@ -154,6 +155,7 @@ the :paramref:`_orm.relationship.collection_class` parameter
 is required in this case so that the :func:`.attribute_keyed_dict`
 may be appropriately parametrized::
 
+    from typing import Dict
     from typing import Optional
 
     from sqlalchemy import ForeignKey
@@ -173,7 +175,7 @@ may be appropriately parametrized::
 
         id: Mapped[int] = mapped_column(primary_key=True)
 
-        notes: Mapped[dict[str, "Note"]] = relationship(
+        notes: Mapped[Dict[str, "Note"]] = relationship(
             collection_class=attribute_keyed_dict("keyword"),
             cascade="all, delete-orphan",
         )
@@ -220,7 +222,7 @@ of the ``Note.text`` field::
 
         id: Mapped[int] = mapped_column(primary_key=True)
 
-        notes: Mapped[dict[str, "Note"]] = relationship(
+        notes: Mapped[Dict[str, "Note"]] = relationship(
             collection_class=attribute_keyed_dict("note_key"),
             back_populates="item",
             cascade="all, delete-orphan",
@@ -268,7 +270,7 @@ object directly::
 
         id: Mapped[int] = mapped_column(primary_key=True)
 
-        notes: Mapped[dict[str, "Note"]] = relationship(
+        notes: Mapped[Dict[str, "Note"]] = relationship(
             collection_class=column_keyed_dict(Note.__table__.c.keyword),
             cascade="all, delete-orphan",
         )
@@ -285,7 +287,7 @@ with a ``@property`` as mentioned earlier::
 
         id: Mapped[int] = mapped_column(primary_key=True)
 
-        notes: Mapped[dict[str, "Note"]] = relationship(
+        notes: Mapped[Dict[str, "Note"]] = relationship(
             collection_class=mapped_collection(lambda note: note.text[0:10]),
             cascade="all, delete-orphan",
         )
@@ -311,7 +313,7 @@ to populate an attribute mapped collection.  Given the following::
 
         id: Mapped[int] = mapped_column(primary_key=True)
 
-        bs: Mapped[dict[str, "B"]] = relationship(
+        bs: Mapped[Dict[str, "B"]] = relationship(
             collection_class=attribute_keyed_dict("data"),
             back_populates="a",
         )
index b644ac41817c2c7f02b3ce2af815469f89922581..a02391004b5a36e9948496c9bb103d22e2314351 100644 (file)
@@ -75,7 +75,7 @@ of the base::
         nickname: Mapped[Optional[str]] = mapped_column(String(64))
         create_date: Mapped[datetime] = mapped_column(insert_default=func.now())
 
-        addresses: Mapped[list["Address"]] = relationship(back_populates="user")
+        addresses: Mapped[List["Address"]] = relationship(back_populates="user")
 
 
     class Address(Base):
@@ -126,6 +126,7 @@ previous section, using the :meth:`_orm.registry.mapped`
 decorator rather than using the :class:`_orm.DeclarativeBase` superclass::
 
     from datetime import datetime
+    from typing import List
     from typing import Optional
 
     from sqlalchemy import ForeignKey
@@ -150,7 +151,7 @@ decorator rather than using the :class:`_orm.DeclarativeBase` superclass::
         nickname: Mapped[Optional[str]] = mapped_column(String(64))
         create_date: Mapped[datetime] = mapped_column(insert_default=func.now())
 
-        addresses: Mapped[list["Address"]] = relationship(back_populates="user")
+        addresses: Mapped[List["Address"]] = relationship(back_populates="user")
 
 
     @mapper_registry.mapped
index 0f96c955d66623303d2cb9e68ebc0da4c7e8da94..fda09327215eb3f1fdf6bd52f7ccca7862310cb7 100644 (file)
@@ -52,13 +52,13 @@ exception of an extra attribute added to the ``User`` class called
         __tablename__ = "user"
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str] = mapped_column(String(64))
-        kw: Mapped[list[Keyword]] = relationship(secondary=lambda: user_keyword_table)
+        kw: Mapped[List[Keyword]] = relationship(secondary=lambda: user_keyword_table)
 
         def __init__(self, name: str):
             self.name = name
 
         # proxy the 'keyword' attribute from the 'kw' relationship
-        keywords: AssociationProxy[list[str]] = association_proxy("kw", "keyword")
+        keywords: AssociationProxy[List[str]] = association_proxy("kw", "keyword")
 
 
     class Keyword(Base):
@@ -150,7 +150,7 @@ using a lambda as is typical::
         ...
 
         # use Keyword(keyword=kw) on append() events
-        keywords: AssociationProxy[list[str]] = association_proxy(
+        keywords: AssociationProxy[List[str]] = association_proxy(
             "kw", "keyword", creator=lambda kw: Keyword(keyword=kw)
         )
 
@@ -203,14 +203,14 @@ collection of ``User`` to the ``.keyword`` attribute present on each
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str] = mapped_column(String(64))
 
-        user_keyword_associations: Mapped[list[UserKeywordAssociation]] = relationship(
+        user_keyword_associations: Mapped[List[UserKeywordAssociation]] = relationship(
             back_populates="user",
             cascade="all, delete-orphan",
         )
 
         # association proxy of "user_keyword_associations" collection
         # to "keyword" attribute
-        keywords: AssociationProxy[list[Keyword]] = association_proxy(
+        keywords: AssociationProxy[List[Keyword]] = association_proxy(
             "user_keyword_associations",
             "keyword",
             creator=lambda keyword: UserKeywordAssociation(keyword=Keyword(keyword)),
@@ -315,6 +315,7 @@ argument to the ``User.keywords`` proxy so that these values are assigned approp
 when new elements are added to the dictionary::
 
     from __future__ import annotations
+    from typing import Dict
 
     from sqlalchemy import ForeignKey
     from sqlalchemy import String
@@ -338,7 +339,7 @@ when new elements are added to the dictionary::
 
         # user/user_keyword_associations relationship, mapping
         # user_keyword_associations with a dictionary against "special_key" as key.
-        user_keyword_associations: Mapped[dict[str, UserKeywordAssociation]] = relationship(
+        user_keyword_associations: Mapped[Dict[str, UserKeywordAssociation]] = relationship(
             back_populates="user",
             collection_class=attribute_keyed_dict("special_key"),
             cascade="all, delete-orphan",
@@ -346,7 +347,7 @@ when new elements are added to the dictionary::
         # proxy to 'user_keyword_associations', instantiating
         # UserKeywordAssociation assigning the new key to 'special_key',
         # values to 'keyword'.
-        keywords: AssociationProxy[dict[str, Keyword]] = association_proxy(
+        keywords: AssociationProxy[Dict[str, Keyword]] = association_proxy(
             "user_keyword_associations",
             "keyword",
             creator=lambda k, v: UserKeywordAssociation(special_key=k, keyword=v),
@@ -426,14 +427,14 @@ present on ``UserKeywordAssociation``::
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str] = mapped_column(String(64))
 
-        user_keyword_associations: Mapped[dict[str, UserKeywordAssociation]] = relationship(
+        user_keyword_associations: Mapped[Dict[str, UserKeywordAssociation]] = relationship(
             back_populates="user",
             collection_class=attribute_keyed_dict("special_key"),
             cascade="all, delete-orphan",
         )
         # the same 'user_keyword_associations'->'keyword' proxy as in
         # the basic dictionary example.
-        keywords: AssociationProxy[dict[str, str]] = association_proxy(
+        keywords: AssociationProxy[Dict[str, str]] = association_proxy(
             "user_keyword_associations",
             "keyword",
             creator=lambda k, v: UserKeywordAssociation(special_key=k, keyword=v),
@@ -458,7 +459,7 @@ present on ``UserKeywordAssociation``::
 
         # 'keyword' is changed to be a proxy to the
         # 'keyword' attribute of 'Keyword'
-        keyword: AssociationProxy[dict[str, str]] = association_proxy("kw", "keyword")
+        keyword: AssociationProxy[Dict[str, str]] = association_proxy("kw", "keyword")
 
 
     class Keyword(Base):
@@ -547,7 +548,7 @@ to a related object, as in the example mapping below::
         )
 
         # column-targeted association proxy
-        special_keys: AssociationProxy[list[str]] = association_proxy(
+        special_keys: AssociationProxy[List[str]] = association_proxy(
             "user_keyword_associations", "special_key"
         )
 
index 45da8ef36e5b23b51df4a4803f0c8626168c016e..94aa609145340b776951eb537f504f6b1344b1fa 100644 (file)
@@ -150,6 +150,7 @@ illustrates a complete example including mapper and session configuration::
 
     import asyncio
     import datetime
+    from typing import List
 
     from sqlalchemy import ForeignKey
     from sqlalchemy import func
@@ -174,7 +175,7 @@ illustrates a complete example including mapper and session configuration::
         id: Mapped[int] = mapped_column(primary_key=True)
         data: Mapped[str]
         create_date: Mapped[datetime.datetime] = mapped_column(server_default=func.now())
-        bs: Mapped[list[B]] = relationship()
+        bs: Mapped[List[B]] = relationship()
 
 
     class B(Base):
index d35967e4ca5086f1f8973dee67a66584c21e7a95..e99bc1df62ccea9380d2c4160bdb7caf14505b75 100644 (file)
@@ -186,7 +186,7 @@ and ``Employee``::
         __tablename__ = "company"
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str]
-        employees: Mapped[list[Employee]] = relationship(back_populates="company")
+        employees: Mapped[List[Employee]] = relationship(back_populates="company")
 
 
     class Employee(Base):
@@ -220,7 +220,7 @@ established between the ``Manager`` and ``Company`` classes::
         __tablename__ = "company"
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str]
-        managers: Mapped[list[Manager]] = relationship(back_populates="company")
+        managers: Mapped[List[Manager]] = relationship(back_populates="company")
 
 
     class Employee(Base):
@@ -481,7 +481,7 @@ relationship::
         __tablename__ = "company"
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str]
-        employees: Mapped[list[Employee]] = relationship(back_populates="company")
+        employees: Mapped[List[Employee]] = relationship(back_populates="company")
 
 
     class Employee(Base):
@@ -522,7 +522,7 @@ or subclasses::
         __tablename__ = "company"
         id: Mapped[int] = mapped_column(primary_key=True)
         name: Mapped[str]
-        managers: Mapped[list[Manager]] = relationship(back_populates="company")
+        managers: Mapped[List[Manager]] = relationship(back_populates="company")
 
 
     class Employee(Base):
index 8553fae42e56d7667569375c9545dac32ddd94c0..afe3c506c9599c5419edb98e02573082036baed0 100644 (file)
@@ -631,7 +631,7 @@ emit a lazy load::
 
         # ...
 
-        children: Mapped[list[MyRelatedClass]] = relationship(lazy="raise")
+        children: Mapped[List[MyRelatedClass]] = relationship(lazy="raise")
 
 Above, attribute access on the ``children`` collection will raise an exception
 if it was not previously populated.  This includes read access but for
index c98a83035a0bf62088039fe1eee4bb5a5c9a9d43..e429b179f25b008c69bae76a51e597400a94f683 100644 (file)
@@ -11,6 +11,7 @@ the :ref:`queryguide_toplevel`.
 ..  sourcecode:: python
 
 
+    >>> from typing import List
     >>> from sqlalchemy import create_engine
     >>> from sqlalchemy import ForeignKey
     >>> from sqlalchemy.orm import DeclarativeBase
@@ -26,7 +27,7 @@ the :ref:`queryguide_toplevel`.
     ...     __tablename__ = "company"
     ...     id: Mapped[int] = mapped_column(primary_key=True)
     ...     name: Mapped[str]
-    ...     employees: Mapped[list["Employee"]] = relationship(back_populates="company")
+    ...     employees: Mapped[List["Employee"]] = relationship(back_populates="company")
     >>>
     >>> class Employee(Base):
     ...     __tablename__ = "employee"
@@ -48,7 +49,7 @@ the :ref:`queryguide_toplevel`.
     ...     __tablename__ = "manager"
     ...     id: Mapped[int] = mapped_column(ForeignKey("employee.id"), primary_key=True)
     ...     manager_name: Mapped[str]
-    ...     paperwork: Mapped[list["Paperwork"]] = relationship()
+    ...     paperwork: Mapped[List["Paperwork"]] = relationship()
     ...     __mapper_args__ = {
     ...         "polymorphic_identity": "manager",
     ...     }
index 593fe995b2077363fd0070757bfd24f248da9d1c..9c621ea9ac1107e66a63d51f2747e0accea72b04 100644 (file)
@@ -124,6 +124,8 @@ The example below illustrates the relationship example at
 relationship to use :ref:`selectin_eager_loading` when a SELECT
 statement for ``Parent`` objects is emitted::
 
+    from typing import List
+
     from sqlalchemy import ForeignKey
     from sqlalchemy.orm import DeclarativeBase
     from sqlalchemy.orm import Mapped
@@ -139,7 +141,7 @@ statement for ``Parent`` objects is emitted::
         __tablename__ = "parent"
 
         id: Mapped[int] = mapped_column(primary_key=True)
-        children: Mapped[list["Child"]] = relationship(lazy="selectin")
+        children: Mapped[List["Child"]] = relationship(lazy="selectin")
 
 
     class Child(Base):
index a4531e8d345eb0a56ce4c33a56600e3fdc3d91d2..eee91358803320ec3163010c9d2d08bc98eb16c1 100644 (file)
@@ -27,6 +27,7 @@ which we will be querying from the database.  This structure, known as a
 Python object model, as well as :term:`database metadata` that describes
 real SQL tables that exist, or will exist, in a particular database::
 
+    >>> from typing import List
     >>> from typing import Optional
     >>> from sqlalchemy import ForeignKey
     >>> from sqlalchemy import String
@@ -45,7 +46,7 @@ real SQL tables that exist, or will exist, in a particular database::
     ...     name: Mapped[str] = mapped_column(String(30))
     ...     fullname: Mapped[Optional[str]]
     ...
-    ...     addresses: Mapped[list["Address"]] = relationship(
+    ...     addresses: Mapped[List["Address"]] = relationship(
     ...         back_populates="user", cascade="all, delete-orphan"
     ...     )
     ...
index bd1fae131c98a53adf9fe4710a971ae17df7b5cb..902881c782172c3491303fce0db7494c218a8b92 100644 (file)
@@ -34,7 +34,7 @@ and other directives:
 
         # ... mapped_column() mappings
 
-        addresses: Mapped[list["Address"]] = relationship(back_populates="user")
+        addresses: Mapped[List["Address"]] = relationship(back_populates="user")
 
 
     class Address(Base):
@@ -400,7 +400,7 @@ the :paramref:`_orm.relationship.lazy` option, e.g.:
     class User(Base):
         __tablename__ = "user_account"
 
-        addresses: Mapped[list["Address"]] = relationship(
+        addresses: Mapped[List["Address"]] = relationship(
             back_populates="user", lazy="selectin"
         )
 
@@ -629,7 +629,7 @@ relationship will never try to emit SQL:
     >>> class User(Base):
     ...     __tablename__ = "user_account"
     ...     id: Mapped[int] = mapped_column(primary_key=True)
-    ...     addresses: Mapped[list["Address"]] = relationship(
+    ...     addresses: Mapped[List["Address"]] = relationship(
     ...         back_populates="user", lazy="raise_on_sql"
     ...     )
 
index 00929758368bb05b465af69860f45cddcb44d277..d7e6634b313c40e87ff3b1e63ab9925f30f4ed2b 100644 (file)
@@ -1428,6 +1428,7 @@ import re
 from typing import Any
 from typing import List
 from typing import Optional
+from typing import Tuple
 
 from . import array as _array
 from . import hstore as _hstore
@@ -3350,7 +3351,7 @@ class PGDialect(default.DefaultDialect):
         else:
             return False, {}
 
-    def _kind_to_relkinds(self, kind: ObjectKind) -> tuple[str, ...]:
+    def _kind_to_relkinds(self, kind: ObjectKind) -> Tuple[str, ...]:
         if kind is ObjectKind.ANY:
             return pg_catalog.RELKINDS_ALL_TABLE_LIKE
         relkinds = ()
index 29ff484b2c8707c07b885d05d597f627756b90e3..24f348bd1b650d74541206a258d02fcbe279bac0 100644 (file)
@@ -28,6 +28,7 @@ from typing import ItemsView
 from typing import Iterable
 from typing import Iterator
 from typing import KeysView
+from typing import List
 from typing import Mapping
 from typing import MutableMapping
 from typing import MutableSequence
@@ -1552,38 +1553,38 @@ class _AssociationList(_AssociationSingleItem[_T], MutableSequence[_T]):
     def __ne__(self, other: object) -> bool:
         return list(self) != other
 
-    def __lt__(self, other: list[_T]) -> bool:
+    def __lt__(self, other: List[_T]) -> bool:
         return list(self) < other
 
-    def __le__(self, other: list[_T]) -> bool:
+    def __le__(self, other: List[_T]) -> bool:
         return list(self) <= other
 
-    def __gt__(self, other: list[_T]) -> bool:
+    def __gt__(self, other: List[_T]) -> bool:
         return list(self) > other
 
-    def __ge__(self, other: list[_T]) -> bool:
+    def __ge__(self, other: List[_T]) -> bool:
         return list(self) >= other
 
-    def __add__(self, other: list[_T]) -> list[_T]:
+    def __add__(self, other: List[_T]) -> List[_T]:
         try:
             other = list(other)
         except TypeError:
             return NotImplemented
         return list(self) + other
 
-    def __radd__(self, other: list[_T]) -> list[_T]:
+    def __radd__(self, other: List[_T]) -> List[_T]:
         try:
             other = list(other)
         except TypeError:
             return NotImplemented
         return other + list(self)
 
-    def __mul__(self, n: SupportsIndex) -> list[_T]:
+    def __mul__(self, n: SupportsIndex) -> List[_T]:
         if not isinstance(n, int):
             return NotImplemented
         return list(self) * n
 
-    def __rmul__(self, n: SupportsIndex) -> list[_T]:
+    def __rmul__(self, n: SupportsIndex) -> List[_T]:
         if not isinstance(n, int):
             return NotImplemented
         return n * list(self)
@@ -1616,7 +1617,7 @@ class _AssociationList(_AssociationSingleItem[_T], MutableSequence[_T]):
             ls = list(self)
             return ls.index(value, *arg)
 
-    def copy(self) -> list[_T]:
+    def copy(self) -> List[_T]:
         return list(self)
 
     def __repr__(self) -> str:
@@ -1776,7 +1777,7 @@ class _AssociationDict(_AssociationCollection[_VT], MutableMapping[_KT, _VT]):
         for key in removals:
             del self[key]
 
-    def copy(self) -> dict[_KT, _VT]:
+    def copy(self) -> Dict[_KT, _VT]:
         return dict(self.items())
 
     def __hash__(self) -> NoReturn:
index 394c11263b73e4eb381ac8146b767d628cc7921b..765ee94a0fcc21674ef18da5a1c07b3d42691ee5 100644 (file)
@@ -21,6 +21,7 @@ from typing import Generic
 from typing import NoReturn
 from typing import Optional
 from typing import overload
+from typing import Tuple
 from typing import Type
 from typing import TypeVar
 import weakref
@@ -160,8 +161,8 @@ class GeneratorStartableContext(StartableContext[_T_co]):
     def __init__(
         self,
         func: Callable[..., AsyncIterator[_T_co]],
-        args: tuple[Any, ...],
-        kwds: dict[str, Any],
+        args: Tuple[Any, ...],
+        kwds: Dict[str, Any],
     ):
         self.gen = func(*args, **kwds)  # type: ignore
 
index 75bfbbc4dcd533d114dfa2ef1b421ec968d42430..0300152848a1b803e1e5f28f7a81f7a9dee068c8 100644 (file)
@@ -1232,14 +1232,10 @@ class AutomapBase:
                 )
             }
 
-            many_to_many: list[
-                tuple[
-                    Table,
-                    Table,
-                    list[ForeignKeyConstraint],
-                    Table,
-                ]
-            ] = []
+            many_to_many: List[
+                Tuple[Table, Table, List[ForeignKeyConstraint], Table]
+            ]
+            many_to_many = []
 
             bookkeeping = cls._sa_automapbase_bookkeeping
             metadata_tables = cls.metadata.tables
@@ -1430,7 +1426,7 @@ def _is_many_to_many(
     if len(fk_constraints) != 2:
         return None, None, None
 
-    cols: list[Column[Any]] = sum(
+    cols: List[Column[Any]] = sum(
         [
             [fk.parent for fk in fk_constraint.elements]
             for fk_constraint in fk_constraints
@@ -1488,7 +1484,7 @@ def _relationships_for_fks(
                 automap_base, referred_cls, local_cls, constraint
             )
 
-            o2m_kws: dict[str, Union[str, bool]] = {}
+            o2m_kws: Dict[str, Union[str, bool]] = {}
             nullable = False not in {fk.parent.nullable for fk in fks}
             if not nullable:
                 o2m_kws["cascade"] = "all, delete-orphan"
index 9ba2b5a15e0a5fc781586565de1c90a340c61f43..07f357bd6be830bb6d8d742cbb5777012bea2cec 100644 (file)
@@ -847,7 +847,7 @@ class MutableDict(Mutable, Dict[_KT, _VT]):
         else:
             return value
 
-    def __getstate__(self) -> dict[_KT, _VT]:
+    def __getstate__(self) -> Dict[_KT, _VT]:
         return dict(self)
 
     def __setstate__(
@@ -1051,7 +1051,7 @@ class MutableSet(Mutable, Set[_T]):
         else:
             return value
 
-    def __getstate__(self) -> set[_T]:
+    def __getstate__(self) -> Set[_T]:
         return set(self)
 
     def __setstate__(self, state: Iterable[_T]) -> None:
index a46c1a7fbb294695b8939bc2ea38f1b92f8d1a27..4a2d5fa21c2b16b98a32b3da87d657d94f3eb890 100644 (file)
@@ -380,7 +380,7 @@ class declared_attr(interfaces._MappedAttribute[_T], _declared_attr_common):
             type: Mapped[str] = mapped_column(String(50))
 
             @declared_attr.directive
-            def __mapper_args__(cls) -> dict[str, Any]:
+            def __mapper_args__(cls) -> Dict[str, Any]:
                 if cls.__name__ == 'Employee':
                     return {
                             "polymorphic_on":cls.type,