When a column is defined with DEFAULT TRUE, DEFAULT FALSE, or DEFAULT NULL, SQLite's PRAGMA table_info returns the literal strings "TRUE", "FALSE", or "NULL". _decode_default_value does not handle these keyword literals and falls through to return the raw string instead of the corresponding Python object.
Effect on table.default_values:
import sqlite_utils db = sqlite_utils.Database(memory=True) db.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, flag INTEGER DEFAULT TRUE, nullable TEXT DEFAULT NULL)") print(db["t"].default_values) # {'flag': 'TRUE', 'nullable': 'NULL'} ← wrong; should be {'flag': True, 'nullable': None}
Effect on .transform():
Because default_values returns strings instead of Python booleans/None, the comparison at the transform step that decides whether a table rebuild is needed treats True != "TRUE", triggering an unnecessary table rebuild even when no defaults have changed.
Fix: add three branches to _decode_default_value before the float() attempt:
upper = value.upper() if upper == "TRUE": return True if upper == "FALSE": return False if upper == "NULL": return None