[pypy-commit] pypy stdlib-2.7.13: No clue if it's a good approach, but trying it out: allow cursors to
arigo
pypy.commits at gmail.com
Sun Dec 18 17:29:24 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: stdlib-2.7.13
Changeset: r89170:5d96f9ed88fe
Date: 2016-12-18 23:28 +0100
http://bitbucket.org/pypy/pypy/changeset/5d96f9ed88fe/
Log: No clue if it's a good approach, but trying it out: allow cursors to
linger like 2.7.13, but if they cause SQLITE_LOCKED, reset them all
and try again the operation.
diff --git a/lib-python/2.7/sqlite3/test/regression.py b/lib-python/2.7/sqlite3/test/regression.py
--- a/lib-python/2.7/sqlite3/test/regression.py
+++ b/lib-python/2.7/sqlite3/test/regression.py
@@ -351,10 +351,7 @@
self.assertRaises(ValueError, cur.execute, " \0select 2")
self.assertRaises(ValueError, cur.execute, "select 2\0")
- @test_support.impl_detail(pypy=False)
def CheckCommitCursorReset(self):
- # This test is for logic added in 2.7.13 which PyPy doesn't
- # implement. See http://bugs.python.org/issue29006
"""
Connection.commit() did reset cursors, which made sqlite3
to return rows multiple times when fetched from cursors
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -363,6 +363,14 @@
if cursor is not None:
cursor._reset = True
+ def _reset_all_statements(self):
+ total = 0
+ for weakref in self.__statements:
+ statement = weakref()
+ if statement is not None:
+ total += statement._reset()
+ return total
+
@_check_thread_wrap
@_check_closed_wrap
def __call__(self, sql):
@@ -418,16 +426,6 @@
if not self._in_transaction:
return
- # The following line is a KNOWN DIFFERENCE with CPython 2.7.13.
- # More precisely, the corresponding line was removed in the
- # version 2.7.13 of CPython, but this is causing troubles for
- # PyPy (and potentially for CPython too):
- #
- # http://bugs.python.org/issue29006
- #
- # So for now, we keep this line.
- self.__do_all_statements(Statement._reset, False)
-
statement_star = _ffi.new('sqlite3_stmt **')
ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1,
statement_star, _ffi.NULL)
@@ -827,7 +825,26 @@
self.__statement._set_params(params)
# Actually execute the SQL statement
- ret = _lib.sqlite3_step(self.__statement._statement)
+
+ # NOTE: if we get SQLITE_LOCKED, it's probably because
+ # one of the cursors created previously is still alive
+ # and not reset and the operation we're trying to do
+ # makes Sqlite unhappy about that. In that case, we
+ # automatically reset all cursors and try again. This
+ # is not what CPython does! It is a workaround for a
+ # new feature of 2.7.13. Previously, all cursors would
+ # be reset at commit(), which makes it unlikely to have
+ # cursors lingering around. Since 2.7.13, cursors stay
+ # around instead. This causes problems here---at least:
+ # this is the only place shown by pysqlite tests, and I
+ # can only hope there is no other.
+
+ while True:
+ ret = _lib.sqlite3_step(self.__statement._statement)
+ if (ret == _lib.SQLITE_LOCKED and
+ self.__connection._reset_all_statements()):
+ continue
+ break
if ret == _lib.SQLITE_ROW:
if multiple:
@@ -1057,6 +1074,8 @@
if self._in_use and self._statement:
_lib.sqlite3_reset(self._statement)
self._in_use = False
+ return 1
+ return 0
if sys.version_info[0] < 3:
def __check_decodable(self, param):
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -488,11 +488,6 @@
the rest is kept. If you return an unexpected string from
``__hex__()`` you get an exception (or a crash before CPython 2.7.13).
-* The ``sqlite`` module was updated on 2.7.13 to no longer reset all
- cursors when there is a commit. This causes troubles for PyPy (and
- potentially for CPython too), and so for now we didn't port this change:
- see http://bugs.python.org/issue29006.
-
.. _`is ignored in PyPy`: http://bugs.python.org/issue14621
.. _`little point`: http://events.ccc.de/congress/2012/Fahrplan/events/5152.en.html
.. _`#2072`: https://bitbucket.org/pypy/pypy/issue/2072/
More information about the pypy-commit
mailing list