diff options
| author | Federico Caselli <cfederico87@gmail.com> | 2022-11-26 19:24:49 +0100 |
|---|---|---|
| committer | Federico Caselli <cfederico87@gmail.com> | 2022-11-26 19:25:37 +0100 |
| commit | 25c2b7dd105a6622eff2c7631d3c2d6eb978dc1f (patch) | |
| tree | 46ae527de593ddcbfcf115ca7d61edad9aa083b5 /lib/sqlalchemy/orm | |
| parent | 34e29f7b225cf1305e151af9d03ef95f42a9dbcc (diff) | |
| download | sqlalchemy-25c2b7dd105a6622eff2c7631d3c2d6eb978dc1f.tar.gz | |
Add new script to sync test files adding future annotation
Create a new test file test_tm_future_annotations_sync.py that's obtained
from test_tm_future_annotations.py by using the new script sync_test_files.
This files includes the ``from __future__ import annotations``
It also turns out we had some bugs in there and we can also support some
additional typing things
Change-Id: Iac005df206d45a55345d9d88d67a80ce799d449f
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/decl_base.py | 11 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/descriptor_props.py | 27 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 4 |
3 files changed, 31 insertions, 11 deletions
diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py index 268a1d57a..c23ea0311 100644 --- a/lib/sqlalchemy/orm/decl_base.py +++ b/lib/sqlalchemy/orm/decl_base.py @@ -64,6 +64,8 @@ from ..sql.schema import Column from ..sql.schema import Table from ..util import topological from ..util.typing import _AnnotationScanType +from ..util.typing import de_stringify_annotation +from ..util.typing import is_fwd_ref from ..util.typing import Protocol from ..util.typing import TypedDict from ..util.typing import typing_get_args @@ -1120,6 +1122,15 @@ class _ClassScanMapperConfig(_MapperConfig): if attr_value is None: for elem in typing_get_args(extracted_mapped_annotation): + if isinstance(elem, str) or is_fwd_ref( + elem, check_generic=True + ): + elem = de_stringify_annotation( + self.cls, + elem, + originating_class.__module__, + include_generic=True, + ) # look in Annotated[...] for an ORM construct, # such as Annotated[int, mapped_column(primary_key=True)] if isinstance(elem, _IntrospectsAnnotations): diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 84d15360d..55c7e9290 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -52,6 +52,8 @@ from .. import util from ..sql import expression from ..sql import operators from ..sql.elements import BindParameter +from ..util.typing import de_stringify_annotation +from ..util.typing import is_fwd_ref from ..util.typing import is_pep593 from ..util.typing import typing_get_args @@ -351,18 +353,23 @@ class CompositeProperty( argument = typing_get_args(argument)[0] if argument and self.composite_class is None: - if isinstance(argument, str) or hasattr( - argument, "__forward_arg__" + if isinstance(argument, str) or is_fwd_ref( + argument, check_generic=True ): - str_arg = ( - argument.__forward_arg__ - if hasattr(argument, "__forward_arg__") - else str(argument) - ) - raise sa_exc.ArgumentError( - f"Can't use forward ref {argument} for composite " - f"class argument; set up the type as Mapped[{str_arg}]" + if originating_module is None: + str_arg = ( + argument.__forward_arg__ + if hasattr(argument, "__forward_arg__") + else str(argument) + ) + raise sa_exc.ArgumentError( + f"Can't use forward ref {argument} for composite " + f"class argument; set up the type as Mapped[{str_arg}]" + ) + argument = de_stringify_annotation( + cls, argument, originating_module, include_generic=True ) + self.composite_class = argument if is_dataclass(self.composite_class): diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index b8e1521a2..e89e3c356 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -684,7 +684,9 @@ class MappedColumn( ) -> None: sqltype = self.column.type - if is_fwd_ref(argument, check_generic=True): + if isinstance(argument, str) or is_fwd_ref( + argument, check_generic=True + ): assert originating_module is not None argument = de_stringify_annotation( cls, argument, originating_module, include_generic=True |
