A data pipeline that trusts its input eventually ingests a row where a price arrived as the string "12.99" instead of a number, and the failure surfaces days later as a model that mysteriously got worse. Validating at the boundary turns that into an immediate, specific complaint.
Task: write validate_rows(rows, schema) returning a list of [row_index, field_name] pairs, one for every violation found.
rows is a list of dictionaries. schema maps a field name to a type name: "int", "float", "str" or "bool".One genuine Python trap to handle: bool is a subclass of int. So isinstance(True, int) is True, and a naive check lets True pass as an integer. Treat them as distinct — a True in an "int" field is a violation, and a 1 in a "bool" field is a violation too.
That asymmetry is not pedantry. A boolean flag silently accepted as the number 1 is exactly the kind of type confusion that produces a feature column of mixed meaning, and no later stage will ever notice.