test: sanctioned functions hold exactly their one table's probe; bare raises requires from-pytest import binding

- every raw statement naming either table in a sanctioned function must
  be exactly that function's expected-table probe (cross-table inserts
  rejected); per-function count still enforces exactly one
- bare Name('raises') is trusted only when the file imports it from
  pytest (from pytest import ... raises); other import bindings
  rejected
This commit is contained in:
Joshua King
2026-09-14 09:03:23 -04:00
parent d1e4603a15
commit fe8ceb2f40
+37 -23
View File
@@ -657,12 +657,21 @@ def test_dao_matrix_test_file_raw_probes_are_only_constraint_probes() -> None:
"""Yield (block, is_pytest_integrity) for pytest.raises blocks. """Yield (block, is_pytest_integrity) for pytest.raises blocks.
Structurally exact: the call func must resolve to Structurally exact: the call func must resolve to
pytest.raises (Attribute pytest.raises, or a bare Name pytest.raises — Attribute(pytest, raises) or a bare Name
imported from pytest — checked against the file's import whose id is bound to pytest via the file's own import
section), and the matcher argument must be an AST chain section (validated below). The matcher argument must be an
whose final segment is exactly IntegrityError (so AST chain whose final segment is exactly IntegrityError (so
NotIntegrityError and fake.IntegrityError fail). NotIntegrityError and fake.IntegrityError fail).
""" """
# Names this file imports from pytest as `raises` (e.g.
# `from pytest import raises`): a bare Name is only trusted
# when bound that way. `from x import raises` for x != pytest
# is rejected.
imported_as_raises = re.search(
r"from\s+pytest\s+import\s+.*\braises\b",
text,
re.IGNORECASE,
)
for sub in ast.walk(node): for sub in ast.walk(node):
if not ( if not (
isinstance(sub, ast.With) isinstance(sub, ast.With)
@@ -680,7 +689,7 @@ def test_dao_matrix_test_file_raw_probes_are_only_constraint_probes() -> None:
): ):
continue continue
elif isinstance(func, ast.Name): elif isinstance(func, ast.Name):
if func.id != "raises": if func.id != "raises" or not imported_as_raises:
continue continue
else: else:
continue continue
@@ -730,28 +739,33 @@ def test_dao_matrix_test_file_raw_probes_are_only_constraint_probes() -> None:
last = segments[-1].strip("`'\"[]") last = segments[-1].strip("`'\"[]")
return last.casefold() == table.casefold() return last.casefold() == table.casefold()
# In a sanctioned function, EVERY raw statement naming either
# table must be exactly that function's one expected-table
# constraint insert — an admin_users insert inside the children
# function (or vice versa) is a bypass attempt and fails here,
# as does any second insert of the expected table.
for insert, rendered in raw_statements: for insert, rendered in raw_statements:
if not any_table.search(rendered): if not any_table.search(rendered):
continue continue
assert allowed_stmt.match(rendered.strip()) is not None, ( assert _is_insert_into_table(rendered, table), (
f"{node.name}: raw {table} table SQL " f"{node.name}: raw statement naming the other table is "
f"must be INSERT or SELECT, got: {rendered[:80]!r}" f"forbidden; only the {table} probe is sanctioned: "
f"{rendered[:80]!r}"
) )
if _is_insert_into_table(rendered, table): # This is the sanctioned probe: require pytest.raises
# This is the sanctioned probe: require pytest.raises # with an exact IntegrityError matcher around it.
# with an exact IntegrityError matcher around it. inside = any(
inside = any( block.lineno <= insert.lineno
block.lineno <= insert.lineno and insert.end_lineno <= block.end_lineno
and insert.end_lineno <= block.end_lineno and matcher_ok
and matcher_ok for block, matcher_ok in _raises_blocks()
for block, matcher_ok in _raises_blocks() )
) assert inside, (
assert inside, ( f"the raw {table} insert in {node.name} must be nested "
f"the raw {table} insert in {node.name} must be nested " "in a pytest.raises(...IntegrityError...) block "
"in a pytest.raises(...IntegrityError...) block " "(expected-to-fail constraint probe, not a write)"
"(expected-to-fail constraint probe, not a write)" )
) probes_per_function[node.name] += 1
probes_per_function[node.name] += 1
# UPDATE/DELETE naming the tables anywhere in a sanctioned # UPDATE/DELETE naming the tables anywhere in a sanctioned
# function is forbidden outright. # function is forbidden outright.
for _, rendered in raw_statements: for _, rendered in raw_statements: