You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The sqlite3 Blob class registers a weakref to itself on the Connection it came from. These are added to a list and never cleaned up, so if you have a long-lived connection and call .blobopen() repeatedly, you gradually accumulate ever more dead weakrefs.
It looks like the blob weakrefs were added to match a similar system for weakrefs (removed in #144378), but the code to periodically clear out dead weakrefs was missed.
importgcimportsqlite3conn=sqlite3.connect(":memory:")
conn.execute("CREATE TABLE foo(a INTEGER PRIMARY KEY, b BLOB)")
conn.execute("INSERT INTO foo VALUES(NULL, ?)", (b'abcdefpokpokpko',))
conn.commit()
# Create & destroy many Blob objectsfor_inrange(10_000):
conn.blobopen("foo", "b", 1)
# Get a reference to the internal list of blob weakrefs - you may need to play with the index hereblob_list=gc.get_referents(conn)[-3]
print(len(blob_list))
Bug report
Bug description:
The sqlite3
Blobclass registers a weakref to itself on the Connection it came from. These are added to a list and never cleaned up, so if you have a long-lived connection and call.blobopen()repeatedly, you gradually accumulate ever more dead weakrefs.It looks like the blob weakrefs were added to match a similar system for weakrefs (removed in #144378), but the code to periodically clear out dead weakrefs was missed.
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs