sqlite3 module allows you to call
Connection.__init__ to reinitialize an existing connection – basically, open a new database using the same connection object.
This is full of corner cases that break, for example, you can currently get a segfault with:
import sqlite3 conn = sqlite3.connect(':memory:') conn.execute('CREATE TABLE foo (bar)') # Attempt to open a new database try: conn.__init__('/bad-file/') except sqlite3.OperationalError: pass # Attempt to use a destroyed database connection conn.execute('INSERT INTO foo (bar) VALUES (1), (2), (3), (4)')
If anyone has a use case for
__init__ on connection objects (or on cursors, etc), rather than creating a new object, I’d love to hear it. But I doubt there is one.
Due to the possibility of bugs in edge cases (and ongoing maintenance burden of keeping the edge cases in mind), we’d like to deprecate re-initialization of objects from
sqlite3 in Python 3.11 and remove it in Python 3.13.
More generally, the tp_new docs say:
tp_newfunction should call
subtype->tp_alloc(subtype, nitems)to allocate space for the object, and then do only as much further initialization as is absolutely necessary. Initialization that can safely be ignored or repeated should be placed in the
tp_inithandler. A good rule of thumb is that for immutable types, all initialization should take place in
tp_new, while for mutable types, most initialization should be deferred to
I believe replacing “immutable types” → “immutable types and state managed in C” and “mutable types” → “properties mutable from Python code” would make a better rule of thumb, but I’m having trouble wording it concisely.