CSV (comma-separated values) is a text format for exchanging tabular records, with delimiters separating fields and quoting rules protecting delimiters that belong inside a field. In quant work, a correctly downloaded price file can still feed the wrong inputs into a calculation if an importer misreads a quoted name, removes leading zeros from an identifier or guesses the wrong price units.
CSV carries field text; it does not by itself specify the financial meaning or data type of each column. A filename ending in
.csv is not a complete input contract.A comma can be data
Consider this fictional file, with a header and one instrument record:
symbol,instrument_id,price
"ACME, INC",0012,1000.50The intended symbol is
ACME, INC. The comma inside its double quotes belongs to that symbol. Splitting the record with split(',') produces four pieces, breaking the name in two; the intended record has three fields. String splitting works for a deliberately restricted delimiter format that excludes embedded delimiters, quotes and record-spanning fields. It is not a general CSV parser.Fictional input. Quoting determines field boundaries; a separate data contract determines what each field means.
Under the common quoting convention described in RFC 4180, section 2, fields containing commas, quotes or line breaks are enclosed in double quotes. An embedded double quote is doubled. Thus a CSV record can span physical lines. RFC 4180 is Informational, not an Internet Standard that every exporter follows.
Read the fields before choosing their types
Python's standard-library
csv.DictReader handles the quoted comma and uses the first record as column names when explicit field names are omitted. In this default quoting mode, field values remain strings:import csv
from io import StringIO
text = 'symbol,instrument_id,price\r\n"ACME, INC",0012,1000.50\r\n'
reader = csv.DictReader(StringIO(text, newline=""), strict=True)
assert reader.fieldnames == ["symbol", "instrument_id", "price"]
row = next(reader)
assert None not in row and all(value is not None for value in row.values())
print(row["symbol"])
print(repr(row["instrument_id"]), repr(row["price"]))
# ACME, INC
# '0012' '1000.50'Keeping
0012 as text preserves the identifier. Converting it to an integer would produce 12, losing its original representation. The price text 1000.50 has not yet established a currency, a unit or a decimal-precision policy. Choose and validate those before calculating exposures. Quoting a field is a parsing instruction, not a declaration that a spreadsheet or another importer must keep it as text.For an actual file, use
with open(path, encoding="utf-8", newline="") as file: when UTF-8 is the agreed encoding, then pass file directly to the reader. Python's CSV parser handles newline boundaries. strict=True catches some malformed CSV; it does not enforce your required header, field count or business rules. DictReader can put surplus fields under a None key or fill missing fields with None, which the example checks explicitly. See the Python CSV contract.Agree on the import contract
A robust handoff makes these choices explicit:
| Choice | Question for the producer |
|---|---|
| Dialect | Comma, semicolon or tab separator? Which quote and escape rules? |
| Header | Present or absent? Which unique column names and ordering are required? |
| Text encoding | Which encoding decodes the file, and is a byte-order mark present? |
| Types and missingness | Which fields stay as text? What denotes missing data? |
| Financial conventions | Which currencies, price units, date formats and time zones apply? |
A semicolon-delimited export needs matching parser settings. A decimal comma needs an explicit number-conversion rule after parsing. Neither should be inferred solely from the extension. Use a CSV writer with the agreed dialect for exports rather than joining values with commas.
This boundary discipline is part of data engineering: retain the original input and the agreed contract so a disputed valuation can be traced back to its source fields.
Continue learning
Files and Exceptions teaches managed file access, explicit encoding and validation after conversion. The full lesson is free with sign-in; a public preview is available. Its simple delimiter example provides the starting point for the boundary checks discussed here.
Sources
- Python 3.14:
csv— CSV File Reading and Writing, especiallyreader,DictReader, dialect parameters and newline handling. The example was executed with Python 3.14.4; the documentation is maintained separately. - RFC 4180: Common Format and MIME Type for CSV Files, sections 2–3 and the Informational status statement.