Skip to content

A semicolon-delimited .csv file parses correctly in the web profiler but breaks in the CLI #439

Description

@yakew7

Where: faircode/loaders.py's read_table (.csv/.tsv branches - delimiter hardcoded by extension) vs assets/profiler-engine.js's parseCSV (always calls sniffDelimiter, regardless of the dropped file's extension).

The gap: Python's read_table only sniffs the delimiter for an unrecognized extension - a .csv file is always read via pd.read_csv(path) (comma, hardcoded), a .tsv always via sep="\t". The JS engine ignores the extension entirely and always sniffs (assets/profiler-ui.js routes any non-.xlsx/.json drop straight to E.parseCSV, never checking the extension either). A semicolon-delimited file saved with a .csv extension - a common Excel-locale export - parses fine in the browser tool but silently breaks the CLI.

Repro: a file semicolon.csv containing:

sex;race;age;outcome
M;White;25;1
F;Black;30;0
M;White;45;1
F;Asian;22;0
>>> from faircode.loaders import read_table
>>> read_table('semicolon.csv').shape, list(read_table('semicolon.csv').columns)
((4, 1), ['sex;race;age;outcome'])

vs the identical file through the JS engine:

> E.parseCSV(fs.readFileSync('semicolon.csv','utf8')).columns
[ 'sex', 'race', 'age', 'outcome' ]

Verified directly - the CLI collapses the file into one bogus column; the web profiler parses it correctly.

Why it matters: CONTRIBUTING.md requires the two engines to "keep producing identical results" for this shared logic - here the CLI silently produces a garbage 1-column profile (every row becomes its own "group", all flagged as a tiny sample) for a file the browser tool handles correctly, with no error on either side.

Suggested fix: make loaders.py's .csv/.tsv branches sniff too (or validate the parsed column count against a quick sniff before committing to the extension-implied delimiter), so both engines make the same choice for the same file.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions