summaryrefslogtreecommitdiff
path: root/test/sql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-12-21 16:10:34 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2022-12-21 16:12:53 -0500
commitb973cbd8939f2cc0e29c668fffd507958c3e455a (patch)
treec42e547b00e50ed06fe1601b09fbb3053ab53b6e /test/sql
parent9749a394b19e78086103b3c01144a03061bb9c75 (diff)
downloadsqlalchemy-b973cbd8939f2cc0e29c668fffd507958c3e455a.tar.gz
check for adapt to same class in AbstractRange
Fixed regression where newly revised PostgreSQL range types such as :class:`_postgresql.INT4RANGE` could not be set up as the impl of a :class:`.TypeDecorator` custom type, instead raising a ``TypeError``. Fixes: #9020 Change-Id: Ib881c3c7f63d000f49a09185a8663659a9970aa9
Diffstat (limited to 'test/sql')
-rw-r--r--test/sql/test_types.py49
1 files changed, 47 insertions, 2 deletions
diff --git a/test/sql/test_types.py b/test/sql/test_types.py
index 59519a5ec..47fe68354 100644
--- a/test/sql/test_types.py
+++ b/test/sql/test_types.py
@@ -85,6 +85,7 @@ from sqlalchemy.testing import expect_raises
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import is_
from sqlalchemy.testing import is_not
+from sqlalchemy.testing import is_true
from sqlalchemy.testing import mock
from sqlalchemy.testing import pickleable
from sqlalchemy.testing.assertions import expect_raises_message
@@ -120,6 +121,15 @@ def _types_for_mod(mod):
def _all_types(omit_special_types=False):
+ yield from (
+ typ
+ for typ, _ in _all_types_w_their_dialect(
+ omit_special_types=omit_special_types
+ )
+ )
+
+
+def _all_types_w_their_dialect(omit_special_types=False):
seen = set()
for typ in _types_for_mod(types):
if omit_special_types and (
@@ -129,6 +139,7 @@ def _all_types(omit_special_types=False):
type_api.TypeEngineMixin,
types.Variant,
types.TypeDecorator,
+ types.PickleType,
)
or type_api.TypeEngineMixin in typ.__bases__
):
@@ -137,13 +148,13 @@ def _all_types(omit_special_types=False):
if typ in seen:
continue
seen.add(typ)
- yield typ
+ yield typ, default.DefaultDialect
for dialect in _all_dialect_modules():
for typ in _types_for_mod(dialect):
if typ in seen:
continue
seen.add(typ)
- yield typ
+ yield typ, dialect.dialect
def _get_instance(type_):
@@ -350,6 +361,40 @@ class AdaptTest(fixtures.TestBase):
t2 = t1.adapt(Text)
eq_(t2.length, 50)
+ @testing.combinations(
+ *[
+ (t, d)
+ for t, d in _all_types_w_their_dialect(omit_special_types=True)
+ ]
+ )
+ def test_every_possible_type_can_be_decorated(self, typ, dialect_cls):
+ """test for #9020
+
+ Apparently the adapt() method is called with the same class as given
+ in the case of :class:`.TypeDecorator`, at least with the
+ PostgreSQL RANGE types, which is not usually expected.
+
+ """
+ my_type = type("MyType", (TypeDecorator,), {"impl": typ})
+
+ if issubclass(typ, ARRAY):
+ inst = my_type(Integer)
+ elif issubclass(typ, pg.ENUM):
+ inst = my_type(name="my_enum")
+ elif issubclass(typ, pg.DOMAIN):
+ inst = my_type(name="my_domain", data_type=Integer)
+ else:
+ inst = my_type()
+ impl = inst._unwrapped_dialect_impl(dialect_cls())
+
+ if dialect_cls is default.DefaultDialect:
+ is_true(isinstance(impl, typ))
+
+ if impl._type_affinity is Interval:
+ is_true(issubclass(typ, sqltypes._AbstractInterval))
+ else:
+ is_true(issubclass(typ, impl._type_affinity))
+
class TypeAffinityTest(fixtures.TestBase):
@testing.combinations(