]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
add Python 3.15 support
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 3 Aug 2026 17:18:39 +0000 (13:18 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 3 Aug 2026 17:44:33 +0000 (13:44 -0400)
Add 3.15 to the noxfile Python matrix and to the trove classifiers.

Repair the auto-generated docstring for MappedAsDataclass subclasses under
3.15.  Python 3.15 changed dataclasses so that the class docstring is no
longer rendered when the dataclass is created, and is instead produced by a
descriptor the first time __doc__ is read.  _ClassScanMapperConfig swaps a
merged __annotations__ onto the class for the duration of the dataclass call
and restores the original in a finally block, so by the time that deferred
render happens the annotations are gone and the docstring loses them
entirely.  Read __doc__ while the swapped annotations are still in place so
the same docstring is produced on every supported Python.

Full sqlite test suite passes on 3.15.0b4 (25972 passed); no change on
3.10, 3.13 or 3.14.

py315: yes

Fixes: #13477
Change-Id: I452a8bb1392a4417194594bd2e1e37b9e56fee26

doc/build/changelog/unreleased_20/13477.rst [new file with mode: 0644]
lib/sqlalchemy/orm/decl_base.py
noxfile.py
pyproject.toml

diff --git a/doc/build/changelog/unreleased_20/13477.rst b/doc/build/changelog/unreleased_20/13477.rst
new file mode 100644 (file)
index 0000000..3fbcfc4
--- /dev/null
@@ -0,0 +1,6 @@
+.. change::
+    :tags: bug, platform
+    :tickets: 13477
+
+    Python 3.15 support has been added and tested, including minimal changes
+    for full compatibility.
index ed491a18b2e33eecf2100c543b73cbeffd649188..59201685c3f4ebeaff713090490be43deb8bcedb 100644 (file)
@@ -662,6 +662,20 @@ class _ClassScanAbstractConfig(_ORMClassConfigurator):
                 "documentation for additional information.",
                 code="dcte",
             ) from ex
+        else:
+            # as of Python 3.15, dataclasses no longer renders the
+            # auto-generated class docstring immediately; it instead installs
+            # a descriptor that renders the ``__init__`` signature the first
+            # time ``__doc__`` is accessed (see
+            # ``dataclasses._AutoDocstring``).  As the ``finally:`` block
+            # below puts the class' original annotations back, that deferred
+            # render would no longer see the dataclass-oriented annotations
+            # we swapped in above, and would omit them from the docstring
+            # entirely.  Read the attribute now, while those annotations are
+            # still in place, so the docstring we generate is the same on
+            # every Python version.
+            self.cls.__doc__
+
         finally:
             if revert and revert_dict:
                 # used for mixin dataclasses; we have to restore the
index 97cd30e8de0ee4ddac58429d6547879d28469dba..19ef15550f1825f1b59ddb09c80ca4f4d7ba32aa 100644 (file)
@@ -24,7 +24,7 @@ if True:
     from tools.toxnox import tox_parameters
 
 
-PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
+PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15"]
 DATABASES = ["sqlite", "sqlite_file", "postgresql", "mysql", "oracle", "mssql"]
 CEXT = ["_auto", "cext", "nocext"]
 GREENLET = ["_greenlet", "nogreenlet"]
index 9b750e318dcd31e800d3d8a2d9e0fac0cc37d676..04e84659cfd523aa413ff1db72476a67eeea7216 100644 (file)
@@ -24,6 +24,7 @@ classifiers = [
     "Programming Language :: Python :: 3.12",
     "Programming Language :: Python :: 3.13",
     "Programming Language :: Python :: 3.14",
+    "Programming Language :: Python :: 3.15",
     "Programming Language :: Python :: Implementation :: CPython",
     "Programming Language :: Python :: Implementation :: PyPy",
     "Topic :: Database :: Front-Ends",