Return clear exit statuses from a CSV preflight check
Quick answer
Give a CSV preflight distinct statuses for a clean file, a completed check that found a contract mismatch, and input that could not be parsed. A shell caller can continue on 0, collect a reviewable finding on 2, and stop on 3 because the parser never completed. The numbers are a local command contract, not csv defaults.
Example
preflight parses actual CSV text with csv.reader and strict=True. It accepts an exact id,email header and two-field data rows. A different header becomes a completed finding, while the unclosed quoted field makes the strict reader raise csv.Error and becomes an input error. The assertions exercise all three outcomes.
import csv
import io
CLEAN = 0
FINDINGS = 2
INPUT_ERROR = 3
def preflight(text):
try:
rows = list(csv.reader(io.StringIO(text, newline=""), strict=True))
except csv.Error:
return INPUT_ERROR
if not rows or rows[0] != ["id", "email"]:
return FINDINGS
if any(len(row) != 2 for row in rows[1:]):
return FINDINGS
return CLEAN
assert preflight("id,email\n1,a@example.test\n") == CLEAN
assert preflight("id,name\n1,A\n") == FINDINGS
assert preflight('id,email\n1,"open\n') == INPUT_ERROR
print("clean=0 findings=2 input-error=3")
Expected stdout:
clean=0 findings=2 input-error=3
Reading the result
The FINDINGS status means the source was readable but did not meet this small contract. It should not be used for an exception that prevented complete validation, because a batch loop could otherwise treat a partial result as safe to review or import. For an executable CLI, return the selected value from main through SystemExit; the pure function here keeps all normal and failure cases runnable in one deterministic example.
This preflight deliberately checks only parser syntax, one header, and row width. It does not validate email syntax, decoding, duplicate IDs, or report-file writes. Allocate separate stable codes only when callers need to distinguish those failure classes.
Sources
- Python csv.reader documentation
- Python csv Dialect.strict documentation
Prepared with AI assistance. The example uses synthetic data; its stated limits apply.
Comments
Post a Comment