Raise ValueError instead of AssertionError for invalid arguments

User-facing argument validation in db.py previously used bare
assert statements, which vanish entirely under python -O and raise
AssertionError - an exception type callers should not have to
catch for input validation. Fifteen validation sites now raise
ValueError with the same messages. Internal invariants (an
unreachable branch and a post-update rowcount check) remain
asserts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UnLnhsH25Nnv7LHhekUfPd
This commit is contained in:
Claude 2026-07-04 19:19:24 +00:00
commit a2e6ea2eca
No known key found for this signature in database
7 changed files with 83 additions and 63 deletions

View file

@ -77,7 +77,7 @@ def test_convert_output(fresh_db, drop, expected):
def test_convert_output_multiple_column_error(fresh_db):
table = fresh_db["table"]
with pytest.raises(AssertionError) as excinfo:
with pytest.raises(ValueError) as excinfo:
table.convert(["title", "other"], lambda v: v, output="out")
assert "output= can only be used with a single column" in str(excinfo.value)

View file

@ -108,7 +108,7 @@ def test_create_table_with_defaults(fresh_db):
def test_create_table_with_bad_not_null(fresh_db):
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
fresh_db.create_table(
"players", {"name": str, "score": int}, not_null={"mouse"}
)
@ -243,11 +243,11 @@ def test_create_table_column_order(fresh_db, use_table_factory):
# If you specify a column that doesn't point to a table, you get an error:
(("one_id", "two_id", "three_id"), NoObviousTable),
# Tuples of the wrong length get an error:
((("one_id", "one", "id", "five"), ("two_id", "two", "id")), AssertionError),
((("one_id", "one", "id", "five"), ("two_id", "two", "id")), ValueError),
# Likewise a bad column:
((("one_id", "one", "id2"),), AlterError),
# Or a list of dicts
(({"one_id": "one"},), AssertionError),
(({"one_id": "one"},), ValueError),
),
)
@pytest.mark.parametrize("use_table_factory", [True, False])
@ -700,7 +700,7 @@ def test_bulk_insert_more_than_999_values(fresh_db):
def test_error_if_more_than_999_columns(fresh_db, num_columns, should_error):
record = dict([("c{}".format(i), i) for i in range(num_columns)])
if should_error:
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
fresh_db["big"].insert(record)
else:
fresh_db["big"].insert(record)
@ -1061,7 +1061,7 @@ def test_create_table_numpy(fresh_db):
def test_cannot_provide_both_filename_and_memory():
with pytest.raises(
AssertionError, match="Either specify a filename_or_conn or pass memory=True"
ValueError, match="Either specify a filename_or_conn or pass memory=True"
):
Database("/tmp/foo.db", memory=True)
@ -1214,7 +1214,7 @@ def test_create_if_not_exists(fresh_db):
def test_create_if_no_columns(fresh_db):
with pytest.raises(AssertionError) as error:
with pytest.raises(ValueError) as error:
fresh_db["t"].create({})
assert error.value.args[0] == "Tables must have at least one column"

View file

@ -15,7 +15,7 @@ def test_create_view_error(fresh_db):
def test_create_view_only_arrow_one_param(fresh_db):
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
fresh_db.create_view("bar", "select 1 + 2", ignore=True, replace=True)

View file

@ -139,9 +139,9 @@ def test_m2m_lookup(fresh_db):
def test_m2m_requires_either_records_or_lookup(fresh_db):
people = fresh_db.table("people", pk="id").insert({"name": "Wahyu"})
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
people.m2m("tags")
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
people.m2m("tags", {"tag": "hello"}, lookup={"foo": "bar"})

View file

@ -15,7 +15,7 @@ def test_recreate_ignored_for_in_memory():
def test_recreate_not_allowed_for_connection():
conn = sqlite3.connect(":memory:")
try:
with pytest.raises(AssertionError):
with pytest.raises(ValueError):
Database(conn, recreate=True)
finally:
conn.close()