]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Default python_type impl now returns object
authorFederico Caselli <cfederico87@gmail.com>
Wed, 5 Feb 2025 22:41:32 +0000 (23:41 +0100)
committerFederico Caselli <cfederico87@gmail.com>
Wed, 12 Feb 2025 20:42:41 +0000 (21:42 +0100)
The default implementation of :attr:`_sql.TypeEngine.python_type` now
returns ``object`` instead of ``NotImplementedError``, since that's the
base for all types in Python3.
The ``python_type`` of :class:`_sql.JSON` no longer returns ``dict``,
but instead fallbacks to the generic implementation.

Fixes: #10646
Change-Id: I2233e4a3d35a67b520a860d70afba8e5b22fd72d

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

diff --git a/doc/build/changelog/unreleased_21/10646.rst b/doc/build/changelog/unreleased_21/10646.rst
new file mode 100644 (file)
index 0000000..7d82138
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: typing
+    :tickets: 10646
+
+    The default implementation of :attr:`_sql.TypeEngine.python_type` now
+    returns ``object`` instead of ``NotImplementedError``, since that's the
+    base for all types in Python3.
+    The ``python_type`` of :class:`_sql.JSON` no longer returns ``dict``,
+    but instead fallbacks to the generic implementation.
index 44c193bf73a681912e7800631bca242662008f3c..ec382c2f14747e237037f3a78fd9144cf108fc7f 100644 (file)
@@ -2739,10 +2739,6 @@ class JSON(Indexable, TypeEngine[Any]):
 
     comparator_factory = Comparator
 
-    @property
-    def python_type(self):
-        return dict
-
     @property  # type: ignore  # mypy property bug
     def should_evaluate_none(self):
         """Alias of :attr:`_types.JSON.none_as_null`"""
index fb72c825e576b1f414a3fe7e3fa16cd7975d7d1b..19b315928afd3a025b9c53f27d2b36d4e4deab1b 100644 (file)
@@ -611,21 +611,22 @@ class TypeEngine(Visitable, Generic[_T]):
     @property
     def python_type(self) -> Type[Any]:
         """Return the Python type object expected to be returned
-        by instances of this type, if known.
+        by instances of this type.
 
         Basically, for those types which enforce a return type,
         or are known across the board to do such for all common
         DBAPIs (like ``int`` for example), will return that type.
 
-        If a return type is not defined, raises
-        ``NotImplementedError``.
+        By default the generic ``object`` type is returned.
 
         Note that any type also accommodates NULL in SQL which
         means you can also get back ``None`` from any type
         in practice.
 
+        .. versionchanged:: 2.1 - The default implementation now returns
+          ``object`` instead of raising ``NotImplementedError``.
         """
-        raise NotImplementedError()
+        return object
 
     def with_variant(
         self,
index f5a042e32a4650ddb41f7e0cbfb1f16a47b162a2..f3e25f395af74fd085e6c114f1cc07f93a5d56fd 100644 (file)
@@ -7,6 +7,7 @@ import pickle
 import subprocess
 import sys
 from tempfile import mkstemp
+import uuid
 
 import sqlalchemy as sa
 from sqlalchemy import and_
@@ -310,22 +311,27 @@ class AdaptTest(fixtures.TestBase):
         eq_(t1.evaluates_none().should_evaluate_none, True)
 
     def test_python_type(self):
+        eq_(types.ARRAY(types.Integer).python_type, list)
+        eq_(types.Boolean().python_type, bool)
+        eq_(types.Date().python_type, datetime.date)
+        eq_(types.DateTime().python_type, datetime.datetime)
+        eq_(types.Double().python_type, float)
+        eq_(types.Enum("one", "two", "three").python_type, str)
+        eq_(types.Float().python_type, float)
         eq_(types.Integer().python_type, int)
+        eq_(types.Interval().python_type, datetime.timedelta)
+        eq_(types.JSON().python_type, object)
+        eq_(types.LargeBinary().python_type, bytes)
+        eq_(types.NullType().python_type, object)
         eq_(types.Numeric().python_type, decimal.Decimal)
         eq_(types.Numeric(asdecimal=False).python_type, float)
-        eq_(types.LargeBinary().python_type, bytes)
-        eq_(types.Float().python_type, float)
-        eq_(types.Double().python_type, float)
-        eq_(types.Interval().python_type, datetime.timedelta)
-        eq_(types.Date().python_type, datetime.date)
-        eq_(types.DateTime().python_type, datetime.datetime)
+        eq_(types.PickleType().python_type, object)
         eq_(types.String().python_type, str)
+        eq_(types.Time().python_type, datetime.time)
         eq_(types.Unicode().python_type, str)
-        eq_(types.Enum("one", "two", "three").python_type, str)
-
-        assert_raises(
-            NotImplementedError, lambda: types.TypeEngine().python_type
-        )
+        eq_(types.Uuid().python_type, uuid.UUID)
+        eq_(types.Uuid(as_uuid=False).python_type, str)
+        eq_(types.TypeEngine().python_type, object)
 
     @testing.uses_deprecated()
     @testing.combinations(*[(t,) for t in _all_types(omit_special_types=True)])