diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch new file mode 100644 index 0000000..635b682 --- /dev/null +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= +Date: Tue, 7 Dec 2021 14:41:59 +0100 +Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the + main thread (GH-28549) (GH-28589)" + +This reverts commit 38c67738c64304928c68d5c2bd78bbb01d979b94. It +introduced regression causing FreeIPA's tests to fail. + +For more info see: +https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +--- + Lib/test/test_threading.py | 33 --------------------------------- + Lib/threading.py | 25 ++++++++----------------- + 2 files changed, 8 insertions(+), 50 deletions(-) + +diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py +index 9c6561c099..84714c03fe 100644 +--- a/Lib/test/test_threading.py ++++ b/Lib/test/test_threading.py +@@ -956,39 +956,6 @@ def test_debug_deprecation(self): + b'is deprecated and will be removed in Python 3.12') + self.assertIn(msg, err) + +- def test_import_from_another_thread(self): +- # bpo-1596321: If the threading module is first import from a thread +- # different than the main thread, threading._shutdown() must handle +- # this case without logging an error at Python exit. +- code = textwrap.dedent(''' +- import _thread +- import sys +- +- event = _thread.allocate_lock() +- event.acquire() +- +- def import_threading(): +- import threading +- event.release() +- +- if 'threading' in sys.modules: +- raise Exception('threading is already imported') +- +- _thread.start_new_thread(import_threading, ()) +- +- # wait until the threading module is imported +- event.acquire() +- event.release() +- +- if 'threading' not in sys.modules: +- raise Exception('threading is not imported') +- +- # don't wait until the thread completes +- ''') +- rc, out, err = assert_python_ok("-c", code) +- self.assertEqual(out, b'') +- self.assertEqual(err, b'') +- + + class ThreadJoinOnShutdown(BaseTestCase): + +diff --git a/Lib/threading.py b/Lib/threading.py +index 8e7cdf6f62..a701401f28 100644 +--- a/Lib/threading.py ++++ b/Lib/threading.py +@@ -1546,29 +1546,20 @@ def _shutdown(): + + global _SHUTTING_DOWN + _SHUTTING_DOWN = True ++ # Main thread ++ tlock = _main_thread._tstate_lock ++ # The main thread isn't finished yet, so its thread state lock can't have ++ # been released. ++ assert tlock is not None ++ assert tlock.locked() ++ tlock.release() ++ _main_thread._stop() + + # Call registered threading atexit functions before threads are joined. + # Order is reversed, similar to atexit. + for atexit_call in reversed(_threading_atexits): + atexit_call() + +- # Main thread +- if _main_thread.ident == get_ident(): +- tlock = _main_thread._tstate_lock +- # The main thread isn't finished yet, so its thread state lock can't +- # have been released. +- assert tlock is not None +- assert tlock.locked() +- tlock.release() +- _main_thread._stop() +- else: +- # bpo-1596321: _shutdown() must be called in the main thread. +- # If the threading module was not imported by the main thread, +- # _main_thread is the thread which imported the threading module. +- # In this case, ignore _main_thread, similar behavior than for threads +- # spawned by C libraries or using _thread.start_new_thread(). +- pass +- + # Join all non-deamon threads + while True: + with _shutdown_locks_lock: diff --git a/00384-gh-94028-clear-and-reset-sqlite3-statements-properly-in-cursor-iternext-gh-94042.patch b/00384-gh-94028-clear-and-reset-sqlite3-statements-properly-in-cursor-iternext-gh-94042.patch new file mode 100644 index 0000000..a2ce195 --- /dev/null +++ b/00384-gh-94028-clear-and-reset-sqlite3-statements-properly-in-cursor-iternext-gh-94042.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Erlend Egeberg Aasland +Date: Tue, 21 Jun 2022 13:30:29 +0200 +Subject: [PATCH] 00384: gh-94028: Clear and reset sqlite3 statements properly + in cursor iternext (GH-94042) + +--- + Lib/test/test_sqlite3/test_transactions.py | 39 +++++++++++++++++++ + ...2-06-20-23-14-43.gh-issue-94028.UofEcX.rst | 3 ++ + Modules/_sqlite/cursor.c | 3 ++ + 3 files changed, 45 insertions(+) + create mode 100644 Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst + +diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py +index 040ab1ee60..226a1d03fa 100644 +--- a/Lib/test/test_sqlite3/test_transactions.py ++++ b/Lib/test/test_sqlite3/test_transactions.py +@@ -141,6 +141,45 @@ def test_rollback_cursor_consistency(self): + con.rollback() + self.assertEqual(cur.fetchall(), [(1,), (2,), (3,)]) + ++ def test_multiple_cursors_and_iternext(self): ++ # gh-94028: statements are cleared and reset in cursor iternext. ++ ++ # Provoke the gh-94028 by using a cursor cache. ++ CURSORS = {} ++ def sql(cx, sql, *args): ++ cu = cx.cursor() ++ cu.execute(sql, args) ++ CURSORS[id(sql)] = cu ++ return cu ++ ++ self.con1.execute("create table t(t)") ++ sql(self.con1, "insert into t values (?), (?), (?)", "u1", "u2", "u3") ++ self.con1.commit() ++ ++ # On second connection, verify rows are visible, then delete them. ++ count = sql(self.con2, "select count(*) from t").fetchone()[0] ++ self.assertEqual(count, 3) ++ changes = sql(self.con2, "delete from t").rowcount ++ self.assertEqual(changes, 3) ++ self.con2.commit() ++ ++ # Back in original connection, create 2 new users. ++ sql(self.con1, "insert into t values (?)", "u4") ++ sql(self.con1, "insert into t values (?)", "u5") ++ ++ # The second connection cannot see uncommitted changes. ++ count = sql(self.con2, "select count(*) from t").fetchone()[0] ++ self.assertEqual(count, 0) ++ ++ # First connection can see its own changes. ++ count = sql(self.con1, "select count(*) from t").fetchone()[0] ++ self.assertEqual(count, 2) ++ ++ # The second connection can now see the changes. ++ self.con1.commit() ++ count = sql(self.con2, "select count(*) from t").fetchone()[0] ++ self.assertEqual(count, 2) ++ + + class RollbackTests(unittest.TestCase): + """bpo-44092: sqlite3 now leaves it to SQLite to resolve rollback issues""" +diff --git a/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst +new file mode 100644 +index 0000000000..5775b2276d +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2022-06-20-23-14-43.gh-issue-94028.UofEcX.rst +@@ -0,0 +1,3 @@ ++Fix a regression in the :mod:`sqlite3` where statement objects were not ++properly cleared and reset after use in cursor iters. The regression was ++introduced by PR 27884 in Python 3.11a1. Patch by Erlend E. Aasland. +diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c +index c58def5f03..8048d83683 100644 +--- a/Modules/_sqlite/cursor.c ++++ b/Modules/_sqlite/cursor.c +@@ -1126,10 +1126,13 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) + int rc = stmt_step(stmt); + if (rc == SQLITE_DONE) { + (void)stmt_reset(self->statement); ++ Py_CLEAR(self->statement); + } + else if (rc != SQLITE_ROW) { + (void)_pysqlite_seterror(self->connection->state, + self->connection->db); ++ (void)stmt_reset(self->statement); ++ Py_CLEAR(self->statement); + Py_DECREF(row); + return NULL; + } diff --git a/python3.11.spec b/python3.11.spec index d6c1695..7fdecbb 100644 --- a/python3.11.spec +++ b/python3.11.spec @@ -17,7 +17,7 @@ URL: https://www.python.org/ %global prerel b3 %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 5%{?dist} +Release: 6%{?dist} License: Python @@ -311,6 +311,17 @@ Patch251: 00251-change-user-install-location.patch # Ideally, we should talk to upstream and explain why we don't want this Patch328: 00328-pyc-timestamp-invalidation-mode.patch +# 00371 # c1754d9c2750f89cb702e1b63a99201f5f7cff00 +# Revert "bpo-1596321: Fix threading._shutdown() for the main thread (GH-28549) (GH-28589)" +# +# This reverts commit 38c67738c64304928c68d5c2bd78bbb01d979b94. It +# introduced regression causing FreeIPA's tests to fail. +# +# For more info see: +# https://bodhi.fedoraproject.org/updates/FEDORA-2021-e152ce5f31 +# https://github.com/GrahamDumpleton/mod_wsgi/issues/730 +Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch + # 00383 # b4e1d3233b9fbcd9a60370d0f29e65012bb9532d # gh-93442: Make C++ version of _Py_CAST work with 0/NULL # @@ -324,6 +335,10 @@ Patch328: 00328-pyc-timestamp-invalidation-mode.patch # we want to not break extensions that do things the old way. Patch383: 00383-gh-93442-make-c-version-of-_py_cast-work-with-0-null.patch +# 00384 # 7c809258e34925560cc13a377b1c6d9c03e83207 +# gh-94028: Clear and reset sqlite3 statements properly in cursor iternext (GH-94042) +Patch384: 00384-gh-94028-clear-and-reset-sqlite3-statements-properly-in-cursor-iternext-gh-94042.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -1596,6 +1611,10 @@ CheckPython optimized # ====================================================== %changelog +* Fri Jun 24 2022 Tomáš Hrnčiar - 3.11.0~b3-6 +- Clear and reset sqlite3 statements properly in cursor iternext (fixes rhbz#2099049) +- Revert a problematic fix of threading._shutdown() again (fixes rhbz#2100282) + * Tue Jun 21 2022 Miro Hrončok - 3.11.0~b3-5 - Build Python with the optimized Blake2 library libb2