Fixed issue with ``__allow_unmapped__`` declarative option where types that
were declared using collection types such as ``list[SomeClass]`` vs. the
typing construct ``List[SomeClass]`` would fail to be recognized correctly.
Pull request courtesy Pascal Corpet.
Fixes: #10385
Closes: #10390
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/10390
Pull-request-sha:
f8796965aefc1852d4b1137d04bf811072a1a0e9
Change-Id: I114d29c3c076386508300e979371b0d760b761c7
--- /dev/null
+.. change::
+ :tags: orm, bug
+ :tickets: 10385
+
+ Fixed issue with ``__allow_unmapped__`` declarative option
+ where types that were declared using collection types such as
+ ``list[SomeClass]`` vs. the typing construct ``List[SomeClass]``
+ would fail to be recognized correctly. Pull request courtesy
+ Pascal Corpet.
from __future__ import annotations
+import builtins
import re
import sys
import typing
try:
return base_globals[name]
except KeyError as ke:
+ # check in builtins as well to handle `list`, `set` or `dict`, etc.
+ try:
+ return builtins.__dict__[name]
+ except KeyError:
+ pass
+
raise NameError(
f"Could not locate name {name} in module {module_name}"
) from ke
decl_base.registry.configure()
- def test_14_style_anno_accepted_w_allow_unmapped(self):
- """test for #8692"""
+ @testing.variation(
+ "collection_type",
+ [
+ ("list", testing.requires.python310),
+ "List",
+ ("set", testing.requires.python310),
+ "Set",
+ ],
+ )
+ def test_14_style_anno_accepted_w_allow_unmapped(self, collection_type):
+ """test for #8692 and #10385"""
class Base(DeclarativeBase):
__allow_unmapped__ = True
id: Mapped[int] = mapped_column(primary_key=True)
data: str = Column(String)
- bs: List["B"] = relationship("B", back_populates="a") # noqa: F821
+
+ if collection_type.list:
+ bs: list["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.List:
+ bs: List["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.set:
+ bs: set["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.Set:
+ bs: Set["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ else:
+ collection_type.fail()
class B(Base):
__tablename__ = "b"
decl_base.registry.configure()
- def test_14_style_anno_accepted_w_allow_unmapped(self):
- """test for #8692"""
+ @testing.variation(
+ "collection_type",
+ [
+ ("list", testing.requires.python310),
+ "List",
+ ("set", testing.requires.python310),
+ "Set",
+ ],
+ )
+ def test_14_style_anno_accepted_w_allow_unmapped(self, collection_type):
+ """test for #8692 and #10385"""
class Base(DeclarativeBase):
__allow_unmapped__ = True
id: Mapped[int] = mapped_column(primary_key=True)
data: str = Column(String)
- bs: List["B"] = relationship("B", back_populates="a") # noqa: F821
+
+ if collection_type.list:
+ bs: list["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.List:
+ bs: List["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.set:
+ bs: set["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ elif collection_type.Set:
+ bs: Set["B"] = relationship( # noqa: F821
+ "B",
+ back_populates="a",
+ )
+ else:
+ collection_type.fail()
class B(Base):
__tablename__ = "b"