python-sqlalchemy fails to build with Python 3.14.0a5. Some of the issues seem to be related to the new forkserver default method of multiproceesing, other to typing. Probably more. === 157 failed, 21951 passed, 10859 skipped, 1 warning in 292.80s (0:04:52) ==== Upstream's discussion: https://github.com/sqlalchemy/sqlalchemy/discussions/12399 For the build logs, see: https://copr-be.cloud.fedoraproject.org/results/@python/python3.14/fedora-rawhide-x86_64/08727120-python-sqlalchemy/ For all our attempts to build python-sqlalchemy with Python 3.14, see: https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-sqlalchemy/ Testing and mass rebuild of packages is happening in copr. You can follow these instructions to test locally in mock if your package builds with Python 3.14: https://copr.fedorainfracloud.org/coprs/g/python/python3.14/ Let us know here if you have any questions. Python 3.14 is planned to be included in Fedora 43. To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.14. A build failure prevents us from testing all dependent packages (transitive [Build]Requires), so if this package is required a lot, it's important for us to get it fixed soon. We'd appreciate help from the people who know this package best, but if you don't want to work on this now, let us know so we can try to work around it on our side.
This was after https://src.fedoraproject.org/rpms/python-sqlalchemy/pull-request/21 Upstream report: https://github.com/sqlalchemy/sqlalchemy/discussions/12399 Upstream claims this is a Python bug: https://github.com/python/cpython/issues/130881
With Python 3.14.0a6 and the patch from the open PR, there are 57 failures with a similar/same traceback: _ RelationshipDefaultFactoryTest.test_replace_operation_works_w_history_etc ___ [gw2] linux -- Python 3.14.0 /usr/bin/python3 Traceback (most recent call last): File "/usr/lib/python3.14/site-packages/_pytest/runner.py", line 341, in from_call result: TResult | None = func() ~~~~^^ File "/usr/lib/python3.14/site-packages/_pytest/runner.py", line 242, in <lambda> lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_hooks.py", line 513, in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.__traceback__) File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/_pytest/threadexception.py", line 92, in pytest_runtest_call yield from thread_exception_runtest_hook() File "/usr/lib/python3.14/site-packages/_pytest/threadexception.py", line 68, in thread_exception_runtest_hook yield File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/_pytest/unraisableexception.py", line 95, in pytest_runtest_call yield from unraisable_exception_runtest_hook() File "/usr/lib/python3.14/site-packages/_pytest/unraisableexception.py", line 70, in unraisable_exception_runtest_hook yield File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/_pytest/logging.py", line 846, in pytest_runtest_call yield from self._runtest_for(item, "call") File "/usr/lib/python3.14/site-packages/_pytest/logging.py", line 829, in _runtest_for yield File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/_pytest/capture.py", line 880, in pytest_runtest_call return (yield) ^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call return (yield) ^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(*args) File "/usr/lib/python3.14/site-packages/_pytest/runner.py", line 174, in pytest_runtest_call item.runtest() ~~~~~~~~~~~~^^ File "/usr/lib/python3.14/site-packages/_pytest/python.py", line 1627, in runtest self.ihook.pytest_pyfunc_call(pyfuncitem=self) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_hooks.py", line 513, in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.__traceback__) File "/usr/lib/python3.14/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(*args) File "/usr/lib/python3.14/site-packages/_pytest/python.py", line 159, in pytest_pyfunc_call result = testfunction(**testargs) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/test/orm/declarative/test_dc_transforms.py", line 962, in test_replace_operation_works_w_history_etc @registry.mapped_as_dataclass ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_api.py", line 1671, in mapped_as_dataclass return decorate(__cls) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_api.py", line 1667, in decorate _as_declarative(self, cls, cls.__dict__) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_base.py", line 245, in _as_declarative return _MapperConfig.setup_mapping(registry, cls, dict_, None, {}) ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_base.py", line 326, in setup_mapping return _ClassScanMapperConfig( registry, cls_, dict_, table, mapper_kw ) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_base.py", line 573, in __init__ self._extract_mappable_attributes() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/decl_base.py", line 1572, in _extract_mappable_attributes value.declarative_scan( ~~~~~~~~~~~~~~~~~~~~~~^ self, ^^^^^ ...<7 lines>... is_dataclass, ^^^^^^^^^^^^^ ) ^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/properties.py", line 725, in declarative_scan self._init_column_for_annotation( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ cls, ^^^^ ...<2 lines>... originating_module, ^^^^^^^^^^^^^^^^^^^ ) ^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/orm/properties.py", line 770, in _init_column_for_annotation our_type = de_optionalize_union_types(argument) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/util/typing.py", line 475, in de_optionalize_union_types return make_union_type(*typ) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/util/typing.py", line 549, in make_union_type return Union.__getitem__(types) # type: ignore ~~~~~~~~~~~~~~~~~^^^^^^^ TypeError: descriptor '__getitem__' requires a 'typing.Union' object but received a 'tuple'
The upstream gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5739 was updated to support these new changes in Python 3.14.0a6. we are also waiting for an upstream fix to cPython at https://github.com/python/cpython/pull/130935 , which repairs most of the original issue we encountered in 3.14.0a5, to merge; we hope this will be in the next release of Python 3.14, and when that merges we will have further adjustments to the gerrit mentioned above. so the state of cpython for 3.14 alpha series is in flux right now.
I updated https://src.fedoraproject.org/rpms/python-sqlalchemy/pull-request/22 to the latest revision.
Back at: DeprecationWarning: 'asyncio.get_event_loop_policy' is deprecated and slated for removal in Python 3.16
OK, we make the 2.0 change by backporting from main, and main doesn't have await_fallback() so this keeps failing. so i need to change main so that it fails on this warning, that way our 2.0 backport wont pass CI unless I remember to also mark out this one test.
I can make it not fail the build.
sure, but on our end we've been falling down pretty hard since we had other things preventing the greenlet/asyncio stuff from even running in our CI for py314 since in our tox file we assumed greenlet wasn't going to be working on 3.14 by default, bit of a rabbit hole discovered by that one simple fail, waiting for full builds of main/2.0 branches here and will ensure all asyncio tests run on both
patchset 12 on that above gerrit should have everything to run without errors
Still get this with patchset 12: --- 8< --- =================================== FAILURES =================================== __________________ TestTestingThings.test_unions_are_the_same __________________ [gw3] linux -- Python 3.13.2 /usr/bin/python3 Traceback (most recent call last): File "/usr/lib/python3.13/site-packages/_pytest/runner.py", line 341, in from_call result: TResult | None = func() ~~~~^^ File "/usr/lib/python3.13/site-packages/_pytest/runner.py", line 242, in <lambda> lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_hooks.py", line 513, in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.__traceback__) File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/_pytest/threadexception.py", line 92, in pytest_runtest_call yield from thread_exception_runtest_hook() File "/usr/lib/python3.13/site-packages/_pytest/threadexception.py", line 68, in thread_exception_runtest_hook yield File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/_pytest/unraisableexception.py", line 95, in pytest_runtest_call yield from unraisable_exception_runtest_hook() File "/usr/lib/python3.13/site-packages/_pytest/unraisableexception.py", line 70, in unraisable_exception_runtest_hook yield File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/_pytest/logging.py", line 846, in pytest_runtest_call yield from self._runtest_for(item, "call") File "/usr/lib/python3.13/site-packages/_pytest/logging.py", line 829, in _runtest_for yield File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/_pytest/capture.py", line 898, in pytest_runtest_call return (yield) ^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] ~~~~~~~~~~~~~~^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call return (yield) ^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(*args) File "/usr/lib/python3.13/site-packages/_pytest/runner.py", line 174, in pytest_runtest_call item.runtest() ~~~~~~~~~~~~^^ File "/usr/lib/python3.13/site-packages/_pytest/python.py", line 1627, in runtest self.ihook.pytest_pyfunc_call(pyfuncitem=self) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_hooks.py", line 513, in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.__traceback__) File "/usr/lib/python3.13/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(*args) File "/usr/lib/python3.13/site-packages/_pytest/python.py", line 159, in pytest_pyfunc_call result = testfunction(**testargs) File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/test/base/test_typing_utils.py", line 151, in test_unions_are_the_same is_(typing.TypeAliasType, typing_extensions.TypeAliasType) ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/builddir/build/BUILD/python-sqlalchemy-2.0.39-build/sqlalchemy-2.0.39/lib/sqlalchemy/testing/assertions.py", line 318, in is_ assert a is b, msg or "%r is not %r" % (a, b) AssertionError: <class 'typing.TypeAliasType'> is not <class 'typing_extensions.TypeAliasType'> assert <class 'typing.TypeAliasType'> is <class 'typing_extensions.TypeAliasType'> --- >8 --- See the failed Koji build here: https://koji.fedoraproject.org/koji/taskinfo?taskID=130562392
OK that's on Python 3.13.2 , so that's an unusual fail because those classes are equivalent for all py that I have over here, I have a py 3.13.0 here: Python 3.13.0 (main, Dec 3 2024, 14:58:14) [GCC 14.2.1 20240912 (Red Hat 14.2.1-3)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import typing >>> import typing_extensions >>> typing.TypeAliasType is typing_extensions.TypeAliasType True but then when I look in the source at https://github.com/python/typing_extensions/blob/main/src/typing_extensions.py it seems like this would not hold true for py<3.14, ah but for the current released version 4.12.2 it does hold: https://github.com/python/typing_extensions/blob/4.12.2/src/typing_extensions.py#L3382 so that's why this would be a different regression altogether (should we make a different bz?) So I guess you are installing typing_extensions from github source ?
I've added typing-extensions>=4.13.0rc1 to the gerrit and amended this test as in https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5739/13/test/base/test_typing_utils.py , though that's still a too-brittle way to be doing this test. on your end I would advise just patching out that test, it's not needed
oh and 4.13.0rc1 is a pre-release that was just released this week march 18, so that's a brand new regression. So this situation keeps changing below our feet
I would respond in Gerrit but I don’t seem to have an account there… (In reply to Michael Bayer from comment #12) > I've added typing-extensions>=4.13.0rc1 to the gerrit and amended this test > as in > https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5739/13/test/base/ > test_typing_utils.py , though that's still a too-brittle way to be doing > this test. I don’t get why the test would verify that typing.TypeAliasType isn’t typing_extensions.TypeAliasType (Python <3.14), that’s dependent on the (pre-)release of typing_extensions, too, isn’t it?
I think what that test is going for is, in our typing module which has tons of routines for runtime type determination of things, we might have logic like "if isinstance(type_, typing.TypeAliasType)" or something like that , and this test is trying to track if we need to amend that. my co-developer is going to check on this. however with my adjusting the test (and in the most recent rev just taking it out) everything else is still passing. obviously we would be better off not trying to guess and just assuming they may or may not be the same class.
FEDORA-2025-fb5f304bee (python-sqlalchemy-2.0.40-1.fc43) has been submitted as an update to Fedora 43. https://bodhi.fedoraproject.org/updates/FEDORA-2025-fb5f304bee
python-sqlalchemy-2.0.40-1.fc43 does not fix this, it breoke it again.
I couldn’t get 2.0.39-2 to build, so AIUI it never was "not broken" for 3.14.
And ofc, Bodhi doesn’t let me remove this ticket from the automatic update. 🙄
FEDORA-2025-fb5f304bee (python-sqlalchemy-2.0.40-1.fc43) has been pushed to the Fedora 43 stable repository. If problem still persists, please make note of it in this bug report.
(In reply to Nils Philippsen from comment #18) > I couldn’t get 2.0.39-2 to build, so AIUI it never was "not broken" for 3.14. For our purpuses itt was "not broken". Anyway, reopening.
Alright, it’s building with this one included: https://src.fedoraproject.org/rpms/python-sqlalchemy/c/e356983712be43e823722a91ab66c5f1ea547186?branch=rawhide Hopefully, this fixes builds with Python 3.14 and lower 😉. Sorry for the hassle. @Mike: The patch is the one from gerrit, rebased on 2.0.40 with conflicts resolved. This alone isn’t enough, I let pytest skip test/base/test_typing_utils.py::TestTyping::test_is_generic on Python 3.14 because, in this version, generic and non-generic Unions seem to be the same.
The build finished in Rawhide, and it built successfully in my local fedora-rawhide-python314 mock root.
Thanks.
3.14.0a7 which was hoped to make things better did indeed fix one of the problems we had but introduced all new ones. so you're going to want to either reopen this or make a new one, as I've gone through a dozen more iterations of the patch to accommodate. Additionally, 3.14.0a7 breaks greenlet: https://github.com/python-greenlet/greenlet/issues/440 and it would be great if we could as in previous times get someone to provide a patch (cc @vstinner)
🤷
> Additionally, 3.14.0a7 breaks greenlet: https://github.com/python-greenlet/greenlet/issues/440 and it would be great if we could as in previous times get someone to provide a patch (cc @vstinner) greenet was fixed a few days ago for Python 3.14.0a7 by https://github.com/python-greenlet/greenlet/pull/442 (commit https://github.com/python-greenlet/greenlet/commit/cf7f854d31bd144d75f284d406dae06882e44730).
greenet was fixed in copr I'm trying out revision 26 of https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5739
Added in https://src.fedoraproject.org/rpms/python-sqlalchemy/pull-request/23 -- locally worked for me.
hi folks - 3.14.0b1 is released today. annnd. it's all bad news :( greenlet is broken again: https://github.com/python-greenlet/greenlet/issues/440 sqlalchemy is broken again also and we will have to patch further. I'm working out what's breaking now
upstream python issue: https://github.com/python/cpython/issues/133684 I am going to hold off trying to work around this one as it seems very broken on their part
OK, I got some workarounds from cpython devs to vendor some lib functions, the patch at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5739 has merged and that has 3.14.0b1 passing completely for the base tox run. greenlet and greenlet related functions in SQLAlchemy's test suite still not tested though. will do greenlet in a separate pass
Fedora PR udpated and blocked by a segfault to be investigated.
> greenlet is broken again: https://github.com/python-greenlet/greenlet/issues/440 I wrote a fix which is already merged: https://github.com/python-greenlet/greenlet/pull/445
(In reply to Victor Stinner from comment #34) > > greenlet is broken again: https://github.com/python-greenlet/greenlet/issues/440 > > I wrote a fix which is already merged: > https://github.com/python-greenlet/greenlet/pull/445 It's in https://src.fedoraproject.org/rpms/python-greenlet/pull-request/19
(In reply to Miro Hrončok from comment #33) > Fedora PR udpated and blocked by a segfault to be investigated. It works.
Miro, I’ve merged your PR, thanks for it! Is there anything else to do other than the greenlet change to land?
(In reply to Nils Philippsen from comment #37) > Miro, I’ve merged your PR, thanks for it! Is there anything else to do other > than the greenlet change to land? It's all good. Thanks.
FEDORA-2025-bf05611bd8 (python-sqlalchemy-2.0.41-1.fc43) has been submitted as an update to Fedora 43. https://bodhi.fedoraproject.org/updates/FEDORA-2025-bf05611bd8
FEDORA-2025-bf05611bd8 (python-sqlalchemy-2.0.41-1.fc43) has been pushed to the Fedora 43 stable repository. If problem still persists, please make note of it in this bug report.