Skip to content

Commit 81b0599

Browse files
committed
Claude Code helped fix a ton of .close() warnings, refs #692
https://gistpreview.github.io/?730f0c5dc38528a1dd0615f330bd5481
1 parent f77ca0e commit 81b0599

File tree

6 files changed

+119
-30
lines changed

6 files changed

+119
-30
lines changed

sqlite_utils/cli.py

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,28 @@
4444

4545
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
4646

47+
48+
def _register_db_for_cleanup(db):
49+
"""Register a database to be closed when the Click context is cleaned up."""
50+
ctx = click.get_current_context(silent=True)
51+
if ctx is None:
52+
return
53+
if not hasattr(ctx, "_databases_to_close"):
54+
ctx._databases_to_close = []
55+
ctx.call_on_close(lambda: _close_databases(ctx))
56+
ctx._databases_to_close.append(db)
57+
58+
59+
def _close_databases(ctx):
60+
"""Close all databases registered for cleanup."""
61+
if hasattr(ctx, "_databases_to_close"):
62+
for db in ctx._databases_to_close:
63+
try:
64+
db.close()
65+
except Exception:
66+
pass
67+
68+
4769
VALID_COLUMN_TYPES = ("INTEGER", "TEXT", "FLOAT", "REAL", "BLOB")
4870

4971
UNICODE_ERROR = """
@@ -183,6 +205,7 @@ def tables(
183205
sqlite-utils tables trees.db
184206
"""
185207
db = sqlite_utils.Database(path)
208+
_register_db_for_cleanup(db)
186209
_load_extensions(db, load_extension)
187210
headers = ["view" if views else "table"]
188211
if counts:
@@ -309,6 +332,7 @@ def optimize(path, tables, no_vacuum, load_extension):
309332
sqlite-utils optimize chickens.db
310333
"""
311334
db = sqlite_utils.Database(path)
335+
_register_db_for_cleanup(db)
312336
_load_extensions(db, load_extension)
313337
if not tables:
314338
tables = db.table_names(fts4=True) + db.table_names(fts5=True)
@@ -336,6 +360,7 @@ def rebuild_fts(path, tables, load_extension):
336360
sqlite-utils rebuild-fts chickens.db chickens
337361
"""
338362
db = sqlite_utils.Database(path)
363+
_register_db_for_cleanup(db)
339364
_load_extensions(db, load_extension)
340365
if not tables:
341366
tables = db.table_names(fts4=True) + db.table_names(fts5=True)
@@ -360,6 +385,7 @@ def analyze(path, names):
360385
sqlite-utils analyze chickens.db
361386
"""
362387
db = sqlite_utils.Database(path)
388+
_register_db_for_cleanup(db)
363389
try:
364390
if names:
365391
for name in names:
@@ -384,7 +410,9 @@ def vacuum(path):
384410
\b
385411
sqlite-utils vacuum chickens.db
386412
"""
387-
sqlite_utils.Database(path).vacuum()
413+
db = sqlite_utils.Database(path)
414+
_register_db_for_cleanup(db)
415+
db.vacuum()
388416

389417

390418
@cli.command()
@@ -403,6 +431,7 @@ def dump(path, load_extension):
403431
sqlite-utils dump chickens.db
404432
"""
405433
db = sqlite_utils.Database(path)
434+
_register_db_for_cleanup(db)
406435
_load_extensions(db, load_extension)
407436
for line in db.iterdump():
408437
click.echo(line)
@@ -464,6 +493,7 @@ def add_column(
464493
sqlite-utils add-column chickens.db chickens weight float
465494
"""
466495
db = sqlite_utils.Database(path)
496+
_register_db_for_cleanup(db)
467497
_load_extensions(db, load_extension)
468498
try:
469499
db[table].add_column(
@@ -501,6 +531,7 @@ def add_foreign_key(
501531
sqlite-utils add-foreign-key my.db books author_id authors id
502532
"""
503533
db = sqlite_utils.Database(path)
534+
_register_db_for_cleanup(db)
504535
_load_extensions(db, load_extension)
505536
try:
506537
db[table].add_foreign_key(column, other_table, other_column, ignore=ignore)
@@ -528,6 +559,7 @@ def add_foreign_keys(path, foreign_key, load_extension):
528559
authors country_id countries id
529560
"""
530561
db = sqlite_utils.Database(path)
562+
_register_db_for_cleanup(db)
531563
_load_extensions(db, load_extension)
532564
if len(foreign_key) % 4 != 0:
533565
raise click.ClickException(
@@ -559,6 +591,7 @@ def index_foreign_keys(path, load_extension):
559591
sqlite-utils index-foreign-keys chickens.db
560592
"""
561593
db = sqlite_utils.Database(path)
594+
_register_db_for_cleanup(db)
562595
_load_extensions(db, load_extension)
563596
db.index_foreign_keys()
564597

@@ -603,6 +636,7 @@ def create_index(
603636
sqlite-utils create-index chickens.db chickens -- -name
604637
"""
605638
db = sqlite_utils.Database(path)
639+
_register_db_for_cleanup(db)
606640
_load_extensions(db, load_extension)
607641
# Treat -prefix as descending for columns
608642
columns = []
@@ -660,6 +694,7 @@ def enable_fts(
660694
fts_version = "FTS4"
661695

662696
db = sqlite_utils.Database(path)
697+
_register_db_for_cleanup(db)
663698
_load_extensions(db, load_extension)
664699
try:
665700
db[table].enable_fts(
@@ -691,6 +726,7 @@ def populate_fts(path, table, column, load_extension):
691726
sqlite-utils populate-fts chickens.db chickens name
692727
"""
693728
db = sqlite_utils.Database(path)
729+
_register_db_for_cleanup(db)
694730
_load_extensions(db, load_extension)
695731
db[table].populate_fts(column)
696732

@@ -712,6 +748,7 @@ def disable_fts(path, table, load_extension):
712748
sqlite-utils disable-fts chickens.db chickens
713749
"""
714750
db = sqlite_utils.Database(path)
751+
_register_db_for_cleanup(db)
715752
_load_extensions(db, load_extension)
716753
db[table].disable_fts()
717754

@@ -734,6 +771,7 @@ def enable_wal(path, load_extension):
734771
"""
735772
for path_ in path:
736773
db = sqlite_utils.Database(path_)
774+
_register_db_for_cleanup(db)
737775
_load_extensions(db, load_extension)
738776
db.enable_wal()
739777

@@ -756,6 +794,7 @@ def disable_wal(path, load_extension):
756794
"""
757795
for path_ in path:
758796
db = sqlite_utils.Database(path_)
797+
_register_db_for_cleanup(db)
759798
_load_extensions(db, load_extension)
760799
db.disable_wal()
761800

@@ -777,6 +816,7 @@ def enable_counts(path, tables, load_extension):
777816
sqlite-utils enable-counts chickens.db
778817
"""
779818
db = sqlite_utils.Database(path)
819+
_register_db_for_cleanup(db)
780820
_load_extensions(db, load_extension)
781821
if not tables:
782822
db.enable_counts()
@@ -805,6 +845,7 @@ def reset_counts(path, load_extension):
805845
sqlite-utils reset-counts chickens.db
806846
"""
807847
db = sqlite_utils.Database(path)
848+
_register_db_for_cleanup(db)
808849
_load_extensions(db, load_extension)
809850
db.reset_counts()
810851

@@ -964,6 +1005,7 @@ def insert_upsert_implementation(
9641005
strict=False,
9651006
):
9661007
db = sqlite_utils.Database(path)
1008+
_register_db_for_cleanup(db)
9671009
_load_extensions(db, load_extension)
9681010
_maybe_register_functions(db, functions)
9691011
if (delimiter or quotechar or sniff or no_headers) and not tsv:
@@ -1480,6 +1522,7 @@ def create_database(path, enable_wal, init_spatialite, load_extension):
14801522
sqlite-utils create-database trees.db
14811523
"""
14821524
db = sqlite_utils.Database(path)
1525+
_register_db_for_cleanup(db)
14831526
if enable_wal:
14841527
db.enable_wal()
14851528

@@ -1569,6 +1612,7 @@ def create_table(
15691612
Valid column types are text, integer, float and blob.
15701613
"""
15711614
db = sqlite_utils.Database(path)
1615+
_register_db_for_cleanup(db)
15721616
_load_extensions(db, load_extension)
15731617
if len(columns) % 2 == 1:
15741618
raise click.ClickException(
@@ -1620,6 +1664,7 @@ def duplicate(path, table, new_table, ignore, load_extension):
16201664
Create a duplicate of this table, copying across the schema and all row data.
16211665
"""
16221666
db = sqlite_utils.Database(path)
1667+
_register_db_for_cleanup(db)
16231668
_load_extensions(db, load_extension)
16241669
try:
16251670
db[table].duplicate(new_table)
@@ -1643,6 +1688,7 @@ def rename_table(path, table, new_name, ignore, load_extension):
16431688
Rename this table.
16441689
"""
16451690
db = sqlite_utils.Database(path)
1691+
_register_db_for_cleanup(db)
16461692
_load_extensions(db, load_extension)
16471693
try:
16481694
db.rename_table(table, new_name)
@@ -1671,6 +1717,7 @@ def drop_table(path, table, ignore, load_extension):
16711717
sqlite-utils drop-table chickens.db chickens
16721718
"""
16731719
db = sqlite_utils.Database(path)
1720+
_register_db_for_cleanup(db)
16741721
_load_extensions(db, load_extension)
16751722
try:
16761723
db[table].drop(ignore=ignore)
@@ -1707,6 +1754,7 @@ def create_view(path, view, select, ignore, replace, load_extension):
17071754
'select * from chickens where weight > 3'
17081755
"""
17091756
db = sqlite_utils.Database(path)
1757+
_register_db_for_cleanup(db)
17101758
_load_extensions(db, load_extension)
17111759
# Does view already exist?
17121760
if view in db.view_names():
@@ -1741,6 +1789,7 @@ def drop_view(path, view, ignore, load_extension):
17411789
sqlite-utils drop-view chickens.db heavy_chickens
17421790
"""
17431791
db = sqlite_utils.Database(path)
1792+
_register_db_for_cleanup(db)
17441793
_load_extensions(db, load_extension)
17451794
try:
17461795
db[view].drop(ignore=ignore)
@@ -1805,6 +1854,7 @@ def query(
18051854
-p age 1
18061855
"""
18071856
db = sqlite_utils.Database(path)
1857+
_register_db_for_cleanup(db)
18081858
for alias, attach_path in attach:
18091859
db.attach(alias, attach_path)
18101860
_load_extensions(db, load_extension)
@@ -1939,6 +1989,8 @@ def memory(
19391989
sqlite-utils memory animals.csv --schema
19401990
"""
19411991
db = sqlite_utils.Database(memory=True)
1992+
if not return_db:
1993+
_register_db_for_cleanup(db)
19421994

19431995
# If --dump or --save or --analyze used but no paths detected, assume SQL query is a path:
19441996
if (dump or save or schema or analyze) and not paths:
@@ -2004,6 +2056,7 @@ def memory(
20042056

20052057
if save:
20062058
db2 = sqlite_utils.Database(save)
2059+
_register_db_for_cleanup(db2)
20072060
for line in db.iterdump():
20082061
db2.execute(line)
20092062
return
@@ -2140,6 +2193,7 @@ def search(
21402193
sqlite-utils search data.db chickens lila
21412194
"""
21422195
db = sqlite_utils.Database(path)
2196+
_register_db_for_cleanup(db)
21432197
_load_extensions(db, load_extension)
21442198
# Check table exists
21452199
table_obj = db[dbtable]
@@ -2307,7 +2361,9 @@ def triggers(
23072361
"""
23082362
sql = "select name, tbl_name as \"table\", sql from sqlite_master where type = 'trigger'"
23092363
if tables:
2310-
quote = sqlite_utils.Database(memory=True).quote
2364+
_quote_db = sqlite_utils.Database(memory=True)
2365+
_register_db_for_cleanup(_quote_db)
2366+
quote = _quote_db.quote
23112367
sql += ' and "table" in ({})'.format(
23122368
", ".join(quote(table) for table in tables)
23132369
)
@@ -2372,7 +2428,9 @@ def indexes(
23722428
sqlite_master.type = 'table'
23732429
"""
23742430
if tables:
2375-
quote = sqlite_utils.Database(memory=True).quote
2431+
_quote_db = sqlite_utils.Database(memory=True)
2432+
_register_db_for_cleanup(_quote_db)
2433+
quote = _quote_db.quote
23762434
sql += " and sqlite_master.name in ({})".format(
23772435
", ".join(quote(table) for table in tables)
23782436
)
@@ -2415,6 +2473,7 @@ def schema(
24152473
sqlite-utils schema trees.db
24162474
"""
24172475
db = sqlite_utils.Database(path)
2476+
_register_db_for_cleanup(db)
24182477
_load_extensions(db, load_extension)
24192478
if tables:
24202479
for table in tables:
@@ -2507,6 +2566,7 @@ def transform(
25072566
--rename column2 column_renamed
25082567
"""
25092568
db = sqlite_utils.Database(path)
2569+
_register_db_for_cleanup(db)
25102570
_load_extensions(db, load_extension)
25112571
types = {}
25122572
kwargs = {}
@@ -2590,6 +2650,7 @@ def extract(
25902650
sqlite-utils extract trees.db Street_Trees species
25912651
"""
25922652
db = sqlite_utils.Database(path)
2653+
_register_db_for_cleanup(db)
25932654
_load_extensions(db, load_extension)
25942655
kwargs = dict(
25952656
columns=columns,
@@ -2734,6 +2795,7 @@ def _content_text(p):
27342795
yield row
27352796

27362797
db = sqlite_utils.Database(path)
2798+
_register_db_for_cleanup(db)
27372799
_load_extensions(db, load_extension)
27382800
try:
27392801
with db.conn:
@@ -2792,6 +2854,7 @@ def analyze_tables(
27922854
sqlite-utils analyze-tables data.db trees
27932855
"""
27942856
db = sqlite_utils.Database(path)
2857+
_register_db_for_cleanup(db)
27952858
_load_extensions(db, load_extension)
27962859
_analyze(db, tables, columns, save, common_limit, no_most, no_least)
27972860

@@ -2991,6 +3054,7 @@ def convert(
29913054
):
29923055
sqlite3.enable_callback_tracebacks(True)
29933056
db = sqlite_utils.Database(db_path)
3057+
_register_db_for_cleanup(db)
29943058
if output is not None and len(columns) > 1:
29953059
raise click.ClickException("Cannot use --output with more than one column")
29963060
if multi and len(columns) > 1:
@@ -3133,6 +3197,7 @@ def add_geometry_column(
31333197
By default, this command will try to load the SpatiaLite extension from usual paths.
31343198
To load it from a specific path, use --load-extension."""
31353199
db = sqlite_utils.Database(db_path)
3200+
_register_db_for_cleanup(db)
31363201
if not db[table].exists():
31373202
raise click.ClickException(
31383203
"You must create a table before adding a geometry column"
@@ -3165,6 +3230,7 @@ def create_spatial_index(db_path, table, column_name, load_extension):
31653230
By default, this command will try to load the SpatiaLite extension from usual paths.
31663231
To load it from a specific path, use --load-extension."""
31673232
db = sqlite_utils.Database(db_path)
3233+
_register_db_for_cleanup(db)
31683234
if not db[table].exists():
31693235
raise click.ClickException(
31703236
"You must create a table and add a geometry column before creating a spatial index"

tests/conftest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ def pytest_configure(config):
1616

1717
@pytest.fixture
1818
def fresh_db():
19-
return Database(memory=True)
19+
db = Database(memory=True)
20+
yield db
21+
db.close()
2022

2123

2224
@pytest.fixture
@@ -30,12 +32,14 @@ def existing_db():
3032
INSERT INTO foo (text) values ("three");
3133
"""
3234
)
33-
return database
35+
yield database
36+
database.close()
3437

3538

3639
@pytest.fixture
3740
def db_path(tmpdir):
3841
path = str(tmpdir / "test.db")
3942
db = sqlite3.connect(path)
4043
db.executescript(CREATE_TABLES)
44+
db.close()
4145
return path

0 commit comments

Comments
 (0)