]> granicus.if.org Git - python/commitdiff
Undocument and clean up sqlite3.OptimizedUnicode
authorPetri Lehtinen <petri@digip.org>
Thu, 9 Feb 2012 19:09:03 +0000 (21:09 +0200)
committerPetri Lehtinen <petri@digip.org>
Thu, 9 Feb 2012 19:09:03 +0000 (21:09 +0200)
Closes #13921.

Doc/includes/sqlite3/text_factory.py
Doc/library/sqlite3.rst
Lib/sqlite3/test/factory.py
Misc/NEWS
Modules/_sqlite/connection.h
Modules/_sqlite/cursor.c
Modules/_sqlite/module.c
Modules/_sqlite/module.h
Modules/_sqlite/statement.c
Modules/_sqlite/statement.h

index 22c29700866846b339b0b40ed7b80b729e7af6c0..bdffd36051ba55919ec5289756722a215406f739 100644 (file)
@@ -30,14 +30,3 @@ cur.execute("select ?", ("this is latin1 and would normally create errors" +
                          "\xe4\xf6\xfc".encode("latin1"),))
 row = cur.fetchone()
 assert type(row[0]) == str
-
-# sqlite3 offers a built-in optimized text_factory that will return bytestring
-# objects, if the data is in ASCII only, and otherwise return unicode objects
-con.text_factory = sqlite3.OptimizedUnicode
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert type(row[0]) == str
-
-cur.execute("select ?", ("Germany",))
-row = cur.fetchone()
-assert type(row[0]) == str
index f3acdc51f8a72322538c23dce630ef12e303411e..6fd239e95f760675ca83b80036f5168938545ae8 100644 (file)
@@ -436,10 +436,6 @@ Connection Objects
    :mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to
    return bytestrings instead, you can set it to :class:`bytes`.
 
-   For efficiency reasons, there's also a way to return :class:`str` objects
-   only for non-ASCII data, and :class:`bytes` otherwise. To activate it, set
-   this attribute to :const:`sqlite3.OptimizedUnicode`.
-
    You can also set it to any other callable that accepts a single bytestring
    parameter and returns the resulting object.
 
index 55695851f113b21f7f0beb367e42d929f17c69e8..9e833aedc5e923f685cd8107c712561e26d62614 100644 (file)
@@ -178,6 +178,8 @@ class TextFactoryTests(unittest.TestCase):
         self.assertTrue(row[0].endswith("reich"), "column must contain original data")
 
     def CheckOptimizedUnicode(self):
+        # In py3k, str objects are always returned when text_factory
+        # is OptimizedUnicode
         self.con.text_factory = sqlite.OptimizedUnicode
         austria = "Österreich"
         germany = "Deutchland"
index 146cbb5c9841a875411daa372872ad1dba80b8e4..a14fe6a989c7caa09e3adf5615293a8eba6b87a7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -466,6 +466,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode,
+  which is obsolete in Python 3.x. It's now aliased to str for
+  backwards compatibility.
+
 - When '' is a path (e.g. in sys.path), make sure __file__ uses the current
   working directory instead of '' in importlib.
 
index c8e2f7cbd2b24657284d70274ee6d6026a2f1972..0c9734caf710c6363518bb66a271cefca7398959 100644 (file)
@@ -83,8 +83,7 @@ typedef struct
 
     /* Determines how bytestrings from SQLite are converted to Python objects:
      * - PyUnicode_Type:        Python Unicode objects are constructed from UTF-8 bytestrings
-     * - OptimizedUnicode:      Like before, but for ASCII data, only PyStrings are created.
-     * - PyBytes_Type:         PyStrings are created as-is.
+     * - PyBytes_Type:          The bytestrings are returned as-is.
      * - Any custom callable:   Any object returned from the callable called with the bytestring
      *                          as single parameter.
      */
index 99a861246e00a529e1bc87a5cf4ee5b789fe32f4..8a56d3cd80c21dcf8406c408c87e6a3dcc857751 100644 (file)
@@ -267,11 +267,6 @@ PyObject* _pysqlite_build_column_name(const char* colname)
     }
 }
 
-PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t size, int optimize)
-{
-    return PyUnicode_FromStringAndSize(val_str, size);
-}
-
 /*
  * Returns a row from the currently active SQLite statement
  *
@@ -355,12 +350,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
             } else if (coltype == SQLITE_TEXT) {
                 val_str = (const char*)sqlite3_column_text(self->statement->st, i);
                 nbytes = sqlite3_column_bytes(self->statement->st, i);
-                if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
-                    || (self->connection->text_factory == pysqlite_OptimizedUnicode)) {
-
-                    converted = pysqlite_unicode_from_string(val_str, nbytes,
-                        self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0);
-
+                if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) {
+                    converted = PyUnicode_FromStringAndSize(val_str, nbytes);
                     if (!converted) {
                         colname = sqlite3_column_name(self->statement->st, i);
                         if (!colname) {
@@ -459,7 +450,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
     int statement_type;
     PyObject* descriptor;
     PyObject* second_argument = NULL;
-    int allow_8bit_chars;
 
     if (!check_cursor(self)) {
         goto error;
@@ -468,10 +458,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
     self->locked = 1;
     self->reset = 0;
 
-    /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
-    allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
-        (self->connection->text_factory != pysqlite_OptimizedUnicode));
-
     Py_XDECREF(self->next_row);
     self->next_row = NULL;
 
@@ -630,7 +616,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
 
         pysqlite_statement_mark_dirty(self->statement);
 
-        pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars);
+        pysqlite_statement_bind_parameters(self->statement, parameters);
         if (PyErr_Occurred()) {
             goto error;
         }
index 406d787efad1dee5db87f3d2a73cd2db86b369b7..bea6d6aba1e94b94630fb58d693679f514b65c6e 100644 (file)
@@ -37,7 +37,7 @@
 
 PyObject* pysqlite_Error, *pysqlite_Warning, *pysqlite_InterfaceError, *pysqlite_DatabaseError,
     *pysqlite_InternalError, *pysqlite_OperationalError, *pysqlite_ProgrammingError,
-    *pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError, *pysqlite_OptimizedUnicode;
+    *pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError;
 
 PyObject* converters;
 int _enable_callback_tracebacks;
@@ -407,13 +407,13 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
     }
     PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError);
 
-    /* We just need "something" unique for pysqlite_OptimizedUnicode. It does not really
-     * need to be a string subclass. Just anything that can act as a special
-     * marker for us. So I pulled PyCell_Type out of my magic hat.
-     */
-    Py_INCREF((PyObject*)&PyCell_Type);
-    pysqlite_OptimizedUnicode = (PyObject*)&PyCell_Type;
-    PyDict_SetItemString(dict, "OptimizedUnicode", pysqlite_OptimizedUnicode);
+    /* In Python 2.x, setting Connection.text_factory to
+       OptimizedUnicode caused Unicode objects to be returned for
+       non-ASCII data and bytestrings to be returned for ASCII data.
+       Now OptimizedUnicode is an alias for str, so it has no
+       effect. */
+    Py_INCREF((PyObject*)&PyUnicode_Type);
+    PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type);
 
     /* Set integer constants */
     for (i = 0; _int_constants[i].constant_name != 0; i++) {
index 0eddb679483062dad0940776a0c9dd2228cb9205..b51724bf4cec53aa98cc55215cce533000c749c6 100644 (file)
@@ -38,8 +38,6 @@ extern PyObject* pysqlite_IntegrityError;
 extern PyObject* pysqlite_DataError;
 extern PyObject* pysqlite_NotSupportedError;
 
-extern PyObject* pysqlite_OptimizedUnicode;
-
 /* the functions time.time() and time.sleep() */
 extern PyObject* time_time;
 extern PyObject* time_sleep;
index cc9c310276c89c44d5e6292a8340fdbeb45cf7f4..9884860ec066dcb61caa0d50f7acc1803c5bffb1 100644 (file)
@@ -87,7 +87,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
     return rc;
 }
 
-int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars)
+int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)
 {
     int rc = SQLITE_OK;
     PY_LONG_LONG longlongval;
@@ -166,7 +166,7 @@ static int _need_adapt(PyObject* obj)
     }
 }
 
-void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars)
+void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters)
 {
     PyObject* current_param;
     PyObject* adapted;
@@ -220,7 +220,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
                 }
             }
 
-            rc = pysqlite_statement_bind_parameter(self, i + 1, adapted, allow_8bit_chars);
+            rc = pysqlite_statement_bind_parameter(self, i + 1, adapted);
             Py_DECREF(adapted);
 
             if (rc != SQLITE_OK) {
@@ -265,7 +265,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
                 }
             }
 
-            rc = pysqlite_statement_bind_parameter(self, i, adapted, allow_8bit_chars);
+            rc = pysqlite_statement_bind_parameter(self, i, adapted);
             Py_DECREF(adapted);
 
             if (rc != SQLITE_OK) {
index e5da42e7d83dfa9dafba7ad536229873a9763ef7..4681443e7601e8708608dff1a106eec8eacff06a 100644 (file)
@@ -46,8 +46,8 @@ extern PyTypeObject pysqlite_StatementType;
 int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql);
 void pysqlite_statement_dealloc(pysqlite_Statement* self);
 
-int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars);
-void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars);
+int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter);
+void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters);
 
 int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters);
 int pysqlite_statement_finalize(pysqlite_Statement* self);