]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
assign variant mapping on adapt()
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Mar 2024 14:23:41 +0000 (10:23 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Mar 2024 15:42:39 +0000 (11:42 -0400)
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
(cherry picked from commit 29a428955a904e235e1b85e928cbe89155aeca82)

doc/build/changelog/unreleased_20/11176.rst [new file with mode: 0644]
lib/sqlalchemy/sql/type_api.py
test/sql/test_types.py

diff --git a/doc/build/changelog/unreleased_20/11176.rst b/doc/build/changelog/unreleased_20/11176.rst
new file mode 100644 (file)
index 0000000..cc35ab1
--- /dev/null
@@ -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.
index 43d47064d4e45062e426f99de925fb36f1d54d95..4233e7f16e80e26527ee49f7f1c18d1741c57e99 100644 (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
index 898d6fa0a8c500ddbc40202c7312b4085f5b2983..0127004438cdfbd1aedcaf6cd3ccd3827046b642 100644 (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"