Add patches #371 & #384

Clear and reset sqlite3 statements properly in cursor iternext (fixes rhbz#2099049)
Revert a problematic fix of threading._shutdown() again (fixes rhbz#2100282)
This commit is contained in:
Tomáš Hrnčiar 2022-06-24 11:59:24 +02:00
parent 17d458f006
commit 7ce324c29a
3 changed files with 213 additions and 1 deletions

View File

@ -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?= <thrnciar@redhat.com>
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:

View File

@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Erlend Egeberg Aasland <erlend.aasland@protonmail.com>
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;
}

View File

@ -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 <thrnciar@redhat.com> - 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 <mhroncok@redhat.com> - 3.11.0~b3-5
- Build Python with the optimized Blake2 library libb2