Author: Ronan Lamy <[email protected]>
Branch: py3.6-sqlite
Changeset: r98468:614cd53df90c
Date: 2020-01-06 21:52 +0100
http://bitbucket.org/pypy/pypy/changeset/614cd53df90c/

Log:    Tests and fix for the 'table locked' issue

diff --git a/extra_tests/test_sqlite3.py b/extra_tests/test_sqlite3.py
--- a/extra_tests/test_sqlite3.py
+++ b/extra_tests/test_sqlite3.py
@@ -211,7 +211,6 @@
     con.execute('select 1')
 
 def test_returning_blob_must_own_memory(con):
-    import gc
     con.create_function("returnblob", 0, lambda: memoryview(b"blob"))
     cur = con.execute("select returnblob()")
     val = cur.fetchone()[0]
@@ -311,3 +310,24 @@
     gc.collect()
     gc.collect()
     assert SQLiteBackend.success
+
+def test_locked_table(con):
+    con.execute("CREATE TABLE foo(x)")
+    con.execute("INSERT INTO foo(x) VALUES (?)", [42])
+    cur = con.execute("SELECT * FROM foo")  # foo() is locked while cur is 
active
+    with pytest.raises(_sqlite3.OperationalError):
+        con.execute("DROP TABLE foo")
+
+def test_cursor_close(con):
+    con.execute("CREATE TABLE foo(x)")
+    con.execute("INSERT INTO foo(x) VALUES (?)", [42])
+    cur = con.execute("SELECT * FROM foo")
+    cur.close()
+    con.execute("DROP TABLE foo")  # no error
+
+def test_cursor_del(con):
+    con.execute("CREATE TABLE foo(x)")
+    con.execute("INSERT INTO foo(x) VALUES (?)", [42])
+    con.execute("SELECT * FROM foo")
+    import gc; gc.collect()
+    con.execute("DROP TABLE foo")  # no error
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -741,6 +741,11 @@
 
         self.__initialized = True
 
+    def __del__(self):
+        # Since statements are cached, they can outlive their parent cursor
+        if self.__statement:
+            self.__statement._reset()
+
     def close(self):
         if not self.__initialized:
             raise ProgrammingError("Base Cursor.__init__ not called.")
@@ -872,6 +877,8 @@
             except AttributeError:
                 pass
             self.__rowcount = -1
+            if self.__statement:
+                self.__statement._reset()
             self.__statement = self.__connection._statement_cache.get(sql)
 
             if self.__connection._begin_statement and self.__statement._is_dml:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to