From 0ee090f54183461f9ecb8ad8b39c25180199a258 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Tue, 16 Dec 2025 16:22:35 -0800 Subject: [PATCH] Use ctx.meta instead of dynamic attribute for database cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Click's Context.meta dictionary is the proper way to store arbitrary data on the context object, avoiding type checker warnings about dynamic attribute assignment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- sqlite_utils/cli.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 78c9f91..4cd728b 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -50,20 +50,19 @@ def _register_db_for_cleanup(db): ctx = click.get_current_context(silent=True) if ctx is None: return - if not hasattr(ctx, "_databases_to_close"): - ctx._databases_to_close = [] + if "_databases_to_close" not in ctx.meta: + ctx.meta["_databases_to_close"] = [] ctx.call_on_close(lambda: _close_databases(ctx)) - ctx._databases_to_close.append(db) + ctx.meta["_databases_to_close"].append(db) def _close_databases(ctx): """Close all databases registered for cleanup.""" - if hasattr(ctx, "_databases_to_close"): - for db in ctx._databases_to_close: - try: - db.close() - except Exception: - pass + for db in ctx.meta.get("_databases_to_close", []): + try: + db.close() + except Exception: + pass VALID_COLUMN_TYPES = ("INTEGER", "TEXT", "FLOAT", "REAL", "BLOB")