Skip to content

Commit bc35beb

Browse files
committed
Undocument and clean up sqlite3.OptimizedUnicode
Closes #13921.
1 parent f0f9679 commit bc35beb

10 files changed

Lines changed: 24 additions & 50 deletions

File tree

‎Doc/includes/sqlite3/text_factory.py‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,3 @@
3030
"\xe4\xf6\xfc".encode("latin1"),))
3131
row = cur.fetchone()
3232
assert type(row[0]) == str
33-
34-
# sqlite3 offers a built-in optimized text_factory that will return bytestring
35-
# objects, if the data is in ASCII only, and otherwise return unicode objects
36-
con.text_factory = sqlite3.OptimizedUnicode
37-
cur.execute("select ?", (AUSTRIA,))
38-
row = cur.fetchone()
39-
assert type(row[0]) == str
40-
41-
cur.execute("select ?", ("Germany",))
42-
row = cur.fetchone()
43-
assert type(row[0]) == str

‎Doc/library/sqlite3.rst‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,6 @@ Connection Objects
436436
:mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to
437437
return bytestrings instead, you can set it to :class:`bytes`.
438438

439-
For efficiency reasons, there's also a way to return :class:`str` objects
440-
only for non-ASCII data, and :class:`bytes` otherwise. To activate it, set
441-
this attribute to :const:`sqlite3.OptimizedUnicode`.
442-
443439
You can also set it to any other callable that accepts a single bytestring
444440
parameter and returns the resulting object.
445441

‎Lib/sqlite3/test/factory.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ def CheckCustom(self):
178178
self.assertTrue(row[0].endswith("reich"), "column must contain original data")
179179

180180
def CheckOptimizedUnicode(self):
181+
# In py3k, str objects are always returned when text_factory
182+
# is OptimizedUnicode
181183
self.con.text_factory = sqlite.OptimizedUnicode
182184
austria = "Österreich"
183185
germany = "Deutchland"

‎Misc/NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,10 @@ Core and Builtins
466466
Library
467467
-------
468468

469+
- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode,
470+
which is obsolete in Python 3.x. It's now aliased to str for
471+
backwards compatibility.
472+
469473
- When '' is a path (e.g. in sys.path), make sure __file__ uses the current
470474
working directory instead of '' in importlib.
471475

‎Modules/_sqlite/connection.h‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ typedef struct
8383

8484
/* Determines how bytestrings from SQLite are converted to Python objects:
8585
* - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings
86-
* - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created.
87-
* - PyBytes_Type: PyStrings are created as-is.
86+
* - PyBytes_Type: The bytestrings are returned as-is.
8887
* - Any custom callable: Any object returned from the callable called with the bytestring
8988
* as single parameter.
9089
*/

‎Modules/_sqlite/cursor.c‎

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,6 @@ PyObject* _pysqlite_build_column_name(const char* colname)
267267
}
268268
}
269269

270-
PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t size, int optimize)
271-
{
272-
return PyUnicode_FromStringAndSize(val_str, size);
273-
}
274-
275270
/*
276271
* Returns a row from the currently active SQLite statement
277272
*
@@ -355,12 +350,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
355350
} else if (coltype == SQLITE_TEXT) {
356351
val_str = (const char*)sqlite3_column_text(self->statement->st, i);
357352
nbytes = sqlite3_column_bytes(self->statement->st, i);
358-
if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
359-
|| (self->connection->text_factory == pysqlite_OptimizedUnicode)) {
360-
361-
converted = pysqlite_unicode_from_string(val_str, nbytes,
362-
self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0);
363-
353+
if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) {
354+
converted = PyUnicode_FromStringAndSize(val_str, nbytes);
364355
if (!converted) {
365356
colname = sqlite3_column_name(self->statement->st, i);
366357
if (!colname) {
@@ -459,7 +450,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
459450
int statement_type;
460451
PyObject* descriptor;
461452
PyObject* second_argument = NULL;
462-
int allow_8bit_chars;
463453

464454
if (!check_cursor(self)) {
465455
goto error;
@@ -468,10 +458,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
468458
self->locked = 1;
469459
self->reset = 0;
470460

471-
/* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
472-
allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
473-
(self->connection->text_factory != pysqlite_OptimizedUnicode));
474-
475461
Py_XDECREF(self->next_row);
476462
self->next_row = NULL;
477463

@@ -630,7 +616,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
630616

631617
pysqlite_statement_mark_dirty(self->statement);
632618

633-
pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars);
619+
pysqlite_statement_bind_parameters(self->statement, parameters);
634620
if (PyErr_Occurred()) {
635621
goto error;
636622
}

‎Modules/_sqlite/module.c‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
PyObject* pysqlite_Error, *pysqlite_Warning, *pysqlite_InterfaceError, *pysqlite_DatabaseError,
3939
*pysqlite_InternalError, *pysqlite_OperationalError, *pysqlite_ProgrammingError,
40-
*pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError, *pysqlite_OptimizedUnicode;
40+
*pysqlite_IntegrityError, *pysqlite_DataError, *pysqlite_NotSupportedError;
4141

4242
PyObject* converters;
4343
int _enable_callback_tracebacks;
@@ -407,13 +407,13 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
407407
}
408408
PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError);
409409

410-
/* We just need "something" unique for pysqlite_OptimizedUnicode. It does not really
411-
* need to be a string subclass. Just anything that can act as a special
412-
* marker for us. So I pulled PyCell_Type out of my magic hat.
413-
*/
414-
Py_INCREF((PyObject*)&PyCell_Type);
415-
pysqlite_OptimizedUnicode = (PyObject*)&PyCell_Type;
416-
PyDict_SetItemString(dict, "OptimizedUnicode", pysqlite_OptimizedUnicode);
410+
/* In Python 2.x, setting Connection.text_factory to
411+
OptimizedUnicode caused Unicode objects to be returned for
412+
non-ASCII data and bytestrings to be returned for ASCII data.
413+
Now OptimizedUnicode is an alias for str, so it has no
414+
effect. */
415+
Py_INCREF((PyObject*)&PyUnicode_Type);
416+
PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type);
417417

418418
/* Set integer constants */
419419
for (i = 0; _int_constants[i].constant_name != 0; i++) {

‎Modules/_sqlite/module.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ extern PyObject* pysqlite_IntegrityError;
3838
extern PyObject* pysqlite_DataError;
3939
extern PyObject* pysqlite_NotSupportedError;
4040

41-
extern PyObject* pysqlite_OptimizedUnicode;
42-
4341
/* the functions time.time() and time.sleep() */
4442
extern PyObject* time_time;
4543
extern PyObject* time_sleep;

‎Modules/_sqlite/statement.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
8787
return rc;
8888
}
8989

90-
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars)
90+
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)
9191
{
9292
int rc = SQLITE_OK;
9393
PY_LONG_LONG longlongval;
@@ -166,7 +166,7 @@ static int _need_adapt(PyObject* obj)
166166
}
167167
}
168168

169-
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars)
169+
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters)
170170
{
171171
PyObject* current_param;
172172
PyObject* adapted;
@@ -220,7 +220,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
220220
}
221221
}
222222

223-
rc = pysqlite_statement_bind_parameter(self, i + 1, adapted, allow_8bit_chars);
223+
rc = pysqlite_statement_bind_parameter(self, i + 1, adapted);
224224
Py_DECREF(adapted);
225225

226226
if (rc != SQLITE_OK) {
@@ -265,7 +265,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
265265
}
266266
}
267267

268-
rc = pysqlite_statement_bind_parameter(self, i, adapted, allow_8bit_chars);
268+
rc = pysqlite_statement_bind_parameter(self, i, adapted);
269269
Py_DECREF(adapted);
270270

271271
if (rc != SQLITE_OK) {

‎Modules/_sqlite/statement.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ extern PyTypeObject pysqlite_StatementType;
4646
int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql);
4747
void pysqlite_statement_dealloc(pysqlite_Statement* self);
4848

49-
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars);
50-
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars);
49+
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter);
50+
void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters);
5151

5252
int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters);
5353
int pysqlite_statement_finalize(pysqlite_Statement* self);

0 commit comments

Comments
 (0)