Python First Verification
The first Python verification should prove async execution through a real provider, not just import generated modules.
1. Static package checks
python -m compileall generated/python-lib app tests
python -m pytest -q
rg 'def purpose|execute_for_list|execute_entities_for_list' generated/python-lib
Inspect function signatures. Every execution terminal must receive only ctx; a
second data-service argument must produce Python's normal TypeError.
2. SQLite round trip
Use tmp_path so every test owns its database. Build a trusted context with the
generated metadata and aiosqlite data service, ensure schema, save an audited entity,
query it, recreate the provider/context, and query it again.
@pytest.mark.asyncio
async def test_sqlite_round_trip(tmp_path):
ctx = await new_sqlite_context(tmp_path / "first.db")
order = (
Q.customer_orders().comment("Create verification order")
.purpose("Verify SQLite persistence").new_entity(ctx)
)
order.update_order_number("VERIFY-10001")
await order.audit_as("Create verification fixture").save(ctx)
rows = await (
Q.customer_orders().comment("Read verification order")
.with_order_number_containing("VERIFY-10001")
.purpose("Verify persisted result")
.execute_entities_for_list(ctx)
)
assert len(rows) == 1
Use generated names from your package. The test is incomplete until a reopened connection also sees the row.
3. Loaded-state check
Run a partial projection containing a nullable field. Prove that a loaded null differs
from an unselected field through the generated E facade. This prevents application
logic from treating “not fetched” as a database null.
4. Governance failures
Add tests for missing comment, missing purpose, uninitialized context, missing
audit_as, stale version, unknown dynamic field/operator, invalid range/paging, and
attempts to supply tenant, actor, permissions, provider, or policy in JSON. Expected
behavior is an explicit error, never an empty or broader query.
with pytest.raises(TypeError):
await executable.execute_for_list(ctx, data_service)
The explicit arity test protects the context-only API from regression.
5. Native SQL check
Retain a masked trace showing bound parameters, stable ordering, native aggregate SQL,
and ROW_NUMBER() OVER (PARTITION BY ...) for an exact per-parent limit. Rows, count,
sum, and facets must share the same active filter.
6. Regeneration check
Add a field, regenerate the whole package, reinstall it, compile, and rerun tests.
Confirm centralized plural/predicate naming remains correct. Never preserve a manual
edit under generated models/ or requests/.
Record Python/runtime/generator/provider versions, model hash, commands, exit codes, masked native response, and SQL shape as the baseline evidence.