[pypy-commit] pypy py3k: merge default

bdkearns noreply at buildbot.pypy.org
Tue Mar 5 05:15:02 CET 2013


Author: Brian Kearns <bdkearns at gmail.com>
Branch: py3k
Changeset: r62046:3306e356c360
Date: 2013-03-04 22:19 -0500
http://bitbucket.org/pypy/pypy/changeset/3306e356c360/

Log:	merge default

diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -40,7 +40,7 @@
     except OSError:
         continue
 else:
-    raise ImportError("Could not load C-library, tried: %s" %(names,))
+    raise ImportError("Could not load C-library, tried: %s" % (names,))
 
 # pysqlite version information
 version = "2.6.0"
@@ -158,7 +158,7 @@
 sqlite.sqlite3_value_type.argtypes = [c_void_p]
 sqlite.sqlite3_value_type.restype = c_int
 
-sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p]
+sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int, c_void_p]
 sqlite.sqlite3_bind_blob.restype = c_int
 sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
 sqlite.sqlite3_bind_double.restype = c_int
@@ -174,7 +174,7 @@
 sqlite.sqlite3_bind_parameter_index.restype = c_int
 sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_bind_parameter_name.restype = c_char_p
-sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, TEXT, c_int,c_void_p]
+sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, TEXT, c_int, c_void_p]
 sqlite.sqlite3_bind_text.restype = c_int
 sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int]
 sqlite.sqlite3_busy_timeout.restype = c_int
@@ -311,17 +311,18 @@
 
 
 class Connection(object):
+    db = None
+
     def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="",
                  check_same_thread=True, factory=None, cached_statements=100):
         self.db = c_void_p()
         if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK:
             raise OperationalError("Could not open database")
         if timeout is not None:
-            timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds
+            timeout = int(timeout * 1000)  # pysqlite2 uses timeout in seconds
             sqlite.sqlite3_busy_timeout(self.db, timeout)
 
         self.text_factory = unicode_text_factory
-        self.closed = False
         self.statements = []
         self.statement_counter = 0
         self.row_factory = None
@@ -349,7 +350,11 @@
         if check_same_thread:
             self.thread_ident = thread_get_ident()
 
-    def _get_exception(self, error_code = None):
+    def __del__(self):
+        if self.db:
+            sqlite.sqlite3_close(self.db)
+
+    def _get_exception(self, error_code=None):
         if error_code is None:
             error_code = sqlite.sqlite3_errcode(self.db)
         error_message = sqlite.sqlite3_errmsg(self.db)
@@ -362,8 +367,8 @@
         elif error_code == SQLITE_NOMEM:
             exc = MemoryError
         elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED,
-            SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN,
-            SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA):
+                SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN,
+                SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA):
             exc = OperationalError
         elif error_code == SQLITE_CORRUPT:
             exc = DatabaseError
@@ -441,6 +446,7 @@
 
     def _get_isolation_level(self):
         return self._isolation_level
+
     def _set_isolation_level(self, val):
         if val is None:
             self.commit()
@@ -517,7 +523,9 @@
             self._reset_cursors()
 
     def _check_closed(self):
-        if getattr(self, 'closed', True):
+        if self.db is None:
+            raise ProgrammingError("Base Connection.__init__ not called.")
+        if not self.db:
             raise ProgrammingError("Cannot operate on a closed database.")
 
     def __enter__(self):
@@ -530,23 +538,23 @@
             self.rollback()
 
     def _get_total_changes(self):
+        self._check_closed()
         return sqlite.sqlite3_total_changes(self.db)
     total_changes = property(_get_total_changes)
 
     def close(self):
         self._check_thread()
-        if self.closed:
-            return
+
         for statement in self.statements:
             obj = statement()
             if obj is not None:
                 obj.finalize()
 
-        self.closed = True
-        ret = sqlite.sqlite3_close(self.db)
-        self._reset_cursors()
-        if ret != SQLITE_OK:
-            raise self._get_exception(ret)
+        if self.db:
+            ret = sqlite.sqlite3_close(self.db)
+            if ret != SQLITE_OK:
+                raise self._get_exception(ret)
+            self.db.value = 0
 
     def create_collation(self, name, callback):
         self._check_thread()
@@ -571,7 +579,6 @@
             c_collation_callback = COLLATION(collation_callback)
             self._collations[name] = c_collation_callback
 
-
         ret = sqlite.sqlite3_create_collation(self.db, name,
                                               SQLITE_UTF8,
                                               None,
@@ -655,7 +662,7 @@
 
                 aggregate_ptr = cast(
                     sqlite.sqlite3_aggregate_context(
-                    context, sizeof(c_ssize_t)),
+                        context, sizeof(c_ssize_t)),
                     POINTER(c_ssize_t))
 
                 if not aggregate_ptr[0]:
@@ -684,7 +691,7 @@
 
                 aggregate_ptr = cast(
                     sqlite.sqlite3_aggregate_context(
-                    context, sizeof(c_ssize_t)),
+                        context, sizeof(c_ssize_t)),
                     POINTER(c_ssize_t))
 
                 if aggregate_ptr[0]:
@@ -729,6 +736,7 @@
 
 DML, DQL, DDL = range(3)
 
+
 class CursorLock(object):
     def __init__(self, cursor):
         self.cursor = cursor
@@ -743,6 +751,8 @@
 
 
 class Cursor(object):
+    initialized = False
+
     def __init__(self, con):
         if not isinstance(con, Connection):
             raise TypeError
@@ -757,9 +767,13 @@
         self.statement = None
         self.reset = False
         self.locked = False
+        self.closed = False
+        self.initialized = True
 
     def _check_closed(self):
-        if not getattr(self, 'connection', None):
+        if not self.initialized:
+            raise ProgrammingError("Base Cursor.__init__ not called.")
+        if self.closed:
             raise ProgrammingError("Cannot operate on a closed cursor.")
         self.connection._check_thread()
         self.connection._check_closed()
@@ -915,31 +929,40 @@
         return sqlite.sqlite3_last_insert_rowid(self.connection.db)
 
     def close(self):
-        if not self.connection:
-            return
-        self._check_closed()
+        self.connection._check_thread()
+        self.connection._check_closed()
         if self.statement:
             self.statement.reset()
             self.statement = None
-        self.connection.cursors.remove(weakref.ref(self))
-        self.connection = None
+        self.closed = True
+
+    def __del__(self):
+        if self.initialized:
+            if self.statement:
+                self.statement.reset()
+            try:
+                self.connection.cursors.remove(weakref.ref(self))
+            except ValueError:
+                pass
 
     def setinputsizes(self, *args):
         pass
+
     def setoutputsize(self, *args):
         pass
 
-
     description = property(_getdescription)
     lastrowid = property(_getlastrowid)
 
+
 class Statement(object):
+    statement = None
+
     def __init__(self, connection, sql):
-        self.statement = None
         if not isinstance(sql, str):
             raise ValueError("sql must be a string")
         self.con = connection
-        self.sql = sql # DEBUG ONLY
+        self.sql = sql  # DEBUG ONLY
         first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper()
         if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"):
             self.kind = DML
@@ -1141,8 +1164,8 @@
         self.in_use = True
 
     def __del__(self):
-        sqlite.sqlite3_finalize(self.statement)
-        self.statement = None
+        if self.statement:
+            sqlite.sqlite3_finalize(self.statement)
 
     def _get_description(self):
         if self.kind == DML:
@@ -1154,6 +1177,7 @@
             desc.append((name, None, None, None, None, None, None))
         return desc
 
+
 class Row(object):
     def __init__(self, cursor, values):
         self.description = cursor.description
@@ -1187,6 +1211,7 @@
     def __hash__(self):
         return hash(tuple(self.description)) ^ hash(tuple(self.values))
 
+
 def _check_remaining_sql(s):
     state = "NORMAL"
     for char in s:
@@ -1229,8 +1254,9 @@
                 return 1
     return 0
 
+
 def _convert_params(con, nargs, params):
-    _params  = []
+    _params = []
     for i in range(nargs):
         typ = sqlite.sqlite3_value_type(params[i])
         if typ == SQLITE_INTEGER:
@@ -1254,6 +1280,7 @@
         _params.append(val)
     return _params
 
+
 def _convert_result(con, val):
     if val is None:
         sqlite.sqlite3_result_null(con)
@@ -1270,6 +1297,7 @@
     else:
         raise NotImplementedError
 
+
 def function_callback(real_cb, context, nargs, c_params):
     params = _convert_params(context, nargs, c_params)
     try:
@@ -1304,15 +1332,19 @@
 converters = {}
 adapters = {}
 
+
 class PrepareProtocol(object):
     pass
 
+
 def register_adapter(typ, callable):
     adapters[typ, PrepareProtocol] = callable
 
+
 def register_converter(name, callable):
     converters[name.upper()] = callable
 
+
 def register_adapters_and_converters():
     def adapt_date(val):
         return val.isoformat()
@@ -1332,16 +1364,15 @@
             microseconds = int(timepart_full[1])
         else:
             microseconds = 0
-
-        val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds)
-        return val
-
+        return datetime.datetime(year, month, day,
+                                 hours, minutes, seconds, microseconds)
 
     register_adapter(datetime.date, adapt_date)
     register_adapter(datetime.datetime, adapt_datetime)
     register_converter("date", convert_date)
     register_converter("timestamp", convert_timestamp)
 
+
 def adapt(val, proto=PrepareProtocol):
     # look for an adapter in the registry
     adapter = adapters.get((type(val), proto), None)
@@ -1372,6 +1403,7 @@
 
 register_adapters_and_converters()
 
+
 def OptimizedUnicode(s):
     try:
         val = str(s, "ascii").encode("ascii")
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py
@@ -76,6 +76,8 @@
                ( 'accept',                ['cd '])])
 
 
+# interrupt uses os.kill which doesn't go through signal handlers on windows
+ at pytest.mark.skipif("os.name == 'nt'")
 def test_interrupt():
     with pytest.raises(KeyboardInterrupt):
         read_spec([('interrupt', [''])])
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py
@@ -45,6 +45,8 @@
     ]
     read_spec(spec, HistoricalTestReader)
 
+
+ at pytest.mark.skipif("os.name != 'posix'")
 def test_signal_failure(monkeypatch):
     import os
     import pty
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py
--- a/pypy/module/test_lib_pypy/pyrepl/test_readline.py
+++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py
@@ -1,9 +1,12 @@
-from pyrepl.readline import _ReadlineWrapper
-import os
-import pty
+import pytest
 
 
+ at pytest.mark.skipif("os.name != 'posix'")
 def test_raw_input():
+    import os
+    import pty
+    from pyrepl.readline import _ReadlineWrapper
+
     master, slave = pty.openpty()
     readline_wrapper = _ReadlineWrapper(slave, slave)
     os.write(master, b'input\n')
diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py
--- a/pypy/module/test_lib_pypy/test_sqlite3.py
+++ b/pypy/module/test_lib_pypy/test_sqlite3.py
@@ -4,10 +4,12 @@
 if sys.version_info < (2, 7):
     skip("lib_pypy._sqlite3 doesn't work with python < 2.7")
 
+import pytest
+from lib_pypy import _sqlite3
+
 def test_list_ddl():
     """From issue996.  Mostly just looking for lack of exceptions."""
-    from lib_pypy._sqlite3 import connect
-    connection = connect(':memory:')
+    connection = _sqlite3.connect(':memory:')
     cursor = connection.cursor()
     cursor.execute('CREATE TABLE foo (bar INTEGER)')
     result = list(cursor)
@@ -18,3 +20,63 @@
     cursor.execute('SELECT * FROM foo')
     result = list(cursor)
     assert result == [(42,)]
+
+def test_total_changes_after_close():
+    con = _sqlite3.connect(':memory:')
+    con.close()
+    pytest.raises(_sqlite3.ProgrammingError, "con.total_changes")
+
+def test_connection_check_init():
+    class Connection(_sqlite3.Connection):
+        def __init__(self, name):
+            pass
+
+    con = Connection(":memory:")
+    e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()")
+    assert '__init__' in e.value.message
+
+def test_cursor_check_init():
+    class Cursor(_sqlite3.Cursor):
+        def __init__(self, name):
+            pass
+
+    con = _sqlite3.connect(":memory:")
+    cur = Cursor(con)
+    e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')")
+    assert '__init__' in e.value.message
+
+def test_cursor_after_close():
+     con = _sqlite3.connect(':memory:')
+     cur = con.execute('select 1')
+     cur.close()
+     con.close()
+     pytest.raises(_sqlite3.ProgrammingError, "cur.close()")
+
+ at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')")
+def test_cursor_del():
+    con = _sqlite3.connect(':memory:')
+    cur = con.execute('select 1')
+    stmt = cur.statement
+    cur.close()
+    cur = con.execute('select 1')
+    assert cur.statement is stmt
+    del cur; import gc; gc.collect(); gc.collect()
+    cur = con.execute('select 1')
+    assert cur.statement is stmt
+
+ at pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')")
+def test_connection_del(tmpdir):
+    """For issue1325."""
+    import gc
+
+    def open_many(cleanup):
+        con = []
+        for i in range(1024):
+            con.append(_sqlite3.connect(str(tmpdir.join('test.db'))))
+            if cleanup:
+                con[i] = None
+                gc.collect(); gc.collect()
+
+    pytest.raises(_sqlite3.OperationalError, open_many, False)
+    gc.collect(); gc.collect()
+    open_many(True)


More information about the pypy-commit mailing list