assign variant mapping on adapt()

Fixed regression from the 1.4 series where the refactor of the
:meth:`_types.TypeEngine.with_variant` method introduced at
:ref:`change_6980` failed to accommodate for the ``.copy()`` method, which
will lose the variant mappings that are set up. This becomes an issue for
the very specific case of a "schema" type, which includes types such as
:class:`.Enum` and :class:`.ARRAY`, when they are then used in the context
of an ORM Declarative mapping with mixins where copying of types comes into
play.  The variant mapping is now copied as well.

Fixes: #11176
Change-Id: Icf1a2752f60fce863c87ead8b0fe298b0f3d3766
This commit is contained in:
Mike Bayer
2024-03-20 10:23:41 -04:00
parent 697dcc94e4
commit 041eb04df0
3 changed files with 28 additions and 1 deletions
+12
View File
@@ -0,0 +1,12 @@
.. change::
:tag: bug, sql, regression
:tickets: 11176
Fixed regression from the 1.4 series where the refactor of the
:meth:`_types.TypeEngine.with_variant` method introduced at
:ref:`change_6980` failed to accommodate for the ``.copy()`` method, which
will lose the variant mappings that are set up. This becomes an issue for
the very specific case of a "schema" type, which includes types such as
:class:`.Enum` and :class:`.ARRAY`, when they are then used in the context
of an ORM Declarative mapping with mixins where copying of types comes into
play. The variant mapping is now copied as well.
+3 -1
View File
@@ -1005,9 +1005,11 @@ class TypeEngine(Visitable, Generic[_T]):
types with "implementation" types that are specific to a particular
dialect.
"""
return util.constructor_copy(
typ = util.constructor_copy(
self, cast(Type[TypeEngine[Any]], cls), **kw
)
typ._variant_mapping = self._variant_mapping
return typ
def coerce_compared_value(
self, op: Optional[OperatorType], value: Any
+13
View File
@@ -1695,6 +1695,19 @@ class VariantTest(fixtures.TestBase, AssertsCompiledSQL):
)
self.composite = self.variant.with_variant(self.UTypeThree(), "mysql")
def test_copy_doesnt_lose_variants(self):
"""test #11176"""
v = self.UTypeOne().with_variant(self.UTypeTwo(), "postgresql")
v_c = v.copy()
self.assert_compile(v_c, "UTYPEONE", dialect="default")
self.assert_compile(
v_c, "UTYPETWO", dialect=dialects.postgresql.dialect()
)
def test_one_dialect_is_req(self):
with expect_raises_message(
exc.ArgumentError, "At least one dialect name is required"