From: Mike Bayer Date: Mon, 21 Nov 2022 13:51:34 +0000 (-0500) Subject: fall back to eval() for names that have dots X-Git-Tag: rel_2_0_0b4~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ece524c0059d0814e45f4bba63abebd7e9af4b8b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git fall back to eval() for names that have dots Fixed regression in 2.0.0b3 caused by :ticket:`8759` where indicating the :class:`.Mapped` name using a qualified name such as ``sqlalchemy.orm.Mapped`` would fail to be recognized by Declarative as indicating the :class:`.Mapped` construct. Fixes: #8853 Change-Id: Iddb6efaae864d4545e80c54658244670f81ef6cc --- diff --git a/doc/build/changelog/unreleased_20/8853.rst b/doc/build/changelog/unreleased_20/8853.rst new file mode 100644 index 0000000000..97d1f08efa --- /dev/null +++ b/doc/build/changelog/unreleased_20/8853.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, orm + :tickets: 8853 + + Fixed regression in 2.0.0b3 caused by :ticket:`8759` where indicating the + :class:`.Mapped` name using a qualified name such as + ``sqlalchemy.orm.Mapped`` would fail to be recognized by Declarative as + indicating the :class:`.Mapped` construct. diff --git a/lib/sqlalchemy/util/typing.py b/lib/sqlalchemy/util/typing.py index 9eb761eff0..20ad148f81 100644 --- a/lib/sqlalchemy/util/typing.py +++ b/lib/sqlalchemy/util/typing.py @@ -141,6 +141,8 @@ def eval_expression(expression: str, module_name: str) -> Any: def eval_name_only(name: str, module_name: str) -> Any: + if "." in name: + return eval_expression(name, module_name) try: base_globals: Dict[str, Any] = sys.modules[module_name].__dict__ diff --git a/test/orm/declarative/test_tm_future_annotations.py b/test/orm/declarative/test_tm_future_annotations.py index d66b08f4e0..b63d856906 100644 --- a/test/orm/declarative/test_tm_future_annotations.py +++ b/test/orm/declarative/test_tm_future_annotations.py @@ -19,6 +19,7 @@ from sqlalchemy import String from sqlalchemy import Table from sqlalchemy import testing from sqlalchemy import Uuid +import sqlalchemy.orm from sqlalchemy.orm import attribute_keyed_dict from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import DynamicMapped @@ -55,6 +56,22 @@ class M3: class MappedColumnTest(_MappedColumnTest): + def test_fully_qualified_mapped_name(self, decl_base): + """test #8853, regression caused by #8759 ;)""" # noqa: E501 + + class Foo(decl_base): + __tablename__ = "foo" + + id: sqlalchemy.orm.Mapped[int] = mapped_column(primary_key=True) + + data: sqlalchemy.orm.Mapped[int] = mapped_column() + + data2: sqlalchemy.orm.Mapped[int] + + self.assert_compile( + select(Foo), "SELECT foo.id, foo.data, foo.data2 FROM foo" + ) + def test_indirect_mapped_name_module_level(self, decl_base): """test #8759